首页 > 其他分享 >关于js toFixed 失真的问题

关于js toFixed 失真的问题

时间:2023-08-03 15:12:40浏览次数:29  
标签:0.1 0.2 js 无限 1100 toFixed RegExp 真的

不精准原因:

下面我们来说一下浮点数运算产生误差的原因:(拿0.1+0.2=0.30000000000000004进行举例)

首先,我们要站在计算机的角度思考 0.1 + 0.2 这个看似小儿科的问题。我们知道,能被计算机读懂的是二进制,而不是十进制,所以我们先把 0.1 和 0.2 转换成二进制看看:

0.1 => 0.0001 1001 1001 1001…(无限循环)

0.2 => 0.0011 0011 0011 0011…(无限循环)

上面我们发现0.1和0.2转化为二进制之后,变成了一个无限循环的数字,这在现实生活中,无限循环我们可以理解,但计算机是不允许无限循环的,对于无限循环的小数,计算机会进行舍入处理。进行双精度浮点数的小数部分最多支持 52 位,所以两者相加之后得到这么一串 0.0100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 ,因浮点数小数位的限制而截断的二进制数字,这时候,我们再把它转换为十进制,就成了 0.30000000000000004。

 例如

0.0515.toFixed(3)
'0.051'
0.0815.toFixed(3)
'0.082'

很明显 最后一位都应该是2 但是由于精度丢失的问题 导致数据最终不正确

解决方法

(function(prototype) {
    prototype.toSuperFixed = function (d) { 
        var s=this+""; 
        if(!d)d=0; 
        if(s.indexOf(".")==-1)s+="."; 
        s+=new Array(d+1).join("0"); 
        if(new RegExp("^(-|\\+)?(\\d+(\\.\\d{0,"+(d+1)+"})?)\\d*$").test(s)){
           var c="0"+RegExp.$2,pm=RegExp.$1,a=RegExp.$3.length,b=true;
           if(a==d+2){
               a=c.match(/\d/g); 
               if(parseInt(a[a.length-1])>4){
                   for(var i=a.length-2;i>=0;i--){
                       a[i]=parseInt(a[i])+1;
                       if(a[i]==10){
                           a[i]=0;
                           b=i!=1;
                       }else break;
                   }
               }
               c=a.join("").replace(new RegExp("(\\d+)(\\d{"+d+"})\\d$"),"$1.$2");

           }if(b)c=c.substr(1); 
           return (pm+c).replace(/\.$/,"");
      }return this+"";

   };
}(Number.prototype));

 

标签:0.1,0.2,js,无限,1100,toFixed,RegExp,真的
From: https://www.cnblogs.com/HePandeFeng/p/17603404.html

相关文章

  • 遇到:nodejs unhandledPromiseRejectionWarning 错误应该如何解决
    遇到"unhandledPromiseRejectionWarning"错误是因为在Node.js中,一个Promise被rejected了,但是没有被处理(handled)。这可能是因为你没有使用适当的错误处理机制,导致Promise的rejected状态没有被捕获。要解决这个问题,你可以考虑以下几个步骤:使用catch方法捕获错误:在你的......
  • Vuejs+WebApi导出Excel
    前后端分离,前端Vuejs,后端.Net6WebApi后端代码1publicclassSalesReportController:BaseController2{3privateSerilog.ILogger_log=GetLogger<SalesReportController>();4privatereadonlyISqlSugarClient_db;5privateIHostEnvironme......
  • Node.js 事件
    一、Node.js事件循环Node.js是单进程单线程应用程序,但是因为V8引擎提供的异步执行回调接口,通过这些接口可以处理大量的并发,所以性能非常高。Node.js几乎每一个API都是支持回调函数的。Node.js基本上所有的事件机制都是用设计模式中观察者模式实现。Node.js单线程类似......
  • 控制台出现lockdown-install.js文件报Removing intrinsics.问题告警
    查的原因是:警告来自MetaMaskChrome扩展。解决方法:关闭MetaMask扩展程序。参考资料:https://www.jdk5.com/ask/282/what-is-causing-the-warning-removing-intrinsics-arrayprototype-toreversed-in......
  • Nuxt.JS实战指南:从入门到精通的练习之旅
    官网:Nuxt.js-Vue.js通用应用框架|Nuxt.js中文网搭建Nuxt2-参考文献:Nuxt-超详细环境搭建及创建项目整体流程(create-nuxt-app)_王佳斌的博客-CSDN博客一、为什么用NuxtSEO:所搜引擎优化1.1如何进行搜索引擎优化?多页面Title、描述、关键字网站内容1.2-预渲染1.2.1-预渲染图解1.2......
  • 手摸手实现js拍照
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=d......
  • 老杜 JavaWeb 讲解(十八) ——项目优化(Servlet+JSP+EL+JSTL)
    (十六)项目优化(Servlet+JSP+EL+JSTL)相关视频:55-EL表达式JSTL和base标签改造OA新旧代码对比:注意点:Java代码不需要改动,只需要更改jsp代码。将需要的包导入:jakarta.servlet.jsp.jstl-2.0.0.jarjakarta.servlet.jsp.jstl-api-2.0.0.jarmysql-connector-j-8.0.31.j......
  • ThreeJs实现简单的动画
    上一节实现可用鼠标控制相机的方式实现动态效果,但很多时候是需要场景自己产恒动态效果,而不是通过鼠标拖动,此时引入一个requestAnimationFrame方法,它实际上是通过定时任务的方式,每隔一点时间改变场景中内容后重新渲染一遍,间隔时间短的话视觉上就显示出连续的动画效果,Js本身也自带定......
  • 【js学习笔记二十二】...扩展运算符
     目录前言导语 代码部分 运行结果前言我是歌谣我有个兄弟巅峰的时候排名c站总榜19叫前端小歌谣曾经我花了三年的时间创作了他现在我要用五年的时间超越他今天又是接近兄弟的一天人生难免坎坷大不了从头再来歌谣的意志是永恒的放弃很容易但是坚持一定很酷导语歌谣歌谣......
  • js 标准时间比较 false 时间戳比较才行
    newDate(),同一时间段的newDate()都是不一样的newDate("ThuAug03202309:59:16GMT+0800(中国标准时间)").getT==newDate("ThuAug03202309:59:16GMT+0800(中国标准时间)")//falsenewDate("ThuAug03202309:59:16GMT+0800(中国标准时间)").getTime()......