js浮点数加减乘除

news/2024/7/19 14:57:00 标签: js, 浮点数, 加减乘除

js浮点数加减乘除">js浮点数加减乘除

js浮点数加减乘除存在着严重的bug,例如:在google浏览器下,0.1+0.2=0.30000000000000004;这完全不是我们想要的结果。

对于这一问题的解决方案就是重写浮点数加减乘除方法,其原理是现将浮点数转换为整数。进行加减乘数,再除以相应的倍数,使之成为对应的浮点数结果。

原理

浮点数的加减乘数之所以会出现bug,跟javascript的精度有关,js中所有数字都是以64位的浮点数形式存储的,包括整数也是如此。只是整数的计算时会现将浮点数形式的整数转化为32位的整数。浮点数由于位运算而导致不够精确。

js hljs ">js-number">1===js-number">1.0 js-comment">//true

js中数字的64位二进制存储形式如下:

  • 第1位:符号位,0表示正数,1表示负数
  • 第2位到第12位:指数部分
  • 第13位到第64位:小数部分(即有效数字)

所以,js数值的范围为:Math.pow(2, -1023)Math.pow(2, 1024)。(1024 = 2的11次方,11为指数位数)
数值的精度范围为:-Math.pow(2, 53)+1Math.pow(2, 53)-1。(符号位+有效位数为53)

Math.pow(2, 53)===9007199254740992

在精度范围内的整数都可以表示,超出该范围的的将无法保证精度。例如:

js hljs ">js-number">9007199254740992111
js-comment">//9007199254740992000,最后3位的精度丢失了。

js-built_in">Math.pow(js-number">2, js-number">53) + js-number">1
js-comment">// 9007199254740992

js-built_in">Math.pow(js-number">2, js-number">53) + js-number">2
js-comment">// 9007199254740994

js-built_in">Math.pow(js-number">2, js-number">53) + js-number">3
js-comment">// 9007199254740996

js-built_in">Math.pow(js-number">2, js-number">53) + js-number">4
js-comment">// 9007199254740996

对于超出精度范围数字的处理,这里暂不介绍,可以大概说一下思路:因为最大精度只能表示16位数字,所以对超出精度范围的数字可以做截取处理,以15位数字为一个单位,将一个大数据分为几个部分,这几个部分组合起来表示这个大数据。至于大数据的加减乘除,肯定也需要重写的,网上有封装好的工具。

解决方案

网上有很多关于浮点数加减乘数的方法,我大致看了一下,都存在或多或少的问题。下面贴上我的代码:

js hljs ">js-comment">//小数乘法
export js-keyword">const floatMul = (a, b) => {
    js-keyword">let m = js-number">0, n = js-number">0,              js-comment">//记录a,b的小数位数
        d = a + js-string">"",                  js-comment">//字符串化
        e = b + js-string">"";
    js-keyword">try {
        m = d.split(js-string">".")[js-number">1].length;
    } js-keyword">catch (error) {
        console.log(error)
    }
    js-keyword">try {
        n = e.split(js-string">".")[js-number">1].length;
    } js-keyword">catch (error) {
        console.log(error)
    }
    js-keyword">let maxInt = js-built_in">Math.pow(js-number">10, m + n); js-comment">//将数字转换为整数的最大倍数
    js-keyword">return js-built_in">Number(d.replace(js-string">".", js-string">"")) * js-built_in">Number(e.replace(js-string">".", js-string">"")) / maxInt;
}

js-comment">//小数加法
export js-keyword">const floatAdd = (a, b) => {
    js-keyword">let m = js-number">0, n = js-number">0,              js-comment">//记录a,b的小数位数
        d = a + js-string">"",                  js-comment">//字符串化
        e = b + js-string">"";
    js-keyword">try {
        m = d.split(js-string">".")[js-number">1].length;
    } js-keyword">catch (error) {
        console.log(error)
    }
    js-keyword">try {
        n = e.split(js-string">".")[js-number">1].length;
    } js-keyword">catch (error) {
        console.log(error)
    }
    js-keyword">let maxInt = js-built_in">Math.pow(js-number">10, js-built_in">Math.max(m, n)); js-comment">//将数字转换为整数的最大倍数
    js-keyword">return (floatMul(a, maxInt) + floatMul(b, maxInt)) / maxInt;
}

js-comment">//小数减法
export js-keyword">const floatSub = (a, b) => {
    js-keyword">let m = js-number">0, n = js-number">0,              js-comment">//记录a,b的小数位数
        d = a + js-string">"",                  js-comment">//字符串化
        e = b + js-string">"";
    js-keyword">try {
        m = d.split(js-string">".")[js-number">1].length;
    } js-keyword">catch (error) {
        console.log(error)
    }
    js-keyword">try {
        n = e.split(js-string">".")[js-number">1].length;
    } js-keyword">catch (error) {
        console.log(error)
    }
    js-keyword">let maxInt = js-built_in">Math.pow(js-number">10, js-built_in">Math.max(m, n)); js-comment">//将数字转换为整数的最大倍数
    js-keyword">return (floatMul(a, maxInt) - floatMul(b, maxInt)) / maxInt;
}

js-comment">//小数除法
export js-keyword">const floatDivision = (a, b) => {
    js-keyword">let m = js-number">0, n = js-number">0,              js-comment">//记录a,b的小数位数
        d = a + js-string">"",                  js-comment">//字符串化
        e = b + js-string">"";
    js-keyword">try {
        m = d.split(js-string">".")[js-number">1].length;
    } js-keyword">catch (error) {
        console.log(error)
    }
    js-keyword">try {
        n = e.split(js-string">".")[js-number">1].length;
    } js-keyword">catch (error) {
        console.log(error)
    }
    js-keyword">let maxInt = js-built_in">Math.pow(js-number">10, js-built_in">Math.max(n, m)); js-comment">//将数字转换为整数的最大倍数
    js-keyword">let aInt = floatMul(a, maxInt);
    js-keyword">let bInt = floatMul(b, maxInt);
    js-keyword">return aInt / bInt;
}

http://www.niftyadmin.cn/n/725324.html

相关文章

poj 1466

二分图的水题&#xff0c;第一次写&#xff1b; 基本上是参考的 &#xff01; 代码&#xff1a; 1 #include<cstdio>2 #include<vector>3 #include<cstring>4 #define maxn 20055 using namespace std;6 7 vector<int>ve[maxn];8 int match[maxn];9 …

canvas详解(1)-原理

canvas详解(1)-原理 原理 canvas本身并不具备绘画能力&#xff0c;它本身只是一个画布&#xff0c;是一个容器。绘图能力是基于html5的getContext("2d")返回的CanvasRenderingContext2D对象来完成的。 const canvas document.getElementById("payAbilityLog…

从汇编看c++中临时对象的析构时机

c中&#xff0c;临时对象一旦不需要&#xff0c;就会调用析构函数&#xff0c;释放其占有的资源&#xff1b;而具名对象则是与创建的顺序相反&#xff0c;依次调用析构函数。 c源码: class X { public:int i;int j;~X() {}X() {}};int main() {X x1;X();x1.i 1;X x2;}对应的汇…

hdu 4722 Good Numbers 数位DP

数位DP&#xff01;&#xff01;&#xff01; 代码如下&#xff1a; 1 #include<iostream>2 #include<stdio.h>3 #include<algorithm>4 #include<iomanip>5 #include<cmath>6 #include<cstring>7 #include<vector>8 #define ll __in…

canvas详解(2)-事件处理

canvas详解&#xff08;2&#xff09;-事件处理 上一章我们讲解了canvas的基本原理应用&#xff0c;这一章主要讲解一下事件如何处理。 canvas详解&#xff08;1&#xff09;-原理 canvas因为是画布的原因&#xff0c;实际上我们可以将它当做一张图片&#xff0c;所以在html中…

java常用用代码

/** *Java获取IP代码 */ import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.net.InetAddress; import java.net.UnknownHostException; import javax.swing.JButton; import javax.swing.JFrame; import jav…

论c++中对象的内存布局

对象的内存布局就是计算对象所占用的内存大小&#xff0c;对象的大小只包含数据成员&#xff0c;类成员函数是执行代码&#xff0c;不属于对象的数据成员。在不讨论类的继承&#xff0c;以及虚函数的时候。一个对象的大小的计算公式一般为: 对象的大小 sizeof(数据成员1) siz…

研发管理深度咨询服务

一、 概述 研发及管理能力是IT企业的核心竞争力&#xff0c;但我们面对前所未有的挑战&#xff1a;  研发管理混乱&#xff0c;加班成家常便饭&#xff0c;项目成功靠RP&#xff1b;  难以招聘合适的人才&#xff0c;也难以留住优秀的员工&#xff1b;  缺乏业务和技术积…