我需要提供一种准确可靠的方法,将数字转换为印度编号系统(在印度次大陆国家使用)的官方文件中使用的单词。
结果应该用于需要计数的任何主题(不仅是货币)。
该任务要求,除了官方编号系统之外,还可以选择使用通用系统(即使用 10 万卢比系统)生成结果。
过去一周我一直在搜索和搜索这个,包括stackoverflow。
以下 StackOverflow (javascript-tagged) 在其标题和/或内容中带有问题和帖子,参考了印度数字或货币,但不同且非常古老(大多数超过 7 到 9 岁)并且不回答我的问题或帮助我(并且在结果上大多是相互矛盾的,这增加了混乱):
我遇到的问题是我不习惯这样的编号系统,并且无法确认我所做的任何编码都会产生正确的结果,因为我不是来自那个地区。
根据这篇解释印度编号系统的 wiki 文章,我创建了以下汇总表(希望是正确的)(根据我的理解)将其转换为步骤/流程逻辑,然后可以将其转换为适当的代码。
因此,基于上述(以及我对主题的理解),我制定了以下javascript函数来处理:
- 官方编号系统,以及
- 通用编号系统,以及
- 如果需要印度货币。
我尝试(尽可能)使用 ES6 关键字和函数。
生成常用文本时,会在每个 Siptlet 文本之间插入一个“逗号”,因为输出很长且难以理解。但是,如果不需要,可以在编码的第 8 行删除此逗号。
我还包含 2 个测试用例代码来测试两个编号系统。
可以为 Common-Use 调用该函数,如下所示:
integerToWordsInd("2222300000")); // Two Hundred Twenty-Two Crore, Twenty-Three Lakh
对于官方系统:
integerToWordsInd ("2222300000",true); // Two Arab Twenty-Two Crore Twenty-Three Lakh
还增加了一个额外的函数 numberCurrencyInd() 将数字转换为印度货币“卢比和派萨”,并且可以使用官方或通用系统作为选项使用调用参数(类似于数字转换函数)。
numberCurrencyIn(3002900000.50); //Three Hundred Crore, Twenty-Nine Lakh Rupees and Fifty Paisa
// or
numberCurrencyIn(3002900000.50,true); // Three Arab Twenty-Nine Lakh Rupees and Fifty Paisa
添加了两 (2) 个额外的休息案例以测试两个系统下的货币生成。
但是,我需要以下帮助和帮助,而我在其他地方找不到答案:
- 使用 Lakh-Crore 系统的编号系统是否正确?
- 输出结果是否在印度次大陆使用且正确。
- 何时使用官方系统和通用系统(十亿)。
- 当我用完秤时,“shankh”之后的秤名是什么。
- 我们写复数比例名称是否带有额外的“s”?即我们是否像英语系统中那样说“三亿,二十万”或“三亿,二十万”?卢比和比萨也是如此。
- 将通用系统作为函数调用的默认值是否正确或合适?
- 通过重复单词“crore”来增加数字的通用系统的顺序是否正确;即“千万千万”然后是“千万千万”等等?
提前感谢您提供的任何帮助。
函数的一些内部工作是:
对于那些感兴趣的人:
以下行将数字转换为 Siptlets (7s) 的数组元素(固定大小 7 位),以用于通用编号系统:
Num = ("0".repeat(6*(Num+="").length % 7) +Num).match(/.{7}/g);
以下行将数字转换为 1 Triplet 的数组元素,然后是 Duplets,用于官方和通用编号系统:
Num = Num> 999 ? [...(Num.slice(0,-3).match(/.{2}/g).map(e => "0"+e)),(Num.slice(-3))] :
[("00"+Num).substr(-3)];
如果请求通用系统,则首先将数字转换为 Siptlets(7's),然后为每个 Siptlet 调用内部函数以使用 Triplet/Duplets 生成单词。
但是,如果相反,请求官方系统,则立即调用内部函数以使用 Triplet/Duplets 生成单词。
/*********************************************************************
* @function : integerToWordsInd()
* @purpose : Converts Unsigned Integers to Indian Numeral Words
* With options for either the Official or the
* Crore-Lakh Counting Systems
* @version : 1.00
* @author : Mohsen Alyafei
* @date : 07 July 2020
* @param : {number} [integer numeric or string]
* @param : Optional {boolean} [Official]
* 0 = Use Crore-Lakh Counting System (default)
* Non 0 = Use the Official System
* @returns : {string} The wordified number string
**********************************************************************/
var Table_0_19 = ["","One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen","Seventeen","Eighteen","Nineteen"],
Table_20_90= ["","","Twenty","Thirty","Forty","Fifty","Sixty","Seventy","Eighty","Ninety"],
Table_Scale= ["","Thousand","Lakh","Crore","Arab","Kharab","Neel","Padma","Shankh","Samudra","Antya","Madhyam","Paraardh","***","***"];
//===================================================================
function integerToWordsInd(Num=0 , Official=0) {
if (Num===0) return "Zero";
if (Official) return Siptlets(Num); // Return Official Numbering System text
let NumWords="";
Num = ("0".repeat(6*(Num+="").length % 7) +Num).match(/.{7}/g); // Create Siptlets Array
return Num.forEach((Siptlet, ScalePos) => { // Return Commmon-Use Numbering System text
let [Scale,SWords] = [(Table_Scale[3]+" ").repeat(Num.length-ScalePos-1).trimRight(), Siptlets(Siptlet)];
NumWords +=(NumWords && SWords ? ", " : "") +SWords +(Scale ? " " : "") +Scale;
}), NumWords;
//===================================================================
function Siptlets(Num, NumWords="") { // Core function (Called for both Systems)
(Num+="").length-3 & 1 && (Num="0"+Num);
Num = Num> 999 ? [...Num.slice(0,-3).match(/.{2}/g).map(e => "0"+e),(Num.slice(-3))]:[("00"+Num).substr(-3)];
return Num.forEach((Duplet,ScalePos) => {if (+Duplet) {
let [Hyphen,Hundreds,Tens,Scale] = [+Duplet[2] ? "-" : "",+Duplet[0],+Duplet.substr(1),Table_Scale[Num.length-ScalePos-1]];
NumWords += (NumWords ? " " : "") + (Hundreds ? Table_0_19[Hundreds] + " Hundred" :"") +
(Hundreds && Tens ? " " : "") + (Tens< 20 ? Table_0_19[Tens] :
Table_20_90[+(Duplet[1])] + Hyphen + Table_0_19[+Duplet[2]]);
NumWords += (NumWords && Scale ? " " : "") + Scale;
}}), NumWords;}
}
//===================================================================
//===================================================================
// Extra Function if needed for Indian Currency
// Uses same input parameters as the above main function
//===================================================================
function numberCurrencyIn(Num=0 , Official=0) {
let n= (Num+"").split(0.1.toLocaleString().substr(1,1)); // Number and Fraction parts
n.length!==2 && (n[1]= ""); // No fraction
Num= n[0];
let Nw="", Fw="", Frc = (n[1]+"00").substring(0,2); // Limit to 2 Decimal Places
Num && (Nw= integerToWordsInd(Num,Official)); // Convert the Whole Number
Frc && (Fw= integerToWordsInd(Frc,Official)); // Convert the Fractional Part
return (Nw ? Nw:"") + (Nw ? " Rupees":"") + (Nw && Fw ? " and ":"") + (Fw ? Fw+" Paisa":""); // Join together
}
//===================================================================
//===================================================================
// Test Cases
//===================================================================
// 1. Test Numbers under Common-Use Numbering System
//===================================================================
var r=0; // test tracker
r |= testN(50,"Fifty");
r |= testN(12000,"Twelve Thousand");
r |= testN(777000,"Seven Lakh Seventy-Seven Thousand");
r |= testN(550001,"Five Lakh Fifty Thousand One");
r |= testN(12345678,"One Crore, Twenty-Three Lakh Forty-Five Thousand Six Hundred Seventy-Eight");
r |= testN(123456789,"Twelve Crore, Thirty-Four Lakh Fifty-Six Thousand Seven Hundred Eighty-Nine");
r |= testN(1234567890,"One Hundred Twenty-Three Crore, Forty-Five Lakh Sixty-Seven Thousand Eight Hundred Ninety");
r |= testN(12345678900,"One Thousand Two Hundred Thirty-Four Crore, Fifty-Six Lakh Seventy-Eight Thousand Nine Hundred");
if (r==0) console.log("Test Case 1 Numbers (Common-Use Numbering System) Passed.");
//===================================================================
// 2. Test Numbers under Official Numbering System
//===================================================================
var r=0; // test tracker
r |= testN(50,"Fifty");
r |= testN(12000,"Twelve Thousand",true);
r |= testN(777000,"Seven Lakh Seventy-Seven Thousand",true);
r |= testN(550001,"Five Lakh Fifty Thousand One",true);
r |= testN(12345678,"One Crore Twenty-Three Lakh Forty-Five Thousand Six Hundred Seventy-Eight",true);
r |= testN(123456789,"Twelve Crore Thirty-Four Lakh Fifty-Six Thousand Seven Hundred Eighty-Nine",true);
r |= testN(1234567890,"One Arab Twenty-Three Crore Forty-Five Lakh Sixty-Seven Thousand Eight Hundred Ninety",true);
r |= testN(12345678900,"Twelve Arab Thirty-Four Crore Fifty-Six Lakh Seventy-Eight Thousand Nine Hundred",true);
if (r==0) console.log("Test Case 2 Numbers (Official Numbering System) Passed.");
//===================================================================
// 3. Test Currency under Common-Use Numbering System
//===================================================================
var r=0; // test tracker
r |= testC(1,"One Rupees");
r |= testC(2.0,"Two Rupees");
r |= testC(2.01,"Two Rupees and One Paisa");
r |= testC(0.3,"Thirty Paisa");
r |= testC(.3,"Thirty Paisa");
r |= testC(3002900000.50,"Three Hundred Crore, Twenty-Nine Lakh Rupees and Fifty Paisa");
r |= testC(220000,"Two Lakh Twenty Thousand Rupees");
if (r==0) console.log("Test Case 3 Currency (Common-Use Numbering System) Passed.");
//===================================================================
// 4. Test Currency under Official Numbering System
//===================================================================
var r=0; // test tracker
r |= testC(3002900000.50,"Three Arab Twenty-Nine Lakh Rupees and Fifty Paisa",true);
r |= testC(55000000000,"Fifty-Five Arab Rupees",true);
if (r==0) console.log("Test Case 4 Currency (Official Numbering System) Passed.");
//===================================================================
function testN(n,tobe,f) {let r = integerToWordsInd(n,f);
if (r !== tobe) {console.log(`${n} Output : ${r}\n${n} Should be: ${tobe}`);return 1;}}
function testC(n,tobe,f) {let r = numberCurrencyIn(n,f);
if (r !== tobe) {console.log(`${n} Output : ${r}\n${n} Should be: ${tobe}`);return 1;}}