zoukankan      html  css  js  c++  java
  • 原来 0.1*0.2!=0.02

    今天老大一本正经的跟我说要交给我一个重大任务。解决关于0.1*0.2的问题。

    0.1*0.2不就等于0.02吗??!!一个小学生都知道的答案,但是程序告诉你0.1*0.2并不是0.02。

    事实上,不仅仅是 JS,在其他采用 IEEE754 浮点数标准的语言中,0.1 * 0.2 都不会等于 0.02,0.1+0.2也不会等于0.3,就是这样。

    如果以后有人问你0.1+0.2 等于多少,0.1*0.2等于多少可别被坑了,就是这么神奇。

    更神奇的是,9007199254740992+1=9007199254740992

      

    为什么0.1*0.2 不等于0.02呢 0.1+0.2不等于0.3呢,这并不是因为程序出bug 了,因为他在做浮点数学。电脑只能本地存储整数,所以他们需要一些表示十进制数的方法。 这种表示带有一定程度的不准确性。 这就是为什么0.1 + 0.2!= 0.3。

    首先我们先来了解一下什么是IEEE标准754浮点数

    这个我就不多说了,您请自己看,我说的也没它好。

    IEEE Standard 754 Floating Point Numbers

    Floating-point arithmetic

    现在让我们来看关于 0.1,0.2,0.3,它的二进制表示

    0.1D=   2^-3 * 0.11001100110011001100110011001100110011001100110011010
    0.2D=   2^-2 * 0.11001100110011001100110011001100110011001100110011010
    0.3D=   2^-1 * 0.10011001100110011001111001100110011001100110011001100

    我是在ionic2 项目中通过npm install了double-bits 和 pad 

    然后ts 文件里这样写

    import { Component } from '@angular/core';
    import * as db from 'double-bits';
    import * as pad from 'pad';
    
    @Component({
      selector: 'page-double-bits',
      templateUrl: 'double-bits.html',
    })
    export class DoubleBits {
    
      constructor() {
        console.log("0.1D=   " + this.base2Str(0.1));
        console.log("0.2D=   " + this.base2Str(0.2));
        console.log("0.3D=   " + this.base2Str(0.3));
      }
    
      base2Str(n) {
        var f = db.fraction(n)
        return (db.sign(n) ? "-" : "") +
          "2^" + (db.exponent(n) + 1) +
          " * 0." + pad(f[1].toString(2), 20, "0") +
          pad(f[0].toString(2), 32, "0")
      }
    }

    输出:

      0.1100110011001100110011001100110011001100110011001101B
    +  1.1001100110011001100110011001100110011001100110011010B
    = 10.0110011001100110011001100110011001100110011001100111B

    将10.0110011001100110011001100110011001100110011001100111B转化成真值,结果为:0.30000000000000004

    所以 0.1+0.2=0.30000000000000004 是这样来的了 。

    那么如果我一定要 0.1+0.2=0.3呢

    然后我找到了 这个 big.js. 一个小而快速的JavaScript库,用于任意精度的十进制算术。

    安装

    npm install big

    导入项目 

    import * as Big from 'big.js';
     
    使用
    this.tt ="0.1*0.2="+ new Big(0.1).times(0.2);
    this.mm="0.1+0.2="+new Big(0.1).add(0.2);
     
    页面显示结果:

    ps:

    double-bits  pad big-js

    How numbers are encoded in JavaScript 

    揭秘 0.1 + 0.2 != 0.3

    此随笔乃本人学习工作记录,如有疑问欢迎在下面评论,转载请标明出处。

    如果对您有帮助请动动鼠标右下方给我来个赞,您的支持是我最大的动力。

  • 相关阅读:
    Java实现 LeetCode 649 Dota2 参议院(暴力大法)
    Java实现 LeetCode 648 单词替换(字典树)
    Java实现 LeetCode 648 单词替换(字典树)
    php getimagesize 函数
    PHP gd_info
    PHP 5 时区
    PHP zip_read() 函数
    PHP zip_open() 函数
    滚动界限终点 | scroll-snap-destination (Scroll Snap)
    滚动界限种类 | scroll-snap-type (Scroll Snap)
  • 原文地址:https://www.cnblogs.com/huangenai/p/6893902.html
Copyright © 2011-2022 走看看