js浮点型数据0.14*100的结果为14.000000000002

问题描述

//此为react table-columns表格中调用getBasisMarginAlgor()方法的一列
{
    title: '资金比例',
    dataIndex: 'buyBasisMargin',
    key: 'buyBasisMargin',
    align: 'center',
    width: 150,
    render: (text, record, index) => {
        return page.getBasisMarginAlgor(text, record, index);
    }
},
//未修改之前写法
getBasisMarginAlgor = (text, record, index) => {
        if (record.basisMarginAlgor === '1') {
            return text*100 + '%';
        }else{
            return text;
        }
    };

未修改之前表格展示效果

js浮点型数据0.14*100的结果为14.000000000002_第1张图片
可以看到除了0.14外其他的数据都正确的加上了百分号

修改后效果

js浮点型数据0.14*100的结果为14.000000000002_第2张图片

原因解析-二进制数据计算误差

0.14 : 0 01111111100 0001111010111000010100011110101110000101000111101100
0.14100 : 0 10000000010 1100000000000000000000000000000000000000000000000001
14.0 : 0 10000000010 1100000000000000000000000000000000000000000000000000
我们可以看到0.14的小数部分出现循环,就像10/3 = 1.33333…一样,所以0.14是有精度丢失的,
比较0.14
100和14.0,0.14*100多了最后一位1。

Java遵循IEEE 754标准来支持浮点数的操作,结合浮点值0.14,我们来看一下,1) 0.14的二进制格式
0 01111111100 0001111010111000010100011110101110000101000111101100.
根据IEEE 754标准,
注:S:符号(0正1负),E,指数,M小数部分。
对0.14格式化后的结果是:
S(1位) E(11位) M (52位)
0 01111111100 0001111010111000010100011110101110000101000111101100
根据计算公式:
我们可以得到e = 01111111100 – 1023 = 1020 – 1023 = -3
m = 1 (隐藏位) + 0.0001111010111000010100011110101110000101000111101100 = 1 +
Long.valueOf(“0001111010111000010100011110101110000101000111101100”, 2)/ (Math.pow(2, 52) – 1)
= 1.12000000000000013
n = 1.12000000000000013 2^-3= 1.12000000000000013/8 约 0.14
接下来,第二个问题,2)为什么0.14 * 100 输出14.000000000000002?
由上可知0.14是不精确的,乘100只会扩大这个不精确度。具体的计算过程如下:
100的浮点二进制:
0 10000000101 1001000000000000000000000000000000000000000000000000
跟据浮点乘法规则指数相加,小数相乘,得到
0.14 * 100 =
2^(6-3) //100的指数是6,0.14的指数是-3
*
(1. 1001000000000000000000000000000000000000000000000000

  1. 0001111010111000010100011110101110000101000111101100) //小数部分
    = 2^(6-3) * (1 + 0.1001000000000000000000000000000000000000000000000000 +
    0.0001111010111000010100011110101110000101000111101100 +
  2. 1001000000000000000000000000000000000000000000000000 * 0. 0001111010111000010100011110101110000101000111101100
    //方便计算,分解乘数(同1.1 * 1.1 = 1 + 0.1 * 1 + 1 * 0.1 + 0.1*0.1)

解决办法-取整

getBasisMarginAlgor = (text, record, index) => {
        if (record.basisMarginAlgor === '1') {
            return Math.floor(text*100) + '%';
        }else{
            return text;
        }
    };

其他

解决办法还有很多,具体看项目要求,愿君受用!!

你可能感兴趣的:(react,前端)