求生成一个Int64的数的算法 ( 积分: 100 )

  • 主题发起人 主题发起人 lfpsoft
  • 开始时间 开始时间
L

lfpsoft

Unregistered / Unconfirmed
GUEST, unregistred user!
算法如下:
采用64位(8字节)的整数:
(1) 时间(格式为MMDDHHMMSS,即月日时分秒):bit64~bit39,
其中
bit64~bit61:月份的二进制表示;
bit60~bit56:日的二进制表示;
bit55~bit51:小时的二进制表示;
bit50~bit45:分的二进制表示;
bit44~bit39:秒的二进制表示;
(2) 短信网关代码:bit38~bit17,把短信网关的代码转换为整数填写到该字段中。
(3) 序列号:bit16~bit1,顺序增加,步长为1,循环使用。
各部分如不能填满,左补零,右对齐。
function GetInt64(Id:String):int64;
var
atime:int64;
asmc:int64;
aSerial:int64;
begin
aTime:=Strtoint(formatDateTime('mmddhhmmss',now));
aTime:=aTime shl 39;
asmc:=Strtoint(ID);
asmc:=asmc shl 17;
aSerial:=Message_Index;
if Message_Index>=131071 then Message_Index:=0 else Message_Index:=Message_Index+1;
Result:=aTime or asmc or aSerial;
end;

不知道是否正确?
 
这样子定义数据结构不就回到汇编时代了吗?即便是正确的,也是不可取的。

高级语言中的记录类型就是用来干这个活的,为什么舍之不用?
 
这个算法是CMPP3.0中产生Msg_Id的算法。如果是用记录类型来做,那又应该如何做呢?
 
貌似有问题
bit应该是0-63这样算的吧,所以你的位移似乎有问题,序列号最大也只是65535而已.
不太明白你的描述.高位和低位的位置,bit1是高位还是低位?
 
上面的描述是从bit1开始的.所以是bit1~bit64
我就是不懂这个位移的问题,所以请教各位了
 
按照我的理解:
1.错了,你这样得不到正确的二进制表示,位移应该是38.
2.不太清楚,位移应该是16.
3.最大值是65535.
 
以下代码请测试,我不能保证正确,请用你手上有效的数据来评估输出结果。

在常量部分,我定义了全部的掩码,部分已经用于合成 int64 数值,剩下的部分应该用于
解码这个合成的 int64 到具体的单个数据,如果需要使用,也请自己测试。

const
mo_Mask = $001C0000;
dd_Mask = $0003C000;
hh_Mask = $00003C00;
mn_Mask = $000003E0;
ss_Mask = $0000001F;
Ldate_Mask = $00000003;
Hdate_Mask = $FFFFFFFC;
code_Mask = $003FFFFF;

function GetInt64(id:string):int64;
type
PInt64Rec = ^Int64Rec;
var
date:integer;
code:integer;
serl:Word;
PRec:PInt64Rec;
begin
date:= StrToInt(formatDatetime('mmddhhmmss',now));
code:=StrToInt(id);
serl:=Message_Index;

if Message_Index >= $FFFF then
Message_Index := 0
else inc(Message_Index);

PRec := @Result;

PRec^.Cardinals[0] := ((date and Ldate_Mask) shl 30) or ((code and code_Mask) shl 16);
PRec^.Cardinals[1] := (date and Hdate_Mask) shr 2;
PRec^.Words[0] := serl;
end;
 
后退
顶部