fTimeStamp
字段从 SQLite 数据库中的 Double
字段读取。下面的代码从 fTimeStamp
计算出 32 位 ID(lIntStamp),但是在某些(罕见)情况下,即使源数据库文件相同,不同的计算机上该值也会有所不同。...
fTimeStamp: TDateTime
...
var
lIntStamp: Int64;
begin
lIntStamp := Round(fTimeStamp * 864000); //86400=24*60*60*10=steps of 1/10th second
lIntStamp := lIntStamp and $FFFFFFFF;
...
end;
TDateTime
的精度(Double)为15位数字,但代码中的舍入值仅使用11位数字,因此应有足够信息进行正确的舍入。举个例子,对于某个特定的测试运行,在Windows计算机上lIntStamp
的值为$ 74AE699B,在iPad上为$ 74AE699A(=仅最后一位不同)。Round
函数在每个平台上的实现是否不同?PS.我们的目标平台目前是Windows、MacOS和iOS。编辑:根据评论,我制作了一个小的测试程序:var d: Double;
id: int64 absolute d;
lDouble: Double;
begin
id := $40E4863E234B78FC;
lDouble := d*864000;
Label1.text := inttostr(Round(d*864000))+' '+floattostr(lDouble)+' '+inttostr(Round(lDouble));
end;
在Windows上的输出结果是:
36317325723 36317325722.5 36317325722
在iPad上,输出结果如下:
36317325722 36317325722.5 36317325722
问题在于第一个数字,它显示了中间计算的四舍五入,因此问题发生在x86具有比ARM更高的内部精度(80位比64位)。
的输出结果为
36317325723 36317325723 36317325722 36317325722 `。x64编译器对于Round和Trunc都会得到相同的值(以22结尾)。 - LU RD