收录日期:2019/02/17 00:17:43 时间:2016/05/29 18:11:46 标签:脚本语言(Perl/Python)
python中的浮点运算误差很大,如何解决?是否有其它的类型替换浮点类型?
2.4中有decimal模块了专门进行这样的处理。
还有一个象 numpy这样的科学计算的包可以用吧。我没用过,不是很清楚。
我再说详细点:2.3*8 应等于18.4 ,但经过pythong计算后等于18.399999999999999

2.3中有没有解决办法,

to limodou:谢谢,我先down个2.4的看看
如果输出可以使用%.nf n表示小数位数与C一样 来控制精度
[Q]wrzcs:为什么会出现2.3*8=18.39999999999的情况?
是不是Python表示浮点数2.3存入内存的时候就不是2.3,而是一个相对接近的数?
这涉及到计算机内部浮点数表示的问题,好象是指数表示方法。具体地要查书了。
to limodou:
我查了一下书[1]。IEEE的标准是:一个机器数表示的不光是一个数,而且是在这个机器数
和最近的两个机器数半个区间内的所有数。
i.g.27.56640625这个数确实可以转换成一个64位的机器数,但是离这个机器数最近的
两个机器数却并不是简单的在最小位上做加减,而是跳过了很多中间的数。因此最后
那个表示27.56640625的机器数表示了这样一个区间里的所有数:
[27.5664062499999.......,27.5664062500000....)

这是最底的实现机制,但仍然不能解决Python为什么算出18.3999999来。简单的进位工作
是容易实现的,为什么Python不进位?我想Python一定引入了什么机制。你提到的numpy
我估计也最多是做了大数计算的模块,跟这个问题应该不相关。
[1]Richard L.Burden and J. Douglas Faires,Numerical Analysis(seventh edition),高教影印,2001
其实这只是Python在表示浮点数方面有些问题,内部它还是正确的:

>>> 2.3 * 8
18.399999999999999
>>> 2.3 *8 == 18.4
True
>>> 2.3 * 8 == 13.999999999999999999999999999999999999999999999999999999999
False
>>>
>>> 2.3 * 8
18.399999999999999
>>> 2.3 *8 == 18.4
True
>>> 2.3 * 8 == 18.399999999999999
True
>>>
真的唉,太荒唐了。

>>> 2.3 * 8
18.399999999999999
>>> 2.3 * 8 == 18.4
True
>>> 2.3 * 8 == 18.399999999999999
True
>>> 18.399999999999999 == 18.4
True
>>>
我觉得这个没有什么问题,
首先比较浮点数不推荐用==而是比较两数差的绝对值小于某个范围。
其次你找到的是一个特例,其实在其他语言中一样的有这样的问题,而且是当前计算机技术发展情况下不能完全解决的,所以在精确计算中很多时候是用的整数计算,最后转换成浮点数表示。
同意  xdspower()  观点
xdspower() wrote:
>首先比较浮点数不推荐用==而是比较两数差的绝对值小于某个范围。
我觉得Python的==绝对不是单纯的==,它一定是一个重构的运算符。也就是说,
如果在C语言里,我们要比较两个浮点数,大概都要先写一个常量(tolerant)来。
但应该在Python中有一个默认的tolerant,和基于它的一个==.
>而且是当前计算机技术发展情况下不能完全解决的
我天生愚笨弄不清楚这一点。比如2.3*8这个问题,计算机算出来的肯定不是18.4,而是
18.39999....;但另一方面,大家都知道2.3*8确实等于18.4,这才是一个精确的答案。
那么就应该在0.1上进位。而且这样一个功能也很好写出来啊。我确实不知道还有什么
理论背景。
TO oasis_me() :

计算机中的浮点数都只是近似值
Python 2.4的decimal就是解决这个问题的。

http://www.python.org/dev/doc/devel/whatsnew/node7.html
yep,2.4 should be the end of this story.The decision was to leave such a conversion out of the API.



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啊。

请高手指示!!!!!!!!!!!!!!!! bcb里能用PixelFormat得到位图每个象素所占字节数吗? 关于日志传送的问题(急) ASP不能解析﹖ 我又想找工作了,这次不想在武汉呆了,没意思,目的地是上海 TDBLookupCombox怎么设置默认值? oracle认证,以下哪个公司较好 微软最新IE累积补丁 在Javascript 中滤除空格 上海地区的高级程序员证书下来了没有? 急!有关音频创建的问题(200分)在线等待! 如何判断一个字符串中含有几个相同的字符? datagrid添加记录问题 問一個FORM 之間傳全局变量的問題 , 全局变量為什麼不可見呢?? 请教转换float小数点后精度的函数C#和sql 如何格式化输出一个整数列? 有哪位可以帮我描述一下VBA是什么东东吗? 能不能帮我找出错在那? 哪位高手有用存储过程实现Select语句的代码? w2k ad server ,系统速度很慢! 给100分!!! datagrid不能增加记录? 这行代码是什么意思啊? 请介绍一些VB的安装工具 请帮我看一下这个问题,谢谢大家了。(急的快哭了) ==按指定用户启动Ms Sql服务,该指定用户怎么建?==== CB理里如何使用M$的directX开发包中的lib文件? 通过代理上网,服务器上不去,但客户机能上去?(急!!!在线等) 控件在可视化编辑中的选中状态怎么做????????????&&讨论 调用存储过程出错的问题,请高手指教 如何调用下面的API函数???