JavaScript 数字到单词

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5529934/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:40:49  来源:igfitidea点击:

JavaScript numbers to Words

javascriptnumbers

提问by Arnon

I'm trying to convert numbers into english words, for example 1234would become: "one thousand two hundred thirty four".

我正在尝试将数字转换为英文单词,例如1234将变为:“一千二三十四”。

My Tactic goes like this:

我的战术是这样的:

  • Separate the digits to three and put them on Array (finlOutPut), from right to left.

  • Convert each group (each cell in the finlOutPutarray) of three digits to a word (this what the triConvertfunction does). If all the three digits are zero convert them to "dontAddBigSuffix"

  • From Right to left, add thousand, million, billion, etc. If the finlOutPutcell equals "dontAddBigSufix"(because it was only zeroes), don't add the word and set the cell to " "(nothing).

  • 将数字分成三个,然后将它们finlOutPut从右到左放在数组 ( ) 上。

  • finlOutPut三位数的每组(数组中的每个单元格)转换为一个单词(这就是triConvert函数所做的)。如果所有三个数字都为零,则将它们转换为"dontAddBigSuffix"

  • 从右到左,加上千、百万、十亿等。如果finlOutPut单元格等于"dontAddBigSufix"(因为它只是零),则不要添加单词并将单元格设置为" "(无)。

It seems to work pretty well, but I've got some problems with numbers like 190000009, converted to: "one hundred ninety million". Somehow it "forgets" the last numbers when there are a few zeros.

它似乎工作得很好,但是我遇到了一些问题,例如 19000000 9转换为:“一亿九千万”。当有几个零时,它会以某种方式“忘记”最后一个数字。

What did I do wrong? Where is the bug? Why does it not work perfectly?

我做错了什么?错误在哪里?为什么它不能完美地工作?

<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>

<script type="text/javascript">
function update(){
    var bigNumArry = new Array('', ' thousand', ' million', ' billion', ' trillion', ' quadrillion', ' quintillion');

    var output = '';
    var numString =   document.getElementById('number').value;
    var finlOutPut = new Array();

    if (numString == '0') {
        document.getElementById('container').innerHTML = 'Zero';
        return;
    }

    if (numString == 0) {
        document.getElementById('container').innerHTML = 'messeg tell to enter numbers';
        return;
    }

    var i = numString.length;
    i = i - 1;

    //cut the number to grups of three digits and add them to the Arry
    while (numString.length > 3) {
        var triDig = new Array(3);
        triDig[2] = numString.charAt(numString.length - 1);
        triDig[1] = numString.charAt(numString.length - 2);
        triDig[0] = numString.charAt(numString.length - 3);

        var varToAdd = triDig[0] + triDig[1] + triDig[2];
        finlOutPut.push(varToAdd);
        i--;
        numString = numString.substring(0, numString.length - 3);
    }
    finlOutPut.push(numString);
    finlOutPut.reverse();

    //conver each grup of three digits to english word
    //if all digits are zero the triConvert
    //function return the string "dontAddBigSufix"
    for (j = 0; j < finlOutPut.length; j++) {
        finlOutPut[j] = triConvert(parseInt(finlOutPut[j]));
    }

    var bigScalCntr = 0; //this int mark the million billion trillion... Arry

    for (b = finlOutPut.length - 1; b >= 0; b--) {
        if (finlOutPut[b] != "dontAddBigSufix") {
            finlOutPut[b] = finlOutPut[b] + bigNumArry[bigScalCntr] + ' , ';
            bigScalCntr++;
        }
        else {
            //replace the string at finlOP[b] from "dontAddBigSufix" to empty String.
            finlOutPut[b] = ' ';
            bigScalCntr++; //advance the counter  
        }
    }

        //convert The output Arry to , more printable string 
        for(n = 0; n<finlOutPut.length; n++){
            output +=finlOutPut[n];
        }

    document.getElementById('container').innerHTML = output;//print the output
}

//simple function to convert from numbers to words from 1 to 999
function triConvert(num){
    var ones = new Array('', ' one', ' two', ' three', ' four', ' five', ' six', ' seven', ' eight', ' nine', ' ten', ' eleven', ' twelve', ' thirteen', ' fourteen', ' fifteen', ' sixteen', ' seventeen', ' eighteen', ' nineteen');
    var tens = new Array('', '', ' twenty', ' thirty', ' forty', ' fifty', ' sixty', ' seventy', ' eighty', ' ninety');
    var hundred = ' hundred';
    var output = '';
    var numString = num.toString();

    if (num == 0) {
        return 'dontAddBigSufix';
    }
    //the case of 10, 11, 12 ,13, .... 19 
    if (num < 20) {
        output = ones[num];
        return output;
    }

    //100 and more
    if (numString.length == 3) {
        output = ones[parseInt(numString.charAt(0))] + hundred;
        output += tens[parseInt(numString.charAt(1))];
        output += ones[parseInt(numString.charAt(2))];
        return output;
    }

    output += tens[parseInt(numString.charAt(0))];
    output += ones[parseInt(numString.charAt(1))];

    return output;
}   
</script>

</head>
<body>

<input type="text"
    id="number"
    size="70"
    onkeyup="update();"
    /*this code prevent non numeric letters*/ 
    onkeydown="return (event.ctrlKey || event.altKey 
                    || (47<event.keyCode && event.keyCode<58 && event.shiftKey==false) 
                    || (95<event.keyCode && event.keyCode<106)
                    || (event.keyCode==8) || (event.keyCode==9) 
                    || (event.keyCode>34 && event.keyCode<40) 
                    || (event.keyCode==46) )"/>
                    <br/>
<div id="container">Here The Numbers Printed</div>
</body>
</html>

采纳答案by typo.pl

JavaScript is parsing the group of 3 numbers as an octal number when there's a leading zero digit. When the group of three digits is all zeros, the result is the same whether the base is octal or decimal.

当有前导零位时,JavaScript 会将 3 个数字的组解析为八进制数。当三位数字组全为零时,无论基数是八进制还是十进制,结果都相同。

But when you give JavaScript '009' (or '008'), that's an invalid octal number, so you get zero back.

但是当你给 JavaScript '009'(或 '008')时,这是一个无效的八进制数,所以你得到零。

If you had gone through the whole set of numbers from 190,000,001 to 190,000,010 you'd hav seen JavaScript skip '...,008' and '...,009' but emit 'eight' for '...,010'. That's the 'Eureka!' moment.

如果您已经浏览了从 190,000,001 到 190,000,010 的整个数字集合,您就会看到 JavaScript 跳过 '...,008' 和 '...,009',但为 '...,010' 发出 '8'。那就是“尤里卡!” 片刻。

Change:

改变:

for (j = 0; j < finlOutPut.length; j++) {
    finlOutPut[j] = triConvert(parseInt(finlOutPut[j]));
}

to

for (j = 0; j < finlOutPut.length; j++) {
    finlOutPut[j] = triConvert(parseInt(finlOutPut[j],10));
}

Code also kept on adding commas after every non-zero group, so I played with it and found the right spot to add the comma.

代码还不断在每个非零组后添加逗号,所以我使用它并找到了添加逗号的正确位置。

Old:

老的:

for (b = finlOutPut.length - 1; b >= 0; b--) {
    if (finlOutPut[b] != "dontAddBigSufix") {
        finlOutPut[b] = finlOutPut[b] + bigNumArry[bigScalCntr] + ' , ';
        bigScalCntr++;
    }
    else {
        //replace the string at finlOP[b] from "dontAddBigSufix" to empty String.
        finlOutPut[b] = ' ';
        bigScalCntr++; //advance the counter  
    }
}

    //convert The output Arry to , more printable string 
    for(n = 0; n<finlOutPut.length; n++){
        output +=finlOutPut[n];
    }

New:

新的:

for (b = finlOutPut.length - 1; b >= 0; b--) {
    if (finlOutPut[b] != "dontAddBigSufix") {
        finlOutPut[b] = finlOutPut[b] + bigNumArry[bigScalCntr]; // <<<
        bigScalCntr++;
    }
    else {
        //replace the string at finlOP[b] from "dontAddBigSufix" to empty String.
        finlOutPut[b] = ' ';
        bigScalCntr++; //advance the counter  
    }
}

    //convert The output Arry to , more printable string 
    var nonzero = false; // <<<
    for(n = 0; n<finlOutPut.length; n++){
        if (finlOutPut[n] != ' ') { // <<<
            if (nonzero) output += ' , '; // <<<
            nonzero = true; // <<<
        } // <<<
        output +=finlOutPut[n];
    }

回答by MAK

Your problem is already solved but I am posting another way of doing it just for reference.

您的问题已经解决,但我发布了另一种方法仅供参考。

The code was written to be tested on node.js, but the functions should work fine when called within the browser. Also, this only handles the range [0,1000000], but can be easily adapted for bigger ranges.

代码是为了在 node.js 上测试而编写的,但在浏览器中调用时,这些函数应该可以正常工作。此外,这仅处理范围 [0,1000000],但可以轻松适应更大的范围。

// actual  conversion code starts here

var ones = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
var tens = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'];
var teens = ['ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'];

function convert_millions(num) {
  if (num >= 1000000) {
    return convert_millions(Math.floor(num / 1000000)) + " million " + convert_thousands(num % 1000000);
  } else {
    return convert_thousands(num);
  }
}

function convert_thousands(num) {
  if (num >= 1000) {
    return convert_hundreds(Math.floor(num / 1000)) + " thousand " + convert_hundreds(num % 1000);
  } else {
    return convert_hundreds(num);
  }
}

function convert_hundreds(num) {
  if (num > 99) {
    return ones[Math.floor(num / 100)] + " hundred " + convert_tens(num % 100);
  } else {
    return convert_tens(num);
  }
}

function convert_tens(num) {
  if (num < 10) return ones[num];
  else if (num >= 10 && num < 20) return teens[num - 10];
  else {
    return tens[Math.floor(num / 10)] + " " + ones[num % 10];
  }
}

function convert(num) {
  if (num == 0) return "zero";
  else return convert_millions(num);
}

//end of conversion code

//testing code begins here

function main() {
  var cases = [0, 1, 2, 7, 10, 11, 12, 13, 15, 19, 20, 21, 25, 29, 30, 35, 50, 55, 69, 70, 99, 100, 101, 119, 510, 900, 1000, 5001, 5019, 5555, 10000, 11000, 100000, 199001, 1000000, 1111111, 190000009];
  for (var i = 0; i < cases.length; i++) {
    console.log(cases[i] + ": " + convert(cases[i]));
  }
}

main();

回答by Hardik Thaker

I know this problem had solved 3 years ago. I am posting this SPECIALLY FOR INDIAN DEVELOPERS

我知道这个问题已经在 3 年前解决了。我特地为印度开发者发布此信息

After spending some time in googling and playing with others code i made a quick fix and reusable function works well for numbers upto 99,99,99,999. use : number2text(1234.56);will return ONE THOUSAND TWO HUNDRED AND THIRTY-FOUR RUPEE AND FIFTY-SIX PAISE ONLY. enjoy !

在花了一些时间在谷歌搜索和玩其他代码之后,我做了一个快速修复和可重用的功能,适用于高达 99,99,99,999 的数字。使用:number2text(1234.56);将返回ONE THOUSAND TWO HUNDRED AND THIRTY-FOUR RUPEE AND FIFTY-SIX PAISE ONLY。请享用 !

function number2text(value) {
    var fraction = Math.round(frac(value)*100);
    var f_text  = "";

    if(fraction > 0) {
        f_text = "AND "+convert_number(fraction)+" PAISE";
    }

    return convert_number(value)+" RUPEE "+f_text+" ONLY";
}

function frac(f) {
    return f % 1;
}

function convert_number(number)
{
    if ((number < 0) || (number > 999999999)) 
    { 
        return "NUMBER OUT OF RANGE!";
    }
    var Gn = Math.floor(number / 10000000);  /* Crore */ 
    number -= Gn * 10000000; 
    var kn = Math.floor(number / 100000);     /* lakhs */ 
    number -= kn * 100000; 
    var Hn = Math.floor(number / 1000);      /* thousand */ 
    number -= Hn * 1000; 
    var Dn = Math.floor(number / 100);       /* Tens (deca) */ 
    number = number % 100;               /* Ones */ 
    var tn= Math.floor(number / 10); 
    var one=Math.floor(number % 10); 
    var res = ""; 

    if (Gn>0) 
    { 
        res += (convert_number(Gn) + " CRORE"); 
    } 
    if (kn>0) 
    { 
            res += (((res=="") ? "" : " ") + 
            convert_number(kn) + " LAKH"); 
    } 
    if (Hn>0) 
    { 
        res += (((res=="") ? "" : " ") +
            convert_number(Hn) + " THOUSAND"); 
    } 

    if (Dn) 
    { 
        res += (((res=="") ? "" : " ") + 
            convert_number(Dn) + " HUNDRED"); 
    } 


    var ones = Array("", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX","SEVEN", "EIGHT", "NINE", "TEN", "ELEVEN", "TWELVE", "THIRTEEN","FOURTEEN", "FIFTEEN", "SIXTEEN", "SEVENTEEN", "EIGHTEEN","NINETEEN"); 
var tens = Array("", "", "TWENTY", "THIRTY", "FOURTY", "FIFTY", "SIXTY","SEVENTY", "EIGHTY", "NINETY"); 

    if (tn>0 || one>0) 
    { 
        if (!(res=="")) 
        { 
            res += " AND "; 
        } 
        if (tn < 2) 
        { 
            res += ones[tn * 10 + one]; 
        } 
        else 
        { 

            res += tens[tn];
            if (one>0) 
            { 
                res += ("-" + ones[one]); 
            } 
        } 
    }

    if (res=="")
    { 
        res = "zero"; 
    } 
    return res;
}

回答by Tomá?

There are JS library for en_USand cs_CZ.
You can use it standalone or as Node module.

en_UScs_CZ有 JS 库。
您可以单独使用它或作为 Node 模块使用它。

回答by ?ime Vidas

Here, I wrote an alternative solution:

在这里,我写了一个替代解决方案:

1) The object containing the string constants:

1) 包含字符串常量的对象:

var NUMBER2TEXT = {
    ones: ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'],
    tens: ['', '', 'twenty', 'thirty', 'fourty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'],
    sep: ['', ' thousand ', ' million ', ' billion ', ' trillion ', ' quadrillion ', ' quintillion ', ' sextillion ']
};

2) The actual code:

2)实际代码:

(function( ones, tens, sep ) {

    var input = document.getElementById( 'input' ),
        output = document.getElementById( 'output' );

    input.onkeyup = function() {
        var val = this.value,
            arr = [],
            str = '',
            i = 0;

        if ( val.length === 0 ) {
            output.textContent = 'Please type a number into the text-box.';
            return;  
        }

        val = parseInt( val, 10 );
        if ( isNaN( val ) ) {
            output.textContent = 'Invalid input.';
            return;   
        }

        while ( val ) {
            arr.push( val % 1000 );
            val = parseInt( val / 1000, 10 );   
        }

        while ( arr.length ) {
            str = (function( a ) {
                var x = Math.floor( a / 100 ),
                    y = Math.floor( a / 10 ) % 10,
                    z = a % 10;

                return ( x > 0 ? ones[x] + ' hundred ' : '' ) +
                       ( y >= 2 ? tens[y] + ' ' + ones[z] : ones[10*y + z] );
            })( arr.shift() ) + sep[i++] + str;
        }

        output.textContent = str;
    };

})( NUMBER2TEXT.ones, NUMBER2TEXT.tens, NUMBER2TEXT.sep );

Live demo:http://jsfiddle.net/j5kdG/

现场演示:http : //jsfiddle.net/j5kdG/

回答by gandil

<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<script type="text/javascript">
var th = ['', ' thousand', ' million', ' billion', ' trillion', ' quadrillion', ' quintillion'];
var dg = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
var tn = ['ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'];
var tw = ['twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'];

function update(){
    var numString =   document.getElementById('number').value;
    if (numString == '0') {
        document.getElementById('container').innerHTML = 'Zero';
        return;
    }
    if (numString == 0) {
        document.getElementById('container').innerHTML = 'messeg tell to enter numbers';
        return;
    }

    var output = toWords(numString);
    //print the output
    document.getElementById('container').innerHTML = output;
}

function toWords(s) {
    s = s.toString();
    s = s.replace(/[\, ]/g, '');
    if (s != parseFloat(s)) return 'not a number';
    var x = s.indexOf('.');
    if (x == -1) x = s.length;
    if (x > 15) return 'too big';
    var n = s.split('');
    var str = '';
    var sk = 0;
    for (var i = 0; i < x; i++) {
        if ((x - i) % 3 == 2) {
            if (n[i] == '1') {
                str += tn[Number(n[i + 1])] + ' ';
                i++;
                sk = 1;
            } else if (n[i] != 0) {
                str += tw[n[i] - 2] + ' ';
                sk = 1;
            }
        } else if (n[i] != 0) {
            str += dg[n[i]] + ' ';
            if ((x - i) % 3 == 0) str += 'hundred ';
            sk = 1;
        }
        if ((x - i) % 3 == 1) {
            if (sk) str += th[(x - i - 1) / 3] + ' ';
            sk = 0;
        }
    }
    if (x != s.length) {
        var y = s.length;
        str += 'point ';
        for (var i = x + 1; i < y; i++) str += dg[n[i]] + ' ';
    }
    return str.replace(/\s+/g, ' ');
}
</script>

</head>
<body>

<input type="text"
    id="number"
    size="70"
    onkeyup="update();"
    /*this code prevent non numeric letters*/ 
    onkeydown="return (event.ctrlKey || event.altKey 
                    || (47<event.keyCode && event.keyCode<58 && event.shiftKey==false) 
                    || (95<event.keyCode && event.keyCode<106)
                    || (event.keyCode==8) || (event.keyCode==9) 
                    || (event.keyCode>34 && event.keyCode<40) 
                    || (event.keyCode==46) )"/>
                    <br/>
<div id="container">Here The Numbers Printed</div>
</body>
</html>

回答by Muhammad Rashid

Try this,convert number to words

试试这个,将数字转换为单词

function convert(number) {

    if (number < 0) {

        console.log("Number Must be greater than zero = " + number);
        return "";
    }
    if (number > 100000000000000000000) {
        console.log("Number is out of range = " + number);
        return "";
    }
    if (!is_numeric(number)) {
        console.log("Not a number = " + number);
        return "";
    }

    var quintillion = Math.floor(number / 1000000000000000000); /* quintillion */
    number -= quintillion * 1000000000000000000;
    var quar = Math.floor(number / 1000000000000000); /* quadrillion */
    number -= quar * 1000000000000000;
    var trin = Math.floor(number / 1000000000000); /* trillion */
    number -= trin * 1000000000000;
    var Gn = Math.floor(number / 1000000000); /* billion */
    number -= Gn * 1000000000;
    var million = Math.floor(number / 1000000); /* million */
    number -= million * 1000000;
    var Hn = Math.floor(number / 1000); /* thousand */
    number -= Hn * 1000;
    var Dn = Math.floor(number / 100); /* Tens (deca) */
    number = number % 100; /* Ones */
    var tn = Math.floor(number / 10);
    var one = Math.floor(number % 10);
    var res = "";

    if (quintillion > 0) {
        res += (convert_number(quintillion) + " quintillion");
    }
    if (quar > 0) {
        res += (convert_number(quar) + " quadrillion");
    }
    if (trin > 0) {
        res += (convert_number(trin) + " trillion");
    }
    if (Gn > 0) {
        res += (convert_number(Gn) + " billion");
    }
    if (million > 0) {
        res += (((res == "") ? "" : " ") + convert_number(million) + " million");
    }
    if (Hn > 0) {
        res += (((res == "") ? "" : " ") + convert_number(Hn) + " Thousand");
    }

    if (Dn) {
        res += (((res == "") ? "" : " ") + convert_number(Dn) + " hundred");
    }


    var ones = Array("", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eightteen", "Nineteen");
    var tens = Array("", "", "Twenty", "Thirty", "Fourty", "Fifty", "Sixty", "Seventy", "Eigthy", "Ninety");

    if (tn > 0 || one > 0) {
        if (!(res == "")) {
            res += " and ";
        }
        if (tn < 2) {
            res += ones[tn * 10 + one];
        } else {

            res += tens[tn];
            if (one > 0) {
                res += ("-" + ones[one]);
            }
        }
    }

    if (res == "") {
        console.log("Empty = " + number);
        res = "";
    }
    return res;
}
function is_numeric(mixed_var) {
    return (typeof mixed_var === 'number' || typeof mixed_var === 'string') && mixed_var !== '' && !isNaN(mixed_var);
}

回答by jasonhao

function intToEnglish(number){

var NS = [
    {value: 1000000000000000000000, str: "sextillion"},
    {value: 1000000000000000000, str: "quintillion"},
    {value: 1000000000000000, str: "quadrillion"},
    {value: 1000000000000, str: "trillion"},
    {value: 1000000000, str: "billion"},
    {value: 1000000, str: "million"},
    {value: 1000, str: "thousand"},
    {value: 100, str: "hundred"},
    {value: 90, str: "ninety"},
    {value: 80, str: "eighty"},
    {value: 70, str: "seventy"},
    {value: 60, str: "sixty"},
    {value: 50, str: "fifty"},
    {value: 40, str: "forty"},
    {value: 30, str: "thirty"},
    {value: 20, str: "twenty"},
    {value: 19, str: "nineteen"},
    {value: 18, str: "eighteen"},
    {value: 17, str: "seventeen"},
    {value: 16, str: "sixteen"},
    {value: 15, str: "fifteen"},
    {value: 14, str: "fourteen"},
    {value: 13, str: "thirteen"},
    {value: 12, str: "twelve"},
    {value: 11, str: "eleven"},
    {value: 10, str: "ten"},
    {value: 9, str: "nine"},
    {value: 8, str: "eight"},
    {value: 7, str: "seven"},
    {value: 6, str: "six"},
    {value: 5, str: "five"},
    {value: 4, str: "four"},
    {value: 3, str: "three"},
    {value: 2, str: "two"},
    {value: 1, str: "one"}
  ];

  var result = '';
  for (var n of NS) {
    if(number>=n.value){
      if(number<=20){
        result += n.str;
        number -= n.value;
        if(number>0) result += ' ';
      }else{
        var t =  Math.floor(number / n.value);
        var d = number % n.value;
        if(d>0){
          return intToEnglish(t) + ' ' + n.str +' ' + intToEnglish(d);
        }else{
          return intToEnglish(t) + ' ' + n.str;
        }

      }
    }
  }
  return result;
}

回答by neatonk

Here's a solution that will handle any integer value that fit's in a string. I've defined number scales up to "decillion", so this solution should be accurate up to 999 decillion. After which you get things like "one thousand decillion" and so on.

这是一个解决方案,它将处理适合字符串的任何整数值。我已将数字比例定义为“十亿”,因此该解决方案应准确到 999 十亿。之后,您会得到“一千分之一”之类的东西。

JavaScript numbers start to fail around "999999999999999" so the convert function works with strings of numbers only.

JavaScript 数字在“999999999999999”附近开始失败,因此转换函数仅适用于数字字符串。

Examples:

例子:

convert("365");
//=> "three hundred sixty-five"

convert("10000000000000000000000000000230001010109");
//=> "ten thousand decillion two hundred thirty billion one million ten thousand one hundred nine"

Code:

代码:

var lt20 = ["", "one", "two", "three", "four", "five", "six", "seven","eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" ],
    tens = ["", "ten", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eightty", "ninety" ],
    scales = ["", "thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion", "septillion", "octillion", "nonillion", "decillion" ],
    max = scales.length * 3;

function convert(val) {
    var len;

    // special cases
    if (val[0] === "-") { return "negative " + convert(val.slice(1)); }
    if (val === "0") { return "zero"; }

    val = trim_zeros(val);
    len = val.length;

    // general cases
    if (len < max) { return convert_lt_max(val); }
    if (len >= max) { return convert_max(val); }
}

function convert_max(val) {
    return split_rl(val, max)
        .map(function (val, i, arr) {
            if (i < arr.length - 1) {
                return convert_lt_max(val) + " " + scales.slice(-1);
            }
            return convert_lt_max(val);
        })
        .join(" ");
}       

function convert_lt_max(val) {
    var l = val.length;
    if (l < 4) {
        return convert_lt1000(val).trim();
    } else {
        return split_rl(val, 3)
            .map(convert_lt1000)
            .reverse()
            .map(with_scale)
            .reverse()
            .join(" ")
            .trim();
    }
}

function convert_lt1000(val) {
    var rem, l;

    val = trim_zeros(val);
    l = val.length;

    if (l === 0) { return ""; }
    if (l < 3) { return convert_lt100(val); }
    if (l === 3) { //less than 1000
        rem = val.slice(1);
        if (rem) {
            return lt20[val[0]] + " hundred " + convert_lt1000(rem);
        } else {
            return lt20[val[0]] + " hundred";
        }
    }
}

function convert_lt100(val) {
    if (is_lt20(val)) { // less than 20
        return lt20[val];
    } else if (val[1] === "0") {
        return tens[val[0]];
    } else {
        return tens[val[0]] + "-" +  lt20[val[1]];
    }
}


function split_rl(str, n) {
    // takes a string 'str' and an integer 'n'. Splits 'str' into
    // groups of 'n' chars and returns the result as an array. Works
    // from right to left.
    if (str) {
        return Array.prototype.concat
            .apply(split_rl(str.slice(0, (-n)), n), [str.slice(-n)]);
    } else {
        return [];
    }
}

function with_scale(str, i) {
    var scale;
    if (str && i > (-1)) {
        scale = scales[i];
        if (scale !== undefined) {
            return str.trim() + " " + scale;
        } else {
            return convert(str.trim());
        }
    } else {
        return "";
    }
}

function trim_zeros(val) {
    return val.replace(/^0*/, "");
}

function is_lt20(val) {
    return parseInt(val, 10) < 20;
}

回答by Steve Black

I've modified the posting from ?ime Vidas - http://jsfiddle.net/j5kdG/To include dollars, cents, commas and "and" in the appropriate places. There's an optional ending if it requires "zero cents" or no mention of cents if 0.

我已经修改了 ?ime Vidas - http://jsfiddle.net/j5kdG/的帖子 ,在适当的地方包含美元、美分、逗号和“和”。如果需要“零美分”或如果为 0 则不提及美分,则有一个可选的结尾。

This function structure did my head in a bit but I learned heaps. Thanks Sime.

这个函数结构有点让我头疼,但我学到了堆。谢谢西梅。

Someone might find a better way of processing this.

有人可能会找到更好的处理方法。

Code:

代码:

var str='';
var str2='';
var str3 =[];

function convertNum(inp,end){
    str2='';
    str3 = [];
    var NUMBER2TEXT = {
    ones: ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'],
    tens: ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'],
    sep: ['', ' thousand', ' million', ' billion', ' trillion', ' quadrillion', ' quintillion', ' sextillion']
};
(function( ones, tens, sep ) {
   var vals = inp.split("."),val,pos,postsep=' ';
   for (p in vals){
      val = vals[p], arr = [], str = '', i = 0;
      if ( val.length === 0 ) {return 'No value';}
      val = parseInt( (p==1 && val.length===1 )?val*10:val, 10 );
      if ( isNaN( val ) || p>=2) {return 'Invalid value'; }
      while ( val ) {
        arr.push( val % 1000 );
        val = parseInt( val / 1000, 10 );   
      }
      pos = arr.length;
      function trimx (strx) {
                return strx.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
            }
        function seps(sepi,i){
                var s = str3.length
                if (str3[s-1][0]){
                    if (str3[s-2][1] === str3[s-1][0]){
                        str = str.replace(str3[s-2][1],'')
                    }
                }
                var temp = str.split(sep[i-2]);
                if (temp.length > 1){
                    if (trimx(temp[0]) ==='' && temp[1].length > 1 ){
                        str = temp[1];
                        } 
                    }
                return sepi + str ;
        }
      while ( arr.length  ) {
        str = (function( a ) {
            var x = Math.floor( a / 100 ),
                y = Math.floor( a / 10 ) % 10,
                z = a % 10;
                postsep = (arr.length != 0)?', ' : ' ' ;
                if ((x+y+z) === 0){
                    postsep = ' '
                }else{ 
                    if (arr.length == pos-1 && x===0 && pos > 1 ){
                        postsep = ' and ' 
                    } 
                }
               str3.push([trimx(str)+"",trimx(sep[i])+""]);
                return  (postsep)+( x > 0 ? ones[x] + ' hundred ' + (( x == 0 && y >= 0 || z >0 )?' and ':' ') : ' ' ) +                  
                   ( y >= 2 ? tens[y] + ((z===0)?' ':'-') + ones[z] : ones[10*y + z] ); 
        })( arr.shift() ) +seps( sep[i++] ,i ) ;             
      }
      if (p==0){ str2 += str + ' dollars'}
      if (p==1 && !end){str2 += (str!='')?' and '+ str + ' cents':'' } 
      if (p==1 && end ){str2 += ' and ' + ((str==='')?'zero':str) + ' cents '} 
   }
})( NUMBER2TEXT.ones , NUMBER2TEXT.tens , NUMBER2TEXT.sep );