如何以编程方式从其功能中获取编号系统刻度名称字符串,而无需使用预定义的刻度名称列表

2022-08-25 00:00:00 numbers number-formatting javascript

TL;DR,示例:

Given 0  output results is : ''                (because 1000^0 = zero)
      1  output results is : 'thousand'        (because 1000^1 = thousand)
      2  output results is : 'million'         (because 1000^2 = million)
      3  output results is : 'billion'         (because 1000^3 = billion)
      4  output results is : 'trillion'        (because 1000^4 = trillion)
      .....
     20  output results is : 'novendecillion'  (because 1000^20 = novendecillion)
    351  output results is : 'quinquagintatrecentillion'
    454  output results is : 'tresquinquagintaquadringentillion'
   1000  output results is : 'novenonagintanongentillion'

详情:

将数字转换为英文单词时,需要说明刻度名称(即,千、百万、万亿等)。根据生成的数字,该值可以根据需要设置为任意大小。在这种情况下,刻度名称通常放在array中。

如果输出需要使用非常大的数字,则小数位数名称需要扩展到大型小数位数名称,有时超过10^200,则这将成为一个问题,因为数组变得非常大并且不合理地在数组中硬编码如此大量的字符串,并可能导致打字错误和错误。

鉴于刻度名称的强大功能,如何以编程方式返回刻度名称字符串?

在维基百科(Names of large numbers)上可以找到更多关于大数字名称的细节和信息。为简单起见,请使用美国、英国、加拿大使用的短刻度数字系统,即使用十亿而不是毫秒的系统。

刻度名称是基本数字1000的幂。

 0 means 1000^0  = ""
 1 means 1000^1  = thousand
 2 means 1000^2  = million
 3 means 1000^3  = billion
 4 means 1000^4  = trillion
11 means 1000^11 = decillion

最大为1000次方的刻度数名称就足够了,因为这意味着数字的右侧有3000个零。

输出需要采用短刻度编号系统(英语)格式。

其他格式,如长刻度编号系统(欧洲/法国系统)或其他语言的法语、阿拉伯语、波斯语等。


我在短刻度编号系统(英语)中的答案是StackOverflow推荐的这个问题的答案:Can I answer my own question?


解决方案

此代码使用用于形成数字前缀的Conway-Guy系统生成短刻度系统&下的大数字刻度的全名。

有关Conway-Guy系统的信息可在this Wikipedia article的末尾找到。

大数的命名过程基于取数字的数字幂,并将其单位、十位和百位的拉丁根与后缀

注意:连接的顺序和顺序是从最低到最大(这与我们如何发音和写数字相反,例如123[123])。

这样,10^3000以下的数字可以轻松命名。

前缀是根据John Horton Conway和Richard K.Guy使用拉丁语词根描述的系统构建的。

下表列出了Conway-Guy形成前缀的系统:

可以通过连接单位名称、十进制名称、百位名称,并在连接的字符串末尾添加llion";来生成比例尺名称,如下所示:

但是,串联并不是那么直接向前,因为四(4)个单位名称(tre(3)、se(6)、Septe(7)和nove(9))不能按原样直接串联,需要根据后面的十位或百位名称进行修改。

例如:如果要与(比方说)20(Viginti)或300(Tricinti)连接,则需要将设备名称";";更改为";tres";。

同样,也需要将因此,对于每个十进制名称和百进制名称,在其前面可以有一个相应的单位名称,用于连接(这就是如此难看的数组的目的)。

下表根据十位名称和百位名称列出了每个设备名称所需的更改。

在连接各种名称时需要考虑的另一个要求是,当设备名称要与单词";llion连接时,需要将以";a";结尾的设备名称更改为以";i";结尾。以&q;a&q;结尾的名称仅存在于十个名称中!

例如:

数字10^31==>;";triinta";变成";&triinti

数字10^81==

这种情况的处理在";ten";数组中提供;作为Boolean True的最后一个元素是标记。

下图显示了其他示例:

该函数的输入是一个以1000为底的幂的数字。

  • 1表示1000^1=1000
  • 2表示1000^2=100万(百万)
  • 3表示1000^3=10亿

代码函数用于为(美国、英国、加拿大,即使用十亿而不是毫秒的系统)中使用的短刻度数字系统生成刻度名称。您可以阅读有关短刻度和长刻度数字系统之间的差异here。

可以很容易地修改代码,以使用相同的数组为长标度系统生成字符串。在本例中,最大功率为10^6000(即1加上6000个零)。

包含测试各种数字的测试代码。

数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
/************************************************************************
* @Function    : getScaleName()
* @Purpose     : Get the full name of the Short Scale Numeral System
*                Using the Conway-Guy system for forming number prefixes
*                Handles power from 0 to 1000
*                The largest scale name is, therefore, the number with
*                3,000 zeros (Novenonagintanongentillion)
*
* @Version     : 1.00
* @Author      : Mohsen Alyafei
* @Date        : 11 Mar 2022
* @Param       : {number} the power numeral of the base 1000
*                e.g.  1 means 1000^1 = 1,000 (thousand)
*                e.g.  2 means 1000^2 = 1,000,000 (million)
*                e.g.  3 means 1000^3 = 1,000,000,000 (billion)
*                e.g.  4 means 1000^4 = 1,000,000,000,000 (trillion)
*                e.g. 11 means 1000^11 = decillion
*
* @Returns     : {string} The name of the large number
* @Reference   : https://en.wikipedia.org/wiki/Names_of_large_numbers
*************************************************************************/


//===================================================================
function getScaleName(power=0) {
if (power<11) return power<2?["","thousand"][power]:["m","b","tr","quadr","quint","sext","sept","oct","non"][power-2]+"illion";
power-=1;
let tensList = [
[              ,[,,,,,,,,,,0]],
["deci"        ,[,,,,,,,"n",,"n",0]],       // 10
["viginti"     ,[,,,"s",,,"s","m",,"m",0]], // 20
["triginta"    ,[,,,"s",,,"s","n",,"n",1]], // 30
["quadraginta" ,[,,,"s",,,"s","n",,"n",1]], // 40
["quinquaginta",[,,,"s",,,"s","n",,"n",1]], // 50
["sexaginta"   ,[,,,,,,,"n",,"n",1]],       // 60
["septuaginta" ,[,,,,,,,"n",,"n",1]],       // 70
["octoginta"   ,[,,,,,,"x","m",,"m",1]],    // 80
["nonaginta"   ,[,,,,,,,,,,1]]              // 90
],
hundredsList = [
[              ,[,,,,,,,,,]],
["centi"       ,[,,,,,,"x","n",,"n"]],    // 100
["ducenti"     ,[,,,,,,,"n",,"n"]],       // 200
["trecenti"    ,[,,,"s",,,"s","n",,"n"]], // 300
["quadringenti",[,,,"s",,,"s","n",,"n"]], // 400
["quingenti"   ,[,,,"s",,,"s","n",,"n"]], // 500
["sescenti"    ,[,,,,,,,"n",,"n"]],       // 600
["septingenti" ,[,,,,,,,"n",,"n"]],       // 700
["octingenti"  ,[,,,,,,"x","m",,"m"]],    // 800
["nongenti"    ,[,,,,,,,,,]]              // 900
],
hund     = ~~(power / 100),               // Hundred Digit
ten      = ~~(power % 100 / 10),          // ten Digit
unit     = power % 10 % 10,               // unit Digit
unitName = ["","un","duo","tre","quattuor","quin","se","septe","octo","nove"][unit], // Get unit Name from Array
tenName  = tensList[ten][0],              // Get Tens Name from Array
hundName = hundredsList[hund][0];         // Get Hundreds Name from Array
tenName??=""; hundName??="";              // make it an empty string if undefined

// convert ten names ending with "a" to "i" if it was proceeding the "llion" word
if (!hund && tensList[ten][1][10]) tenName = tenName.slice(0,-1)+"i";
// Pickup and add the correct suffix to the unit Name (s,x,n, or m)
if (ten) tenName           =  (tensList[ten][1][unit]     ??="")+tenName;
else if (hund && !ten) hundName =  (hundredsList[hund][1][unit]??="")+hundName;
return unitName + tenName + hundName + "llion";  // Create name
}
//===================================================================














//=========================================
//             Test Codes
//=========================================

var r=0; // test tracker
r |= test(0,"");
r |= test(1,"thousand");
r |= test(2,"million");
r |= test(3,"billion");
r |= test(4,"trillion");
r |= test(5,"quadrillion");
r |= test(6,"quintillion");
r |= test(7,"sextillion");
r |= test(8,"septillion");
r |= test(9,"octillion");
r |= test(10,"nonillion");
r |= test(11,"decillion");
r |= test(12,"undecillion");
r |= test(13,"duodecillion");
r |= test(14,"tredecillion");
r |= test(15,"quattuordecillion");
r |= test(16,"quindecillion");
r |= test(17,"sedecillion");
r |= test(18,"septendecillion");
r |= test(19,"octodecillion");
r |= test(20,"novendecillion");
r |= test(21,"vigintillion");
r |= test(22,"unvigintillion");
r |= test(23,"duovigintillion");
r |= test(24,"tresvigintillion");
r |= test(25,"quattuorvigintillion");
r |= test(26,"quinvigintillion");
r |= test(27,"sesvigintillion");
r |= test(28,"septemvigintillion");
r |= test(29,"octovigintillion");
r |= test(30,"novemvigintillion");
r |= test(31,"trigintillion");
r |= test(32,"untrigintillion");
r |= test(33,"duotrigintillion");
r |= test(34,"trestrigintillion");
r |= test(35,"quattuortrigintillion");
r |= test(36,"quintrigintillion");
r |= test(37,"sestrigintillion");
r |= test(38,"septentrigintillion");
r |= test(39,"octotrigintillion");
r |= test(40,"noventrigintillion");
r |= test(41,"quadragintillion");
r |= test(51,"quinquagintillion");
r |= test(61,"sexagintillion");
r |= test(71,"septuagintillion");
r |= test(81,"octogintillion");
r |= test(91,"nonagintillion");
r |= test(101,"centillion");
r |= test(102,"uncentillion");
r |= test(111,"decicentillion");
r |= test(112,"undecicentillion");
r |= test(121,"viginticentillion");
r |= test(122,"unviginticentillion");
r |= test(131,"trigintacentillion");
r |= test(141,"quadragintacentillion");
r |= test(151,"quinquagintacentillion");
r |= test(161,"sexagintacentillion");
r |= test(171,"septuagintacentillion");
r |= test(181,"octogintacentillion");
r |= test(191,"nonagintacentillion");
r |= test(201,"ducentillion");
r |= test(251,"quinquagintaducentillion");
r |= test(301,"trecentillion");
r |= test(351,"quinquagintatrecentillion");
r |= test(378,"septenseptuagintatrecentillion");
r |= test(401,"quadringentillion");
r |= test(451,"quinquagintaquadringentillion");
r |= test(454,"tresquinquagintaquadringentillion");
r |= test(501,"quingentillion");
r |= test(601,"sescentillion");
r |= test(701,"septingentillion");
r |= test(801,"octingentillion");
r |= test(901,"nongentillion");
r |= test(999,"octononagintanongentillion");
r |= test(1000,"novenonagintanongentillion");

if (r==0) console.log("All Test Units Passed.");


//================
function test(n,should) {
var result = getScaleName(n);
if (result !== should) {
    console.log(`${n} Output   : ${result}`);
    console.log(`${n} Should be: ${should}`);
    return 1;
}
}

相关文章