惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threatpost
IT之家
IT之家
Hugging Face - Blog
Hugging Face - Blog
Engineering at Meta
Engineering at Meta
爱范儿
爱范儿
博客园 - Franky
博客园 - 【当耐特】
MyScale Blog
MyScale Blog
雷峰网
雷峰网
月光博客
月光博客
云风的 BLOG
云风的 BLOG
博客园 - 司徒正美
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
P
Proofpoint News Feed
The GitHub Blog
The GitHub Blog
N
Netflix TechBlog - Medium
WordPress大学
WordPress大学
罗磊的独立博客
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Y
Y Combinator Blog
Know Your Adversary
Know Your Adversary
宝玉的分享
宝玉的分享
L
Lohrmann on Cybersecurity
S
SegmentFault 最新的问题
L
LangChain Blog
K
Kaspersky official blog
P
Palo Alto Networks Blog
P
Privacy & Cybersecurity Law Blog
美团技术团队
Scott Helme
Scott Helme
B
Blog RSS Feed
T
Threat Research - Cisco Blogs
博客园_首页
L
LINUX DO - 热门话题
腾讯CDC
C
CERT Recently Published Vulnerability Notes
A
About on SuperTechFans
博客园 - 三生石上(FineUI控件)
J
Java Code Geeks
V
V2EX
Martin Fowler
Martin Fowler
T
The Exploit Database - CXSecurity.com
人人都是产品经理
人人都是产品经理
MongoDB | Blog
MongoDB | Blog
Latest news
Latest news
S
Schneier on Security
AWS News Blog
AWS News Blog

轶哥博客

blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog
blog
2020-08-07 · via 轶哥博客

C/C++、Java、JavaScript等语言,都有计算不精准的问题。原因是这些语言在计算的时候遵循IEEE 二进制浮点数算术标准(IEEE 754),跟CPU浮点运算器有关系。

0.1+0.2!=0.3

“为什么JS中计算0.1加0.2的时候不等于0.3”,“为什么JS中计算4.44乘以100不等于444”,这类问题在诸多程序员岗位的面试中很常见。各个语言也提供了相应的数学库解决计算精度的问题。

在涉及大量计算的JavaScript项目中,强烈推荐使用Math.js这个精确计算库解决JS计算不精准的问题。

Math.js是一个用于JavaScript和Node.js的高级数学计算函数库。它内置大量的函数和常量,具有支持符号计算的表达式解析器,并提供了一个集成的解决方案用于处理不同的数据类型,例如numbers、 big numbers、 complex numbers、 fractions、 units和matrices。强大且易于使用。

特征

  • 支持数字,大数,复数,分数,单位,字符串,数组和矩阵。
  • 与JavaScript的内置Math库兼容。
  • 包含一个灵活的表达式解析器。
  • 进行符号计算。
  • 带有大量内置函数和常量。
  • 也可以用作命令行应用程序。
  • 在任何JavaScript引擎上运行。
  • 很容易扩展。
  • 开源。

安装


npm install mathjs

更多内容请直接访问Math.js的开源仓库:https://github.com/josdejong/mathjs

示例

常规计算(加减乘除)


import { create, all } from 'mathjs'



const config = {

  number: 'BigNumber',

  precision: 64

}



const math = create(all, config)



math.evaluate('4.44 * 100')

math.evaluate('0.1 + 0.2')

JS%E7%B2%BE%E5%87%86%E8%AE%A1%E7%AE%97.png

四舍五入

在JavaScript中toFixed()方法可把 Number 四舍五入为指定小数位数的数字。

NumberObject.toFixed(num)

需要注意的是,toFixed()同样存在精度问题。例如2.55取一位小数四舍五入的结果可能是2.5

toFixed.png

在JS自带的函数Math.round()中,3.5将舍入为 4,而 -3.5将舍入为-3

为了避免这类问题,可以通过mathjs提供的round()方法。

Round

将值四舍五入到最接近的整数。对于矩阵,该函数按元素进行求值。

句法

math.round(x)
math.round(x, n)

参数

参数 类型 描述
x number| BigNumber | Fraction | Complex | Array | Matrix 四舍五入
n number| BigNumber | Array 小数位数默认值:0。

返回值

类型 描述
number| BigNumber | Fraction | Complex | Array | Matrix 取整值

例子

math.round(3.2)              // returns number 3
math.round(3.8)              // returns number 4
math.round(-4.2)             // returns number -4
math.round(-4.7)             // returns number -5
math.round(math.pi, 3)       // returns number 3.142
math.round(123.45678, 2)     // returns number 123.46

const c = math.complex(3.2, -2.7)
math.round(c)                // returns Complex 3 - 3i

math.round([3.2, 3.8, -4.7]) // returns Array [3, 4, -5]

mathjs.png

math.js更多方法:https://mathjs.org/docs/reference/functions.html

取整

在JavaScript中,parseInt()方法可以实现取整。

parseInt(string, radix)

第二个参数radix可选。表示要解析的数字的基数。

同样的,通过parseInt()方法取整也存在精度问题。例如:

parseInt(0.0000001)的结果是1

parseInt.png

解决这个问题,只需要确保传入的第一个参数是字符串即可,例如:parseInt('0.0000001', 10),得到的结果就是0了(**注意:parseInt('1e-7')的结果也是1**)。

第二个参数最好明确指明数字是10进制,否则可能因浏览器遵循的ECMA标准而存在返回值差异。

当参数 radix 的值为 0,或没有设置该参数时,parseInt() 会根据 string 来判断数字的基数。

  • 如果 string 以 "0x" 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。
  • 如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。
  • 如果 string 以 1 ~ 9 的数字开头,parseInt() 将把它解析为十进制的整数。

可这带来一个新的问题,parseInt(0.0000001)产生了隐式转换,得到的结果不是我们想要的。如何将0.0000001正确的转换为'0.0000001'呢?

对于非负小数取整,我们可以采用Math.floor(0.0000001)方法实现向下取整,避免转换过程。

如果是负数,那么Math.floor(-0.0000001)将会得到-1,而parseInt('-0.0000001')得到的结果是-0

因此,对于不超过4294967295(有效整数,int,范围是0-0xffffffff)的数字来说,JavaScript向下取整,可以采用-0.0000001 | 0,或者-0.0000001 >>> 0来实现。

>>>是无符号位移。所以>>> 0 在JS里面是确保数字有意义的判断方法。

安全值与最大数

1.7976931348623157e+308,这个数字究竟意味着什么?

maxvalue.jpg

Number.MAX_SAFE_INTEGER 是js里整数的安全的最大值,由于 js 用的是 IEEE 754 双精度浮点,可以安全地表示 [ -2^53+1 , 2^53-1 ] 这个范围。

Number.MAX_VALUE 属性是 JavaScript 中可表示的最大的数。