简体   繁体   中英

Modulo operator innaccuracy with large numbers in Javascript

I am writing some code to convert large integers from a thousand-based system (eg 1,234,567,891) to the Japanese system of ten-thousand (eg 12億3456万7891). In short, writing out numbers to a readable format in Japanese means splitting numbers into sets of four instead of sets of three.

The user inputs a number (var innum ), and the modulo operator is used with divisors of 10,000's to pinpoint the 4-digit chunks where I would like the number marked with kanji (Chinese characters).

ex: where chobase =10^12 (one-trillion), okubase =10^8 (100-million) and manbase =10000 (ten-thousand), and say the user input is 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 

slap it all together as a string and... 54兆2342億3852万4003
Excellent- it works great.

However, when the integer tips into the ten-quadrillions (10^16), the modulo operator is no longer reliable.

example produced by code using the same logic as above (commas added for readability):

input: 4,234,322,423,423,424,003
output: 423京4322兆4234億2342万4000

This is incorrect, as the last four digits in the Japanese format should read 4003 given the input.

I realize that JavaScript numbers are floating point and that accuracy wanes as integers reach a certain size, so are there any suggestions on how to work around this for numbers of ten-quadrillions in size? (This is roughly the maximum size number I am aiming to convert). I saw php has an fmod() method for handling this type of situation, but I have been unable to find a javascript equivalent..

I'd consider leaving them as strings if possible, then just using substring operations to manipulate them. Then you don't have to worry about whether they'll fit into a numeric data type.

By way of example, consider the following script:

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"));

This first removes all commas then builds up the Japanese number section by section, using markers to select the correct separators. If your number is so big that it runs out of markers, I just use (未詳) instead which, if it doesn't mean "unknown", you can blame on the Japaneses-English online dictionary I used.

The result of that script is, as expected, a dialog box containing 423京4322兆4234億2342万4003 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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