注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

@fc_lamp

关注Web应用解决方案MySql/PHP/Python一盏名为"飞川"的灯~

 
 
 

日志

 
 

计算机中的 0.58 问题  

2013-11-05 14:05:19|  分类: Web技术-应用研究 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
在PHP、Python 算数运算中,你肯定遇到过这样的情况:

#PHP代码

var_dump(intval(0.58*100)); #输出: 57


#Python代码

print int(0.58*100) #输出57

为什么0.58*100 运算整型化后不是58而是57,这还得从浮点数在计算机中的存储说起:

浮点数在计算机中以二进制的除法表示. 比如, 十进制的:

0.125
其值为 1/10 + 2/100 + 5/1000, 同样, 以二进制表示则为:

0.001
其值为 0/2 + 0/4 + 1/8. 这两种表示法的值是一样的, 唯一的区别是, 前者以十进制表示, 而后者则以二进制表示.

不幸的是, 大多数的十进制小数都无法严格的以二进制来表示. 一个结果就是, 普遍来说, 你输入的十进制的小数, 通常只是以接近的二进制数表示.

在十进制中这个问题很容易理解. 考虑分数 1/3 . 你可以用一个接近的十进制数表示:

0.3
要更一些,

0.33
更好一些,

0.333
等等. 但是不管你怎么写, 都不是严格的等于 1/3, 但是可以使结果更接近于 1/3.

同样, 无论你用了多少位, 二进制的数也无法精确表示十进制的 0.1 . 在以二为底的情况下, 将是个无限循环

0.0001100110011001100110011001100110011001100110011...
在任意有限的位上停止, 可以得到一个近似值. 在今天的大多数机子上, 浮点数近似地使用二元的分数来表示, 其分子是一个 53 位的数字, 分母则是 2 的幂. 像 1/10, 其二进制表示为 3602879701896397 / 2 ** 55. 这个很接近, 但不是准确的等于.

很多用户因为这些值显示的方法而并不知道近似. Python (PHP) 仅仅打印一个合适的十进制分数, 而真正的二进制近似还是存储于机器中. 在大多数情况下, 如果让 Python 打印一个十进制小数, 那么其会以真实存储的数字显示, 例如 0.1
python高版本(2.7)中:

>>>0.1

0.1

Python低版本(2.4)中:

>>>0.1

0.10000000000000001


但是, 对于浮点数请不要过度谨慎. 在 Python (PHP) 中这些浮点数的问题来源于其硬件, 在多数的机器中, 浮点的精度没有必要达到 1/2**53 . 对于普通的任务已经足够了, 你需要记住的就是, 这不是算数的问题, 每个浮点数操作都会遇到这样的问题。


好了,有以上知识后,我们再来看0.58。
实际上当 0.58 *100 运算后以下面的结果存在计算机中(以下是一个近似值):

>>> 0.58 * 100

57.999999999999993

所以当后执行int() (PHP中为intval())后,结果就是 57了。


参:
    








  评论这张
 
阅读(225)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017