浮点型数据间的运算结果出乎预料?

yeyuboy 2004-11-01 02:21:20
代码情形如下:
var
f1,f2:double; //类型为double时导致错误,类型为currency时就正确了。
begin
...;//代码略,f1,f2会从数据库中取值。
f1:=f1-f2; //?在未执行此语句时,从delphi调试环境下显示f1的值为6.3,f2的值为6。
//执行完此语句后,从delphi调试环境下显示f1的值为0.3,但是当将f1
//转换成字符串后(用floattostr),字符串的内容竟然是0.2999999999999997,
//这使得我生成的Sql语句内容不正确。
end;

为什么使用Currency而不使用Double,single程序就会正确运行呢?

于是我写了一些测试代码:
var
v1,v2:double;
begin
v1:=6.3;
assert(v1=6.3); //failed.
v1:=6;
assert(v1=6); //failed.
assert(v1-v2=0.3); //failed.
end;
数据类型改为Currency后:
var
v1,v2:Currency;
begin
v1:=6.3;
assert(v1=6.3); //ok.
v1:=6;
assert(v1=6); //ok.
assert(v1-v2=0.3); //ok.
end;
请帮我解释一下!
...全文
140 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
zzjzhao 2004-11-02
  • 打赏
  • 举报
回复
是计算精度问题,所有的编程语言都存在,

如果是Double类型,5-5<>0你可以看看!
jinjazz 2004-11-02
  • 打赏
  • 举报
回复
if abs(a-100)<1e-5
YFLK 2004-11-02
  • 打赏
  • 举报
回复
是计算精度问题,所有的编程语言都存在,
yeyuboy 2004-11-02
  • 打赏
  • 举报
回复
C不存在相关问题吧,我一直以为精度问题只会导致将0.00000000000000001的实际值变成0,而不会将5的实值弄成4。999999999999...的,而我的程序中浮点数间的运算结果就出现了很多小数位,而且出现得又不是很有规律,800次运算中出现了两次而已,其中一次结果还是负的,可以想象客户对这个结余为负的还带科学计数法的报表的震惊了。不过当将double改成currency后4。999999999...成了5,负数也成了0,这正是我要的结果,难不成以后总用currency型吗?
yeyuboy 2004-11-01
  • 打赏
  • 举报
回复
现在我在程序中将所有用double型的变量全部改成了Currency,感觉很怪。
longtusoft 2004-11-01
  • 打赏
  • 举报
回复
用CURRENCY型来解决上述问题吧.专为MONEY而设计的类型.
darkliu 2004-11-01
  • 打赏
  • 举报
回复
我最近也被精度问题困扰,在没有安装delphi的机子上带小数就出错,例如 99.1+0.9<>100(real类型)


后来我不用精确比较了,用 if abs(a-100)<0.0000000001 then


虽然基本解决问题了,但感觉很不爽
mikespook 2004-11-01
  • 打赏
  • 举报
回复
跟运算精度是有关系的,正因为是1位小数,那么你使用CURRENCY的话从数量级上说是相似的。自然运算的结果也基本正确。如果用DOUBLE,DOUBLE可以精确到小数点以后若干位,但是它在1位小数的时候不能保证精确度。

你可以把你的浮点数转换成二进制,手工运算一下,就知道为什么CURRENCY能得到比DEOBLE更准确的结果了。舍入的位数相差太远。

短消息里忘了说了,或者直接用DELPHI编译,然后反汇编一下,你会看出来到底计算上有什么不同。
mikespook 2004-11-01
  • 打赏
  • 举报
回复
计算精度的问题

Type Range Significant digits Size in bytes
Real48 2.9 x 10^-39 .. 1.7 x 10^38 11-12 6
Single 1.5 x 10^-45 .. 3.4 x 10^38 7-8 4
Double 5.0 x 10^-324 .. 1.7 x 10^308 15-16 8
Extended 3.6 x 10^-4951 .. 1.1 x 10^4932 19-20 10
Comp -2^63+1 .. 2^63 -1 19-20 8
Currency -922337203685477.5808.. 922337203685477.5807 19-20 8

这个表是从DELPHI的帮助里复制的,明显CURRENCY在表达4位小数的时候会更准确一些~~~

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧