Javascript 中大数的模运算符不准确
Modulo operator innaccuracy with large numbers in Javascript
我正在编写一些代码,将大整数从千位系统(例如 1,234,567,891)转换为日本的万位系统(例如 12亿3456万7891)。简而言之,用日语将数字写成可读格式意味着将数字分成四个一组而不是三个一组。
用户输入一个数字(var innum
),模运算符与10,000的除数一起使用以精确定位我想要用汉字(汉字)标记的数字的4位数字块).
例如:
其中 chobase
=10^12(万亿),okubase
=10^8(亿)和 manbase
=10000(万),假设用户输入是54234238524003:
var cho = Math.floor((innum/chobase)); //returns 54
var oku = Math.floor(((innum%chobase)/okubase)); //returns 2342
var man = Math.floor(((innum%okubase)/manbase)); //returns 3852
var sen = (innum%manbase); //returns 4003
把它拼成一个字符串然后... 54兆2342亿3852万4003
太棒了 - 效果很好。
但是,当整数接近十千万亿 (10^16) 时,模运算符就不再可靠了。
使用与上述相同逻辑的代码生成的示例(添加逗号以提高可读性):
input: 4,234,322,423,423,424,003
output: 423京4322兆4234億2342万4000
这是不正确的,因为根据输入,日文格式的最后四位数字应显示为 4003。
我知道 JavaScript 数字是浮点数,当整数达到一定大小时精度会下降,那么对于大小为 10-quadrillion 的数字,是否有任何关于如何解决此问题的建议? (这大致是我打算转换的最大尺寸数字)。我看到 php 有一个 fmod() 方法来处理这种情况,但我找不到 javascript 等价物..
如果可能,我会考虑将它们保留为 strings,然后仅使用子字符串操作来操作它们。这样您就不必担心它们是否适合数字数据类型。
例如,考虑以下脚本:
function makeNum(num) {
num = num.replace(/,/g,"");
var markers = "万億兆京";
var result = "";
while (num.length > 4) {
if (markers.length == 0) {
result = "(未詳)" + num.substr(num.length-4) + result;
} else {
result = markers.substr(0, 1) + num.substr(num.length-4) + result;
markers = markers.substr(1);
}
num = num.substr(0, num.length-4);
}
return num + result;
}
alert(makeNum("4,234,322,423,423,424,003"));
这首先删除所有逗号,然后使用 markers
到 select 正确的分隔符逐节构建日文数字。如果你的数字太大以至于用完了标记,我只是使用 (未詳)
代替,如果它 不 意味着 "unknown",你可以责怪我用的日英在线词典
正如预期的那样,该脚本的结果是一个包含 423京4322兆4234億2342万4003
.
的对话框
我正在编写一些代码,将大整数从千位系统(例如 1,234,567,891)转换为日本的万位系统(例如 12亿3456万7891)。简而言之,用日语将数字写成可读格式意味着将数字分成四个一组而不是三个一组。
用户输入一个数字(var innum
),模运算符与10,000的除数一起使用以精确定位我想要用汉字(汉字)标记的数字的4位数字块).
例如:
其中 chobase
=10^12(万亿),okubase
=10^8(亿)和 manbase
=10000(万),假设用户输入是54234238524003:
var cho = Math.floor((innum/chobase)); //returns 54
var oku = Math.floor(((innum%chobase)/okubase)); //returns 2342
var man = Math.floor(((innum%okubase)/manbase)); //returns 3852
var sen = (innum%manbase); //returns 4003
把它拼成一个字符串然后... 54兆2342亿3852万4003
太棒了 - 效果很好。
但是,当整数接近十千万亿 (10^16) 时,模运算符就不再可靠了。
使用与上述相同逻辑的代码生成的示例(添加逗号以提高可读性):
input: 4,234,322,423,423,424,003
output: 423京4322兆4234億2342万4000
这是不正确的,因为根据输入,日文格式的最后四位数字应显示为 4003。
我知道 JavaScript 数字是浮点数,当整数达到一定大小时精度会下降,那么对于大小为 10-quadrillion 的数字,是否有任何关于如何解决此问题的建议? (这大致是我打算转换的最大尺寸数字)。我看到 php 有一个 fmod() 方法来处理这种情况,但我找不到 javascript 等价物..
如果可能,我会考虑将它们保留为 strings,然后仅使用子字符串操作来操作它们。这样您就不必担心它们是否适合数字数据类型。
例如,考虑以下脚本:
function makeNum(num) {
num = num.replace(/,/g,"");
var markers = "万億兆京";
var result = "";
while (num.length > 4) {
if (markers.length == 0) {
result = "(未詳)" + num.substr(num.length-4) + result;
} else {
result = markers.substr(0, 1) + num.substr(num.length-4) + result;
markers = markers.substr(1);
}
num = num.substr(0, num.length-4);
}
return num + result;
}
alert(makeNum("4,234,322,423,423,424,003"));
这首先删除所有逗号,然后使用 markers
到 select 正确的分隔符逐节构建日文数字。如果你的数字太大以至于用完了标记,我只是使用 (未詳)
代替,如果它 不 意味着 "unknown",你可以责怪我用的日英在线词典
正如预期的那样,该脚本的结果是一个包含 423京4322兆4234億2342万4003
.