[python]数值运算问题

wtzcs 2004-08-24 11:05:55
python中的浮点运算误差很大,如何解决?是否有其它的类型替换浮点类型?
...全文
561 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
xdspower 2004-08-27
  • 打赏
  • 举报
回复
oasis_me()
>而且是当前计算机技术发展情况下不能完全解决的
我天生愚笨弄不清楚这一点。比如2.3*8这个问题,计算机算出来的肯定不是18.4,而是
18.39999....;但另一方面,大家都知道2.3*8确实等于18.4,这才是一个精确的答案。
那么就应该在0.1上进位。而且这样一个功能也很好写出来啊。我确实不知道还有什么
理论背景。
-----------------------------------------------
这和计算机中浮点数表示有关,在计算机中,所有的浮点数都不是精确表示,这也是不能直接比较浮点数是否相等的原因,你前面也提到了这点。但你主观的人为可以用简单进位来处理,这是不现实的,你怎么能确定一定是精确到0.1位上?为什么不能是0.01位或者0.001位?如果你自己的应用中需要确定,一般计算机上到是有专门的处理来满足你的要求,但从你前面的问题提出中你没有提到这点。而且这样的问题不但python中有,就是其他语言也一定存在,而且在理论上这样的处理是符合精度要求的,(18.4-18.399999999999999)=0.000000000000001啊。
oasis_me 2004-08-26
  • 打赏
  • 举报
回复
yep,2.4 should be the end of this story.The decision was to leave such a conversion out of the API.



oncsdn 2004-08-26
  • 打赏
  • 举报
回复
同意 xdspower() 观点
xdspower 2004-08-26
  • 打赏
  • 举报
回复
我觉得这个没有什么问题,
首先比较浮点数不推荐用==而是比较两数差的绝对值小于某个范围。
其次你找到的是一个特例,其实在其他语言中一样的有这样的问题,而且是当前计算机技术发展情况下不能完全解决的,所以在精确计算中很多时候是用的整数计算,最后转换成浮点数表示。
shhgs 2004-08-26
  • 打赏
  • 举报
回复
真的唉,太荒唐了。

>>> 2.3 * 8
18.399999999999999
>>> 2.3 * 8 == 18.4
True
>>> 2.3 * 8 == 18.399999999999999
True
>>> 18.399999999999999 == 18.4
True
>>>
oasis_me 2004-08-26
  • 打赏
  • 举报
回复
>>> 2.3 * 8
18.399999999999999
>>> 2.3 *8 == 18.4
True
>>> 2.3 * 8 == 18.399999999999999
True
>>>
shhgs 2004-08-26
  • 打赏
  • 举报
回复
Python 2.4的decimal就是解决这个问题的。

http://www.python.org/dev/doc/devel/whatsnew/node7.html
oncsdn 2004-08-26
  • 打赏
  • 举报
回复
TO oasis_me() :

计算机中的浮点数都只是近似值
oasis_me 2004-08-26
  • 打赏
  • 举报
回复
xdspower() wrote:
>首先比较浮点数不推荐用==而是比较两数差的绝对值小于某个范围。
我觉得Python的==绝对不是单纯的==,它一定是一个重构的运算符。也就是说,
如果在C语言里,我们要比较两个浮点数,大概都要先写一个常量(tolerant)来。
但应该在Python中有一个默认的tolerant,和基于它的一个==.
>而且是当前计算机技术发展情况下不能完全解决的
我天生愚笨弄不清楚这一点。比如2.3*8这个问题,计算机算出来的肯定不是18.4,而是
18.39999....;但另一方面,大家都知道2.3*8确实等于18.4,这才是一个精确的答案。
那么就应该在0.1上进位。而且这样一个功能也很好写出来啊。我确实不知道还有什么
理论背景。
shhgs 2004-08-25
  • 打赏
  • 举报
回复
其实这只是Python在表示浮点数方面有些问题,内部它还是正确的:

>>> 2.3 * 8
18.399999999999999
>>> 2.3 *8 == 18.4
True
>>> 2.3 * 8 == 13.999999999999999999999999999999999999999999999999999999999
False
>>>
oasis_me 2004-08-25
  • 打赏
  • 举报
回复
[1]Richard L.Burden and J. Douglas Faires,Numerical Analysis(seventh edition),高教影印,2001
oasis_me 2004-08-25
  • 打赏
  • 举报
回复
to limodou:
我查了一下书[1]。IEEE的标准是:一个机器数表示的不光是一个数,而且是在这个机器数
和最近的两个机器数半个区间内的所有数。
i.g.27.56640625这个数确实可以转换成一个64位的机器数,但是离这个机器数最近的
两个机器数却并不是简单的在最小位上做加减,而是跳过了很多中间的数。因此最后
那个表示27.56640625的机器数表示了这样一个区间里的所有数:
[27.5664062499999.......,27.5664062500000....)

这是最底的实现机制,但仍然不能解决Python为什么算出18.3999999来。简单的进位工作
是容易实现的,为什么Python不进位?我想Python一定引入了什么机制。你提到的numpy
我估计也最多是做了大数计算的模块,跟这个问题应该不相关。
limodou 2004-08-25
  • 打赏
  • 举报
回复
这涉及到计算机内部浮点数表示的问题,好象是指数表示方法。具体地要查书了。
oasis_me 2004-08-25
  • 打赏
  • 举报
回复
[Q]wrzcs:为什么会出现2.3*8=18.39999999999的情况?
是不是Python表示浮点数2.3存入内存的时候就不是2.3,而是一个相对接近的数?
limodou 2004-08-24
  • 打赏
  • 举报
回复
如果输出可以使用%.nf n表示小数位数与C一样 来控制精度
wtzcs 2004-08-24
  • 打赏
  • 举报
回复
我再说详细点:2.3*8 应等于18.4 ,但经过pythong计算后等于18.399999999999999

2.3中有没有解决办法,

to limodou:谢谢,我先down个2.4的看看
limodou 2004-08-24
  • 打赏
  • 举报
回复
2.4中有decimal模块了专门进行这样的处理。
还有一个象 numpy这样的科学计算的包可以用吧。我没用过,不是很清楚。

37,719

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

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