首页 > 其他分享 >JS中数值类型的本质

JS中数值类型的本质

时间:2022-10-28 19:59:34浏览次数:68  
标签:coefficient 有效位数 number 本质 JS reduction 数值

一、JS中的数值类型

众所JS爱好友周知,JS中只有一个总的数值类型——number,它包含了整型、浮点型等数值类型。其中,浮点数的实现思想有点复杂,它把一个数拆成两部分来存储。第一部分是有效位数,也可以称作系数、分数或者尾数;第二部分被称为指数,表示小数点位应该插在系数的哪个位置。在JS中,浮点数由IEEE 754标准非完全实现。一个number包含1个符号位,11位指数为和53位有效位数。IEEE 754基于二进制运作,分为两个部分组成。第一部分包含两个子部分:符号位和有效位数。符号位在最高位中,该位为1表示该数是负数,为0则表示正数;有效位数在64位的最低几位中,通常表示一个范围内的小数。

0.5 <= 有效位数 < 1.0

按照这种表示法,有效位数的最高位理论上始终为1。因此,该位实际上并不需要被存放于number 当中,于是就多出了能用的1位,称作彩蛋位。

第二部分指数存在于符号位和有效位数之间那些位中。存放号后,可以用如下公式表示一个数值:

数值 = 符号位 * 系数 * (2 ** 指数)

下面来分析一下数值类型的本质。

二、JS中数值类型的本质

在了解JS中数值类型的本质之前,我们先来看一个问题:0.1 + 0.2 = ?

我相信很多人都见过JS中这个经典的计算。是的,0.1 + 0.2 != 0.3,而是等于0.30000000000000004。这是为什么呢,下面我们就来剖析一下这种现象出现的本质原因。看一下代码:

function deconstruct(number) {
    let sign = 1;
    let coefficient = number;
    let exponent = 0;

    //将符号位从系数中提取出来
    if (coefficient < 0) {
        coefficient = -coefficient;
        sign = -1;
    }

    if (Number.isFinite(number) && number !== 0) {
        //-1128 就是 Number.MIN_VALUE的指数减去有效位数再减去彩蛋位的结果
        exponent = -1128;
        let reduction = coefficient;
        //将系数不断除以 2,直到趋近于 0 为止
        while (reduction !== 0) {
            //将除的次数与-1128相加到exponent
            exponent += 1;
            reduction /= 2;
        }
        //当指数为 0 的时候,可以认为数值是一个整数
        //如果指数不为0,则通过校正系数来使其为 0
        reduction = exponent;
        while (reduction > 0) {
            coefficient /= 2;
            reduction -= 1;
        }

        while (reduction < 0) {
            coefficient *= 2;
            reduction += 1;
        }
    }
    return {
        sign,
        coefficient,
        exponent,
        number
    };
}

现在,我们看看传入1的结果:

image

根据数值公式计算:1 * 9007199254740992 * (2 ** -53) = 1

这显然是没有问题的。

那么我们将0.1传入函数呢,会产生怎样的结果,接着来看。

image

根据数值公式计算:

1 * 7205759403792794 * 2 ** -56 = 0.1000000000000000055511151231257827021181583404541015625

结果出人意料!JS无法精确的处理小数。这是由IEEE 754机制决定的。

因此,0.1 + 0.2 != 0.3很好解释了。

那么,我们怎么在业务中,使得0.1 + 0.2 = 0.3呢?下面给出解决办法:

image

Number.toFixed()用于保留小数点具体位数进行四舍五入,参数默认为0,则不保留小数。Number.toPrecision()用于保留并四舍五入到指定的数字位数,默认全部保留,参数为0,则保留1位有效数字。注意,以上两个函数均返回string类型的值,所以在这里需要将其显示转换为number类型。

标签:coefficient,有效位数,number,本质,JS,reduction,数值
From: https://www.cnblogs.com/mogebw/p/16837286.html

相关文章

  • PYTHON JSON EXCEL
    #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#pipinstallpandas#pipinstallopenpyxl#importjsonimporttimeimportpandasimpor......
  • JS删除两个数组对象中id相同的对象
    letarr1=[{id:'1',name:'json'},{id:'2',name:'book'}]letarr2=[{id:'1',name:'json',age:'15'},{id:'2',name:'book',age:'16'},{id:'3',name:'......
  • js一键切换dark模式 -
    js一键切换dark模式//初始化$(function(){lettheme=$.cookie('theme');if(theme=="dark"){$("body").addClass('dark');$("#theme").add......
  • 【JS】大道至简---来看看JS中你最熟悉的变量和数值的知识吧
    1变量1.1什么是变量?变量就是一个装东西的盒子。变量是用于存放数据的容器。我们通过变量名获取数据,数据可以被更改。1.2声明变量1.2.1定义单个变量js通过var来声明变量,v......
  • VSCode-Add_Configuration后launch.json为空的解决办法
    VSCode-AddConfiguration后launch.json为空的解决办法今天需要使用VSCodedebug一个程序,点击菜单栏的“Run”-"AddConfiguration"选项,准备生成一个默认的launch.json......
  • 模拟腾讯返回的json数据
     模拟腾讯返回的json数据 $(document).ready(function(){$("#SubmitButton").click(function(){alert("ajax准备......
  • 腾讯返回json数据转换
     腾讯返回json数据转换 #region----远程获取微信小程序二维码的流----///<summary>///远程获取微信小程序二维码的流///</summary>......
  • js数据处理4
    <template><ModuleBox2title="数据趋势图"bgType="2":cityShow="true"moduleType="sjqs":styleObj="styleObj"><divclass="echarts......
  • C#对象转json
     objectobj=new{Provider=appointmentErpStoreEntity.ProvinceName,City=appointmen......
  • JS数组对象排序
    原文地址:https://blog.csdn.net/qq_37899792/article/details/88655920利用数组api——>sort来进行排序varperson=[{name:"Rom",age:12},{name:"Bob",age:22},{name:......