JavaScript中的每个有限数字都具有确切的实际值。例如:
const x = Number.MAX_VALUE
此处,x
的精确值为2 1024 - 2 971 =
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368
我们可以通过在算术中使用x
来证明这一点:
console.log(x % 10000) // 8368
但是如何获得那些十进制数字的全部?
我喜欢它,如果解决方案也适用于非整数,例如const y = Number.EPSILON
正好是2 -52 =
0.0000000000000002220446049250313080847263336181640625
答案 0 :(得分:2)
我发现这样做的唯一有效方法是
Float64Array
例如:
const Decimal = require('decimal.js')
Decimal.set({
precision: 10000
})
const stringify = number => {
if (Object.is(-0, number)) {
return '-0'
}
const uint8Array = new Uint8Array(new Float64Array([number]).buffer)
const sign = ((uint8Array[7] & 0b10000000) >> 7)
const exponent =
((uint8Array[7] & 0b01111111) << 4) +
((uint8Array[6] & 0b11110000) >> 4)
// Can't use bit shifts here because JS bitwise operations are 32-bit
const mantissa =
((uint8Array[6] & 0b00001111) * Math.pow(1 << 8, 6)) +
((uint8Array[5] & 0b11111111) * Math.pow(1 << 8, 5)) +
((uint8Array[4] & 0b11111111) * Math.pow(1 << 8, 4)) +
((uint8Array[3] & 0b11111111) * Math.pow(1 << 8, 3)) +
((uint8Array[2] & 0b11111111) * Math.pow(1 << 8, 2)) +
((uint8Array[1] & 0b11111111) * Math.pow(1 << 8, 1)) +
((uint8Array[0] & 0b11111111) * Math.pow(1 << 8, 0))
const one = new Decimal(-1).toPower(sign)
const power = new Decimal(2).toPower((exponent === 0 ? 1 : exponent) - 1023)
const fraction = new Decimal(mantissa).dividedBy(Math.pow(2, 52)).plus(exponent === 0 ? 0 : 1)
return one.times(power).times(fraction).toFixed()
}
console.log(stringify(Number.MAX_VALUE))
输出:
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368
类似地:
console.log(stringify(Number.EPSILON))
输出:
0.0000000000000002220446049250313080847263336181640625
请注意,new Decimal(Number.MAX_VALUE).toFixed()
不会返回所需的结果。我也遇到了BigInteger.js这个问题。信息在大量施工时丢失。这可以说是两个图书馆的缺陷。我没有找到没有这个缺陷的库。
此外,虽然decimal.js可以表示负零,但它似乎不喜欢输出前导一元否定符号,所以特别容易这样做。
答案 1 :(得分:-2)
你误解了浮点。
你得到的最大值约为14位,因为没有精确度。 2 ^ 52
最大数字是一个包含三个部分的数字。
有关详细信息,请参阅wiki Double-precision_floating-point_format。