简体   繁体   English

JavaScript的内置Number()方法似乎返回了一个不正确的值

[英]JavaScript's Built-in Number() method seems to return an incorrect value

I've made a program to convert bases of numbers. 我已经制作了一个转换数字基数的程序。 I thought that, in the event that there are no characters AF in the output, it would be convenient to return the number as a Number instead of a String (even though I'd be returning base 2 numbers as regular decimal numbers, whatever). 我认为,如果输出中没有字符AF ,将数字作为数字而不是字符串返回会很方便(即使我将基数为2的数字作为常规十进制数返回,无论如何) 。

For some reason, when I converted A3B2 32 to Binary (which should be 1010000110101100100 2 [ Wolfram|Alpha source]), I got 1010000110101100200 . 出于某种原因,当我将A3B2 32转换为Binary(应该是1010000110101100100 2 [ Wolfram | Alpha source])时,我得到了1010000110101100200 There's a two in there, that isn't binary! 那里有两个,那不是二元的! The final line of code which returns the value is: 返回值的最后一行代码是:

return (toBase <= 10) ? Number(result) : result;

This worked properly for basically all tests, until I decided to use that base-32 number above. 这基本上适用于所有测试,直到我决定使用上面的base-32数字。 I thought my program was doing the division/remainder step incorrect, so I had it print out the result just before it returns the value. 我认为我的程序正在执行除法/余数步骤不正确,所以我让它在返回值之前打印出结果。 It was correctly giving out 1010000110101100100 . 它正确地给出了1010000110101100100 So, I tested the Number() method directly in Chrome's console. 所以,我直接在Chrome的控制台中测试了Number()方法。 This is what happened: 这就是发生的事情:

> Number("1010000110101100100")
> 1010000110101100200

Am I misunderstanding what the Number() method does? 我误解了Number()方法的作用吗? Why is it converting a string made up of all Ones and Zeroes to a number with Ones, Zeroes, and Twos ? 为什么将由所有Ones和Zeroes组成的字符串转换为包含Ones,Zeroes和Twos的数字

What you're doing when calling Number("1010000110101100100") is passing a string, which it is trying to turn it into a number, but that number is higher than JavaScript can count, which is 9,007,199,254,740,991 (also known as Number.MAX_SAFE_INTEGER ) 你在调用Number("1010000110101100100")时正在做的是传递一个字符串,它试图把它变成一个数字,但是这个数字高于JavaScript可以计算的数字,即9,007,199,254,740,991(也称为Number.MAX_SAFE_INTEGER

Basically, any number over 9,007,199,254,740,991 can't reliably be used because JavaScript uses double-precision floating-point format numbers as specified in IEEE 754 基本上,任何超过9,007,199,254,740,991的数字都不能可靠使用,因为JavaScript使用IEEE 754中规定的双精度浮点格式数字

Here's some examples, the following input numbers "should" be the same as the output, but aren't because they've gone over the MAX_SAFE_INTEGER. 以下是一些示例,以下输入数字“应该”与输出相同,但不是因为它们已超过MAX_SAFE_INTEGER。 Some are, but it's not reliable as demonstrated in the Bonus Fun With LARGE Numbers section below. 有些是,但它不可靠,如下面的大额奖励乐趣部分所示。

Number("9007199254740992") // 9007199254740992
Number("9007199254740993") // 9007199254740992
Number("9007199254740994") // 9007199254740994
Number("9007199254740995") // 9007199254740996
Number("9007199254740996") // 9007199254740996
Number("9007199254740997") // 9007199254740996
Number("9007199254740998") // 9007199254740998
Number("9007199254740999") // 9007199254741000

If you still want to convert hex to binary, you need to use parseInt and Number.prototype.toString and keep it as a string. 如果您仍想将十六进制转换为二进制,则需要使用parseIntNumber.prototype.toString并将其保留为字符串。

 const hex = "A3B2"; const binary = parseInt(hex, 16).toString(2); console.log(binary); 

Bonus Fun With LARGE Numbers 与大数字的奖金乐趣

The following is true! 以下是真的!

 console.log(9007199254740992 === 9007199254740993); console.log(1010000110101100200 === 1010000110101100100) 

Documentation 文档

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString

@AnonymusSB said is right. @AnonymusSB说是对的。 i want add few details to it. 我想添加一些细节。

So when you Number(value) it internally calls ToNumber to calculate the value. 因此,当您使用Number(value)它会在内部调用ToNumber来计算该值。 when you supply a string. 当你提供一个字符串。 it have a two step process to change it number. 它有两个步骤来改变它的数量。

  1. First it calculate the Mathematical value (MV) of the string. 首先,它计算字符串的Mathematical value (MV)
  2. In second process it rounds up the calculated value.(when you exceed the limit of Math.MAX_SAFE_INTEGER it round of the number). 在第二个过程中,它将计算出的值向上Math.MAX_SAFE_INTEGER 。(当你超过Math.MAX_SAFE_INTEGER的限制时,它会绕过数字)。

 console.log(Number("9007199254740996")) console.log(Number("9007199254740997"), "rounded down") console.log(Number("9007199254740998")) console.log(Number("9007199254740999") ,"rounded up") 

EcmaScript 的EcmaScript

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM