js或者php浮点数运算产生多位小数的理解
<?php
$f = 0.58;
var_dump(intval($f * 100)); //为啥输出57
?>
首先我们要知道浮点数的表示(IEEE 754):
浮点数, 以64位的长度(双精度)为例, 会采用1位符号位(E), 11指数位(Q), 52位尾数(M)表示(一共64位).
符号位:最高位表示数据的正负,0表示正数,1表示负数。
指数位:表示数据以2为底的幂,指数采用偏移码表示
尾数:表示数据小数点后的有效数字.
这里的关键点就在于, 小数在二进制的表示, 关于小数如何用二进制表示, 大家可以百度一下, 我这里就不再赘述, 我们关键的要了解, 0.58 对于二进制表示来说, 是无限长的值(下面的数字省掉了隐含的1)..
0.58的二进制表示基本上(52位)是: 0010100011110101110000101000111101011100001010001111
0.57的二进制表示基本上(52位)是: 0010001111010111000010100011110101110000101000111101
而两者的二进制, 如果只是通过这52位计算的话,分别是:
0.58 -> 0.57999999999999996
0.57 -> 0.56999999999999995
至于0.58 * 100的具体浮点数乘法, 我们不考虑那么细, 有兴趣的可以看(Floating point), 我们就模糊的以心算来看… 0.58 * 100 = 57.999999999
那你intval一下, 自然就是57了….
可见, 这个问题的关键点就是: “你看似有穷的小数, 在计算机的二进制表示里却是无穷的”
另外举例辅助理解:
十进制数字 8,用二进制表示为 1000
可以理解为 1*2^3+0*2^2+0*2^1+0*2^0 = 8
那么小数部分怎么表示?
十进制数字 0.5,用二进制表示为 0.1
可以理解为 0*2^0+1*(2^-1) = 0.5
十进制数字 0.25,用二进制表示为 0.01
可以理解为 0*2^0+0*(2^-1)+1*(2^-2) = 0.25
十进制数字 0.75,用二进制表示为 0.11
可以理解为 0*2^0+1*(2^-1)+1*(2^-2) = 0.75
好了,问题来了 怎么表示一个 介于 0.25~0.5 之间的数?
除不尽吧?无理数吧?对了,这就是浮点数不是刚刚好等于一个十进制浮点数的原因
js或者php浮点数运算产生多位小数的理解的更多相关文章
- js只允许输入数字和两位小数
一.js只允许输入数字和两位小数 //只允许输入数字和两位小数 function clearNoNum(obj) { obj.value = obj.value.replace(/[^\d.]/g, ...
- sql 除法运算 保留两位小数
sql 除法运算 保留两位小数 SELECT 1530/60 select cast(1530*1./60 as decimal(18,1))
- js小数运算出现多位小数如何解决
小数相乘出现很多位小数的问题:这个问题自己以前也遇到过,现在特意来总结一下: Number类型: Number类型是ECMAScript中最常用和最令人关注的类型了:这种类型使用IEEE754格式来表 ...
- js中如何将数据获得2位小数以及对数据进行千分位划分
js中toFixed(n) 方法可把 数字四舍五入为指定小数位数n的数字,注意:这个方法只能对数据类型为Number的数据起作用,包括float,int等.例如: 123.12345.toFixe ...
- js实现文本框自动显示两位小数
转自https://blog.csdn.net/qiji2011/article/details/81270552 1.js: //保留2位小数,如:2,会在2后面补上00.即2.00 functio ...
- js对金额浮点数运算精度的处理方案
浮点数产生的原因 浮点数转二进制,会出现无限循环数,计算机又对无限循环小数进行舍入处理 js弱语言的解决方案 方法一: 指定要保留的小数位数(0.1+0.2).toFixed(1) = 0.3;这个方 ...
- js,java,浮点数运算错误及应对方法
js,java浮点数运算错误及应对方法 一,浮点数为什么会有运算错误 IEEE 754 标准规定了计算机程序设计环境中的二进制和十进制的浮点数自述的交换.算术格式以及方法. 现有存储介质都是2进制.2 ...
- js小数计算小数点后显示多位小数(转)
首先写一个demo 重现问题,我使用的是一个js在线测试环境[打开] 改写displaynum()函数 function displaynum(){var num = 22.77;alert(num ...
- JS007. 深入探讨带浮点数运算丢失精度问题(二进制的浮点数存储方式)
复现与概述 当JS在进行浮点数运算时可能产生丢失精度的情况: 从肉眼可见的程度上观察,发生精度丢失的浮点数是没有规律的,但该浮点数丢失精度的问题会100%复现.经查阅,这个问题要追溯至浮点数的二进制存 ...
随机推荐
- UVa 459 - Graph Connectivity
题目大意:给你一个无向图的顶点和边集,让你求图中连通分量的个数.使用并查集解决. #include <cstdio> #include <cstring> #define MA ...
- python模块的打包setuptools
样例代码:新建test.py文件,内容如下: print "show me" 新建一个setup.py编译文件,内容如下: from distutils.core import s ...
- mysql配置主从数据库
1.目的 1.1 实现数据备份 1.2 项目访问时可以实现读写分离,提高访问和操作数据的速度<读写分离好处> 2.背景 这次的主从配置主要实现主库数据的改变可以实现同步到从库中: 此次试验 ...
- UIViewController 之 边框类型
self.edgesForExtendedLayout = UIRectEdgeNone; 该功能会导致下面的状态栏位置被白边占据一块. 复现如下: Navgation根视图--push -- 下个视 ...
- 3.IP协议,ARP协议,RARP协议
1.IP协议 IP协议是TCP/IP协议的核心,所有的TCP,UDP,IMCP,IGCP的数据都以IP数据格式传输.要注意的是,IP不是可靠的协议,这是说,IP协议没有提供一种数据未传达以后的处理机制 ...
- php防止重复提交表单
解决方案一:引入cookie机制来解决 提交页面代码如下a.php代码如下: <form id="form1" name="form1" method=& ...
- redis3 list类型
list类型及操作list是一个链表结构,主要功能是push,pop.获取一个范围的所有值等,操作中key理解为链表的名字.redis的list类型其实就是一个每个子元素都是string类型的双向链表 ...
- origin添加error bar
增加一列,然后set as Y Error,然后全部选中显示就行了.
- swift 画图 Charts的基本使用
下面的这些代码呢是在oc工程里里使用的 其实和在swift中使用没什么大的差别 属性都一样的 //创建饼状图 self.pieChartView = [[PieChartView alloc] ...
- JDK中的插入排序
算法 有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法--插入排序法,插入排序的基本操作就是将一个数据插入到已经排好 ...