2011-11-28 29 views
2

上个月我们遇到了佣金支付方面的问题。美元金额超过了整数可以容纳的实际值。这是自应用程序写入以来第一次发生。问题四舍五入Int64和负数,我在这里失踪了什么?

clist   : tstringlist; 

clist.objects[dex]:= tobject(round((10000*DM.QryComm1.fieldbyname('COSS_NET_CHECK_AMT').asfloat)) + integer(clist.objects[dex])); 

的美元金额是$ 215,980.72我们通过10000繁殖并获得2159807200.答案最大的整数为2147483647

所以我们增加为Int64的整数。

clist.objects[dex]:= tobject(round((10000*DM.QryComm1.fieldbyname('COSS_NET_CHECK_AMT').asfloat)) + int64(clist.objects[dex])) 

,我们遇到的问题是如果一个负整数来通过时,我们使用的Int64,的4294428496缺省值被放置在tstringlsit而不是实际的数值。这只发生在负面情况下。正数很好。

我们一直在研究所有的网络,并找不到解决方案。

这里是原来的代码.....

while not DM.QryComm1.eof do 
begin 
. 
. 
{Sum net amount for each BVCICI_ID} 
dex:=clist.indexof(BVCICI_ID); 
if dex<> -1 then 
    clist.objects[dex]:= tobject(round((10000*DM.QryComm1.fieldbyname('COSS_NET_CHECK_AMT').asfloat)) + 
         integer(clist.objects[dex])) 
else 
    clist.addobject(BVCICI_ID, tobject(round(DM.QryComm1.fieldbyname('COSS_NET_CHECK_AMT').asfloat*10000))); 
+0

在货币计算中使用二进制浮点是非常糟糕的风格。 – CodesInChaos

+1

'10000 *'的存在让人怀疑你是否应该真正做'AsDecimal'。 –

回答

8

看起来像你强制转换为32位指针,这显然失去了信息的64位整数。看起来您的代码基本上是Int64(UInt32(some64BitInteger))

作为解决方法,您可以创建一个包含Int64 as字段的新对象。但是当然你需要注意摧毁它,否则你会泄漏内存。

一个干净的解决方案将是一个字符串 - > Int64字典,但只有在最近版本的delphi中才有。

+0

+1完全忘记了只有32位的对象指针。实质上,我的回答没有错,但你的指甲更好:) –