Javascript:将非常大和非常小的数字转换为固定的人类可读字符串
Javascript: converting very large and very small numbers to a fixed human readbale string
我有以下函数,我认为它可以将非常大的数字(例如 1e+24
和非常小的数字(例如 1e-18
)转换为固定字符串,例如 10000000000000000000000000:
convertExponentialToDecimal (exponentialNumber) {
// Sanity Check - i.e., is it exponential number?
const str = exponentialNumber.toString()
if (str.indexOf('e-') !== -1) {
const exponent = parseInt(str.split('-')[1], 10)
return exponentialNumber.toFixed(exponent)
}
if (str.indexOf('e+') !== -1) {
const exponent = parseInt(str.split('+')[1], 10)
return exponentialNumber.toFixed(exponent)
}
return exponentialNumber
}
但是,对于非常大的数字 - 该过程似乎不起作用...
即,1e+24 的转换产生 1e+24,但 1e-18 产生 0.000000000000000001,如预期的那样。
任何人都可以发现明显的问题,或者对这种情况有任何指示甚至他们自己的工作解决方案...
如果这是任何见解 - 它适用于任何小于 1e+21 的东西...
你的 'very large' 部分:
if (str.indexOf('e+') !== -1) {
let [a,b] = str.split('+')
a = a.slice(0,-1)
if (a.indexOf('.') !== -1) {
b = parseInt(b) - (a.length - a.indexOf('.') -1)
}
return a.replace('.','')+"".padEnd(b,0)
}
对于你的 'very small' 部分(虽然这需要测试,但它适用于我的例子,但我没有经历极端情况):
if (str.indexOf('e-') !== -1) {
const [a,b] = str.split('-')
return '0.'+a.slice(0,-1).padStart(b,0).replace('.','')
}
数字类型是 IEEE754 浮点数,幕后双精度,它没有足够的精度来表示 1e24 位数字。如果您想避免将数字视为字符串,请考虑 BigInt 数据类型。
有带 n
后缀的 BigInt 文字,它们不支持指数表示法,但幸运的是它们支持 **
。对于大数字,您可以使用
10n**24n; // 1000000000000000000000000n
BigInts,是Int,没有小数点。但它们也很大,所以你可以负担得起定点符号,比如前千位是整数部分,后千位是小数部分(最大大小取决于可用内存)。
我有以下函数,我认为它可以将非常大的数字(例如 1e+24
和非常小的数字(例如 1e-18
)转换为固定字符串,例如 10000000000000000000000000:
convertExponentialToDecimal (exponentialNumber) {
// Sanity Check - i.e., is it exponential number?
const str = exponentialNumber.toString()
if (str.indexOf('e-') !== -1) {
const exponent = parseInt(str.split('-')[1], 10)
return exponentialNumber.toFixed(exponent)
}
if (str.indexOf('e+') !== -1) {
const exponent = parseInt(str.split('+')[1], 10)
return exponentialNumber.toFixed(exponent)
}
return exponentialNumber
}
但是,对于非常大的数字 - 该过程似乎不起作用...
即,1e+24 的转换产生 1e+24,但 1e-18 产生 0.000000000000000001,如预期的那样。
任何人都可以发现明显的问题,或者对这种情况有任何指示甚至他们自己的工作解决方案...
如果这是任何见解 - 它适用于任何小于 1e+21 的东西...
你的 'very large' 部分:
if (str.indexOf('e+') !== -1) {
let [a,b] = str.split('+')
a = a.slice(0,-1)
if (a.indexOf('.') !== -1) {
b = parseInt(b) - (a.length - a.indexOf('.') -1)
}
return a.replace('.','')+"".padEnd(b,0)
}
对于你的 'very small' 部分(虽然这需要测试,但它适用于我的例子,但我没有经历极端情况):
if (str.indexOf('e-') !== -1) {
const [a,b] = str.split('-')
return '0.'+a.slice(0,-1).padStart(b,0).replace('.','')
}
数字类型是 IEEE754 浮点数,幕后双精度,它没有足够的精度来表示 1e24 位数字。如果您想避免将数字视为字符串,请考虑 BigInt 数据类型。
有带 n
后缀的 BigInt 文字,它们不支持指数表示法,但幸运的是它们支持 **
。对于大数字,您可以使用
10n**24n; // 1000000000000000000000000n
BigInts,是Int,没有小数点。但它们也很大,所以你可以负担得起定点符号,比如前千位是整数部分,后千位是小数部分(最大大小取决于可用内存)。