37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数)
我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.08499999999998
怎么会这样,两个只有一位小数的数字相乘,怎么可能多出这么小数点出来。
我Google了一下,发现原来这是JavaScript浮点运算的一个bug。
比如:7*0.8 JavaScript算出来就是:5.6000000000000005
网上找到了一些解决办法,就是重新写了一些浮点运算的函数或直接扩大倍数运算。
下面就把这些方法摘录下来,以供遇到同样问题的朋友参考:
------------------------------------------------------------------------------------------------------
程序代码
(方法一:重写浮点运算的函数)
//除法函数,用来得到精确的除法结果
//说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
//调用:accDiv(arg1,arg2)
//返回值:arg1除以arg2的精确结果
function accDiv(arg1,arg2){
var t1=0,t2=0,r1,r2;
try{t1=arg1.toString().split(".")[1].length}catch(e){}
try{t2=arg2.toString().split(".")[1].length}catch(e){}
with(Math){
r1=Number(arg1.toString().replace(".",""))
r2=Number(arg2.toString().replace(".",""))
return (r1/r2)*pow(10,t2-t1);
}
}
//给Number类型增加一个div方法,调用起来更加方便。
Number.prototype.div = function (arg){
return accDiv(this, arg);
}
//乘法函数,用来得到精确的乘法结果
//说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
//调用:accMul(arg1,arg2)
//返回值:arg1乘以arg2的精确结果
function accMul(arg1,arg2)
{
var m=0,s1=arg1.toString(),s2=arg2.toString();
try{m+=s1.split(".")[1].length}catch(e){}
try{m+=s2.split(".")[1].length}catch(e){}
return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)
}
//给Number类型增加一个mul方法,调用起来更加方便。
Number.prototype.mul = function (arg){
return accMul(arg, this);
}
//加法函数,用来得到精确的加法结果
//说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
//调用:accAdd(arg1,arg2)
//返回值:arg1加上arg2的精确结果
function accAdd(arg1,arg2){
var r1,r2,m;
try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
m=Math.pow(10,Math.max(r1,r2))
return (arg1*m+arg2*m)/m
}
//给Number类型增加一个add方法,调用起来更加方便。
Number.prototype.add = function (arg){
return accAdd(arg,this);
}
//减法函数,用来得到精确的减法结果
//说明:javascript的减法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的减法结果。
//调用:accSubtr(arg1,arg2)
//返回值:arg1减去arg2的精确结果
function accSubtr(arg1,arg2){
var r1,r2,m,n;
try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
m=Math.pow(10,Math.max(r1,r2));
//动态控制精度长度
n=(r1>=r2)?r1:r2;
return ((arg1*m-arg2*m)/m).toFixed(n);
}
//给Number类型增加一个subtr 方法,调用起来更加方便。
Number.prototype.subtr = function (arg){
return accSubtr(arg,this);
} 在你要用的地方包含这些函数,然后调用它来计算就可以了。
比如你要计算:7*0.8 ,则改成 (7).mul(8)
其它运算类似,就可以得到比较精确的结果。
------------------------------------------------------------------------------------------------------
(方法二:将浮点数放大倍数到整型)
//如果在知道小数位个数的前提下,可以考虑通过将浮点数放大倍数到整型(最后再除以相应倍数),再进行运算操作,这样就能得到正确的结果了
<script>
alert(11*(22.9*10)/10);
</script>
浮点数计算问题
js解释环境里面,0.1+0.2!=0.3 ;结果是true
为了避免产生精度差异,我们要把需要计算的数字乘以 10 的 n 次幂,换算成计算机能够精确识别的整数,然后再除以 10 的 n 次幂;
大部分编程语言都是这样处理精度差异的,借用过来处理一下 JS 中的浮点数精度误差。
针对单个脚本
针对单个函数
JavaScript中变量提升Hoisting
ECMAScript 6入门 - let和const命令
'use strict'; let
jquery setTimeout 清除
#3
const php
#3js const
js取整数四舍五入
PHP数字价格格式化,保留两位小数
我们需要将价格保留两位小数比如12元需要表示为¥12.00,这时就需要使用number_format函数,使用方法为number_format(12,2),如果需要四舍五入,可以使用round函数配合。
number_format
格式化数字字串。
语法: string number_format(float number, int [decimals], string [dec_point], string [thousands_sep]);
传回值: 字串
函式种类: 数学运算
内容说明
本函式用来将浮点参数 number 格式化。若没加参数 decimals 则传回的字串只要整数部份,加了此参数才依参数指定的小数点位数传回。参 数 dec_point 表示小数点的表示方式方法,内定值是 ”.”,若需要转换成其它的小数点就可以在这个参数改掉。参 数 thousands_sep 为整数部份每三位的分隔符号,内定值是 ”,”。本函式最特别的地方就是参数数目,最少要有一个,也就是欲格式化的字 串;也可以有二个或者四个参数,但不能用三个参数。值得注意的是指定小数点的位数之后的数字直接舍弃,没有四舍五入的情形。
描述
number
必需。要格式化的数字。
如果未设置其他参数,则数字会被格式化为不带小数点且以逗号 (,) 作为分隔符。
decimals 可选。规定多少个小数。如果设置了该参数,则使用点号 (.) 作为小数点来格式化数字。
decimalpoint 可选。规定用作小数点的字符串。
separator
可选。规定用作千位分隔符的字符串。
仅使用该参数的第一个字符。比如 "xyz" 仅输出 "x"。
注释:如果设置了该参数,那么所有其他参数都是必需的。
例子:
输出:
1,000,000
1,000,000.00
1.000.000,00
1.000.000*00
1000000.00
有意思的number_format
number_format(number,decimals,decimalpoint,separator)
有四个参数,
第一个和第二个参数是必须的,第三个和第四个是可选项。但实际测试中第三个和第四个这两个参数必须同时存在,也就是要么都设置,要么都不设置。
没有设置第三个和第四个参数:
Number_format(13526, 2); echo 13,526.00;
如果你将这处理后的数字去累加,则只会得到一个13!。
设置了第三个和第四个参数
Number_format(23125, 2, ‘.',''); echo 23125.00;
这时再对这处理后的数字进行运算的话则会正确执行!
该函数的第三个参数表示 ‘小数点'位置用什么来表示,可以默认 . ,也可以设置成‘,'等其他符号。Ps:但我相信没人会这么干。
第四个则表示每隔 千位时用什么来分割数字。如果没什么特殊要求,又要进行运算的话最好设置为空。
PHP保留两位小数的几种方法
js取float型小数点后两位数的方法
四舍五入
以下处理结果会四舍五入:
不四舍五入
以下处理结果不会四舍五入:
第一种,先把小数边整数:
第二种,当作字符串,使用正则匹配:
注意:如果是负数,请先转换为正数再计算,最后转回负数
1.丢弃小数部分,保留整数部分
2.向上取整,有小数就整数部分加1
3,四舍五入.
4,向下取整
功能:将浮点数四舍五入,取小数点后2位,如果不足2位则补0,
这个函数返回的是字符串的格式用法:changeTwoDecimal(3.1415926)返回3.14 changeTwoDecimal(3.1)返回3.10
JS处理数据四舍五入,tofixed与round的区别
1 、tofixed方法
toFixed() 方法可把 Number 四舍五入为指定小数位数的数字。例如将数据Num保留2位小数,则表示为:toFixed(Num);但是其四舍五入的规则与数学中的规则不同,使用的是银行家舍入规则,银行家舍入:所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法。具体规则如下:
简单来说就是:四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一。
显然这种规则不符合我们平常在数据中处理的方式。为了解决这样的问题,可以自定义去使用Math.round方法进行自定义式 的实现指定保留多少位数据进行处理。
2 、 round方法
round() 方法可把一个数字舍入为最接近的整数。例如:Math.round(x),则是将x取其最接近的整数。其取舍的方法使用的是四舍五入中的方法,符合数学中取舍的规则。对于小数的处理没有那么便捷,但是可以根据不同的要求,进行自定义的处理。
例如:对于X进行保留两位小数的处理,则可以使用Math.round(X * 100) / 100.进行处理。
银行家舍入
所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法。
据说,大部分的编程软件都使用的是这种方法,也算是一种国际标准。 所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法。其规则是:当舍去位的数值小于5时,直接舍去该位;当舍去位的数值大于等于6时,在舍去该位的同时向前位进一;当舍去位的数值等于5时,如果前位数值为奇,则在舍去该位的同时向前位进一,如果前位数值为偶,则直接舍去该位。
简单的说,就是:四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一
可以用隐式类型转换理解
intval 会把字符串第一个开始最长数字字符转换为数字
他的运算是这样的 "1+5=" . 5 = "1+5=5"; "1+5=5"+1 = 2;
和 c+++++c 一样无聊
.优先计算了,结果字符串
遇到+,尝试转数字类型,转的过程中遇到非数字停止,所以只剩第一个数字+最后一个数字
`echo "5+1=". 1+5;`被解析为`echo ("5+1=". 1)+5;`
前面是个字符串拼接,也就是 `"5+1=1" + 5`,最终`5+1=1`这个字符串,转换成数字,第一个是数字 5,然后+号不是数字,于是被认为是数字 5,加上最后的一个 5,结果是 10。
只能说这代码从语法上就不对。
主要是字符串拼接后的整形转换