1.0.2 • Published 3 years ago

chinesenum v1.0.2

Weekly downloads
76
License
MIT
Repository
github
Last release
3 years ago

中文数字转换支持库

ChineseNum

简介

chinesenum用于中文数字表示法与阿拉伯数字表示法的转换.核心部分,使用数组表示有效数字和数量单位,突破了其他npm包使用number类型算数取模的粗暴方法带来的位数限制(最多支持16位),同时采用了更优化算法,不需要算数取模,算数整除等算术运算,速度更快bug更少.此npm包广泛支持各种中文数字表示方法,提供配置参数可供用户精准定制转换后的结果.在处理用户输入数据的时候使用正则表达式过滤非法输入符号,增强了程序的鲁棒性.

此npm包支持中文表示法:

支持正负号 简体中文数字(cn) 繁体中文数字(CN) 金融人民币金额大写简(繁)中文数字(money/MONEY) 口语简(繁)中文数字(cn spoken/CN spoken) 中国军用数字表示(army/ARMY) 国标数字单位格式化(base:gb) 日韩台等地区数字单位格式化(base:tw) 普通常规数字单位格式化(base:normal) 天干地支(hs/eb. 天干 Heavenly Stems,地支 Earthly Branches) 支持农历日期(day) 中文表示法转阿拉伯数字

用法

//commonjs
var chinesenum = require("chinesenum")
chinesenum.numToChinanumerals(num:number | string | bigint = 0,option:object)
chinesenum.chinanumeralsToNum(num:string = "壹佰叁拾伍元貳角壹分伍厘",option:object)
//ES6 module
import {numToChinanumerals,chinanumeralsToNum} from chinesenum
numToChinanumerals(num:number | string | bigint = 0,option:object)
chinanumeralsToNum(num:string = "壹佰叁拾伍元貳角壹分伍厘",option:object)

numToChinanumerals(num:number | string | bigint = 0,option:object)

参数说明

num

option

  • option :object 可选,默认为{format:'normal',base:'normal'}
interface option{
  format:string,
  base?:string
}

测试

正负值输出

eg:

numToChinanumerals('+123456789')
numToChinanumerals('-123456789')
输入 123456789
正负值输出 一亿二千三百四十五万六千七百八十九
输入 +123456789
正负值输出 正一亿二千三百四十五万六千七百八十九
输入 -123456789
正负值输出 负一亿二千三百四十五万六千七百八十九

数字转军用数字

eg:

numToChinanumerals(123543.123315,{format:'ARMY'})
numToChinanumerals(123543.123315,{format:'army'})
输入 202020000
输出 两洞两洞两洞洞洞洞
输出 两洞两洞两洞洞洞洞
输入 102310101010001200000020
输出 幺洞两叁幺洞幺洞幺洞幺洞洞洞幺两洞洞洞洞洞洞两洞
输出 幺洞两三幺洞幺洞幺洞幺洞洞洞幺两洞洞洞洞洞洞两洞
输入 123543.123315
输出 幺两叁伍肆叁点幺两叁叁幺伍
输出 幺两三五四三点幺两三三幺五
输入 12354.123121
输出 幺两叁伍肆点幺两叁幺两幺
输出 幺两三五四点幺两三幺两幺
输入 0.154
输出 洞点幺伍肆
输出 洞点幺五四
输入 -.215
输出 洞点两幺伍
输出 洞点两幺五
输入 -123.
输出 幺两叁
输出 幺两三
输入 135.0000
输出 幺叁伍
输出 幺三五

常规测试(满足日常需求)

eg:

numToChinanumerals('12345678901234567890')
输入 2020020200
输出 二十亿二千零二万零二百
输入 1000200010
输出 十亿零二十万零一十
输入 202020000
输出 二亿零二百零二万
输入 102310101010001200000020
输出 一千零二十三万亿亿一千零一十亿亿一千零一十万亿零十二亿零二十
输入 10100000000000000020
输出 一千零一十亿亿零二十
输入 12345678901234567890
输出 一千二百三十四亿亿五千六百七十八万亿九千零一十二亿三千四百五十六万七千八百九十
输入 705485621320500230020
输出 七万亿亿零五百四十八亿亿五千六百二十一万亿三千二百零五亿零二十三万零二十
输入 10020202000
输出 一百亿二千零二十万二千
输入 10101010
输出 一千零一十万一千零一十
输入 10
输出 十
输入 0
输出 零

简繁输入测试(需要指定option的format字段为'cn'或'CN')

eg:

numToChinanumerals('705485621320500230020',{format:'cn'})
输入 102310101010001200000020
输出 一千〇二十三万亿亿一千〇一十亿亿一千〇一十万亿〇十二亿〇二十
输出 壹仟零貳拾叁萬億億壹仟零壹拾億億壹仟零壹拾萬億零拾貳億零貳拾
输入 10100000000000000020
输出 一千〇一十亿亿〇二十
输出 壹仟零壹拾億億零貳拾
输入 705485621320500230020
输出 七万亿亿〇五百四十八亿亿五千六百二十一万亿三千二百〇五亿〇二十三万〇二十
输出 柒萬億億零伍佰肆拾捌億億伍仟陆佰貳拾壹萬億叁仟貳佰零伍億零貳拾叁萬零貳拾
输入 10
输出 十
输出 拾
输入 0
输出 〇
输出 零

口语化输入测试(需要指定option的format字段为'spoken')

eg:

numToChinanumerals('2000202020',{format:'cn spoken'})
输入 2020020200
标准输出 二十亿二千〇二万〇二百
口语化输出 二十亿两千〇二万〇两百
输入 2000202020
标准输出 二十亿〇二十万二千〇二十
口语化输出 二十亿〇二十万两千〇二十
输入 202022222
标准输出 二亿〇二百〇二万二千二百二十二
口语化输出 两亿〇两百〇二万两千两百二十二
输入 202022202
标准输出 二亿〇二百〇二万二千二百〇二
口语化输出 两亿〇两百〇二万两千两百〇二
输入 102210202020010200000020
标准输出 一千〇二十二万亿亿一千〇二十亿亿二千〇二十万亿〇一百〇二亿〇二十
口语化输出 一千〇二十二万亿亿一千〇二十亿亿两千〇二十万亿〇一百〇二亿〇二十
输入 10100000000000000020
标准输出 一千〇一十亿亿〇二十
口语化输出 一千〇一十亿亿〇二十
输入 10020202000
标准输出 一百亿二千〇二十万二千
口语化输出 一百亿两千〇二十万两千
输入 20
标准输出 二十
口语化输出 二十
输入 2
标准输出 二
口语化输出 二

金额输入测试(需要指定option的format字段为'money'或'MONEY')

eg:

numToChinanumerals('12354.123121', { format: 'money' })
numToChinanumerals('12354.123121', { format: 'MONEY' })
输入 202020000
标准输出 二亿〇二百〇二万
金额输出 貳億零貳佰零貳萬元整
输入 102310101010001200000020
标准输出 一千〇二十三万亿亿一千〇一十亿亿一千〇一十万亿〇十二亿〇二十
金额输出 壹仟零貳拾叁萬億億壹仟零壹拾億億壹仟零壹拾萬億零壹拾貳億零貳拾元整
输入 123543.123315
标准输出 十二万三千五百四十三点一二三三一五
金额输出 壹拾貳萬叁仟伍佰肆拾叁元壹角貳分叁厘
输入 12354.123121
标准输出 一万二千三百五十四点一二三一二一
金额输出 壹萬貳仟叁佰伍拾肆元壹角貳分叁厘
输入 0.154
标准输出 〇点一五四
金额输出 零元壹角伍分肆厘
输入 .215
标准输出 〇点二一五
金额输出 零元貳角壹分伍厘
输入 -123.
标准输出 负一百二十三
金额输出 負壹佰貳拾叁元整
输入 135.0000
标准输出 一百三十五
金额输出 壹佰叁拾伍元整

数量单位及大数(超过16位)输入测试(需要指定option的base字段为'normal'或'gb'或'tw')

eg:

numToChinanumerals('102310101010001200000020', { format: 'cn' })
numToChinanumerals('102310101010001200000020', { format: 'cn', base:'normal' })
numToChinanumerals('102310101010001200000020', { format: 'cn', base:'gb' })
numToChinanumerals('102310101010001200000020', { format: 'cn', base:'tw' })
输入 102310101010001200000020
标准输出 一千〇二十三万亿亿一千〇一十亿亿一千〇一十万亿〇十二亿〇二十
国标输出 一千〇二十三垓一千〇一十京一千〇一十太〇十二亿〇二十
台标输出 一千〇二十三垓一千〇一十京一千〇一十兆〇十二亿〇二十
输入 10100000000000000020
标准输出 一千〇一十亿亿〇二十
国标输出 一千〇一十京〇二十
台标输出 一千〇一十京〇二十
输入 705485621320500230020
标准输出 七万亿亿〇五百四十八亿亿五千六百二十一万亿三千二百〇五亿〇二十三万〇二十
国标输出 七垓〇五百四十八京五千六百二十一太三千二百〇五亿〇二十三万〇二十
台标输出 七垓〇五百四十八京五千六百二十一兆三千二百〇五亿〇二十三万〇二十

小数输入测试(需要输入数为小数)

eg:

numToChinanumerals('123543.123315',{format:'MONEY'})
numToChinanumerals('123543.123315',{format:'cn'})
输入 123543.123315
输出 十二万三千五百四十三点一二三三一五
输出 拾貳萬叁仟伍佰肆拾叁點壹貳叁叁壹伍
输出 幺两叁伍肆叁点幺两叁叁幺伍
输出 壹拾貳萬叁仟伍佰肆拾叁元壹角貳分叁厘
输入 12354.123121
输出 一万二千三百五十四点一二三一二一
输出 壹萬貳仟叁佰伍拾肆點壹貳叁壹貳壹
输出 幺两叁伍肆点幺两叁幺两幺
输出 壹萬貳仟叁佰伍拾肆元壹角貳分叁厘
输入 0.154
输出 〇点一五四
输出 零點壹伍肆
输出 洞点幺伍肆
输出 零元壹角伍分肆厘
输入 -154.25
输出 负一百五十四点二五
输出 負壹佰伍拾肆點貳伍
输出 幺伍肆点两伍
输出 負壹佰伍拾肆元貳角伍分
输入 -.215
输出 负〇点二一五
输出 零點貳壹伍
输出 洞点两幺伍
输出 零元貳角壹分伍厘
输入 -123.
输出 负一百二十三
输出 負壹佰貳拾叁
输出 幺两叁
输出 負壹佰貳拾叁元整
输入 456554
输出 四十五万六千五百五十四
输出 肆拾伍萬陆仟伍佰伍拾肆
输出 肆伍陆伍伍肆
输出 肆拾伍萬陆仟伍佰伍拾肆元整
输入 135.0000
输出 一百三十五
输出 壹佰叁拾伍
输出 幺叁伍
输出 壹佰叁拾伍元整

中文星期天干地支输出

eg:

numToChinanumerals(5,{format:'WK'})
numToChinanumerals(5,{format:'wk'})
numToChinanumerals(7,{format:'hs'})   //天干(Heavenly Stems)
numToChinanumerals(11,{format:'eb'})  //地支(Earthly Branches)
输入 2
周输出 周二
星期输出 二
天干输出 乙
地支输出 丑
输入 10
周输出 周三
星期输出 三
天干输出 癸
地支输出 酉
输入 12
周输出 周五
星期输出 五
天干输出 乙
地支输出 亥
输入 26
周输出 周五
星期输出 五
天干输出 己
地支输出 丑
输入 -12.2
周输出 周五
星期输出 五
天干输出 乙
地支输出 亥
输入 0
周输出 周日
星期输出 日
天干输出 癸
地支输出 亥
输入 -.23
周输出 周日
星期输出 日
天干输出 癸
地支输出 亥
输入
周输出 周日
星期输出 日
天干输出 癸
地支输出 亥

中文农历日期输出

eg:

numToChinanumerals(5,{format:'day'})
numToChinanumerals(15,{format:'day'})
numToChinanumerals(20,{format:'day'})
numToChinanumerals(21,{format:'day'})
numToChinanumerals(30,{format:'day'})
输入 8
农历日期输出 初八
输入 10
农历日期输出 初十
输入 11
农历日期输出 十一
输入 19
农历日期输出 十九
输入 20
农历日期输出 廿十
输入 26
农历日期输出 廿六
输入 30
农历日期输出 三十
输入 31
农历日期输出 三十一
输入 32
农历日期输出 初一
输入 33

鲁棒性测试

eg:

let arr = ['/0-.123','0s000-1s--32w1','2 a3.2.3-5646','00a.-456ds54 1564','a00-.123']
arr.forEach((v)=>{console.log(numToChinanumerals(v))})
输入: /0-.123
输出: 负零点一二三
输入: 0s000-1s--32w1
输出: 负一千三百二十一
输入: 2 a3.2.3-5646
输出: 二十三点二三五六四六
输入: 00a.-456ds54 1564
输出: 零点四五六五四一五六四
输入: a00-.123      
输出: 负零点一二三

同类型对比测试

eg:

numToChinese(10101010001200000000)
numToChinanumerals(10101010001200000000)
输入: 00a.-456ds54 1564
某功能类似的库输出: 抛出异常程序崩溃
我重新编写的库输出: 零点四五六五四一五六四
输入: 1000200010
某功能类似的库输出: 一十亿零二十万零一十
我重新编写的库输出: 十亿零二十万零一十
输入: 1000200010
某功能类似的库输出: 一十亿零二十万零一十
我重新编写的库输出: 十亿零二十万零一十
输入: 202020000
某功能类似的库输出: 二亿零二百零二万零
我重新编写的库输出: 二亿零二百零二万
输入: 10101010001200000000
某功能类似的库输出: 一千零一十亿亿一千零一十万亿零一十二亿零零
我重新编写的库输出: 一千零一十亿亿一千零一十万亿零十二亿
输入: 0000
某功能类似的库输出: 零
我重新编写的库输出: 零
输入: 10
某功能类似的库输出: 一十
我重新编写的库输出: 十
输入: 0
某功能类似的库输出:   \\没错这里什么输出都没有
我重新编写的库输出: 零
输入: 10101010000000000000
某功能类似的库输出: 一千零一十亿亿一千零一十万亿零零零
我重新编写的库输出: 一千零一十亿亿一千零一十万亿
输入: 200200000
某功能类似的库输出: 二亿零二十万零
我重新编写的库输出: 二亿零二十万
输入: 10101010001200000020
某功能类似的库输出: 一千零一十亿亿一千零一十万亿零一十二亿零二十
我重新编写的库输出: 一千零一十亿亿一千零一十万亿零十二亿零二十

chinanumeralsToNum(str:string = '', option:object = {format:'cn'})

参数说明

str

  • str:string 可选,默认为0

option

  • option :object 必选,默认为{format:'cn'}
interface option{
  format:string,
}

测试

军用数字输出

eg:

chinanumeralsToNum('幺两叁伍肆叁点幺两叁叁幺伍', { format: 'army' })
输入 幺洞两三幺洞幺洞幺洞幺洞洞洞幺两洞洞洞洞洞洞两洞
输出 102310101010001200000020
输入 幺两叁伍肆叁点幺两叁叁幺伍
输出 123543.123315

一般中文数字输出

eg:

chinanumeralsToNum('二千六百五十垓〇一百六十五京四千一百兆〇二百二十五亿四千五百二十万〇一百五十二', { format: 'cn' })
输入 二千六百五十垓〇一百六十五京四千一百兆〇二百二十五亿四千五百二十万〇一百五十二
输出 265001654100022545200152
输入 一百〇四万亿亿五千亿亿一千八百三十三万亿〇一百三十五亿四千六百〇四万八千五百
输出 10450001833013546048500
输入 七垓〇五百四十八京五千六百二十一太三千二百〇五亿〇二十三万〇二十
输出 705485621320500230020

含有小数位的数字输出

eg:

chinanumeralsToNum('十二万三千五百四十三点一二三三一五', { format: 'cn' })
输入 十二万三千五百四十三点一二三三一五
输出 123543.123315
输入 拾貳萬叁仟伍佰肆拾叁點壹貳叁叁壹伍
输出 123543.123315
输入 零元貳角壹分伍厘
输出 0.215
输入 壹佰叁拾伍元整
输出 135
输入 零元零角零分零厘
输出 0
输入 零元零角壹分零厘
输出 0.01

注意

  1. option 的format字段严格遵循大小写,如果需要简体就用小写,需要繁体就用大写例如{format:'MONEY'}/{format:'army'},千万不能写成Money/aRmY一定会报错.当然缺省属性normal和口语化附加属性spoken除外,只要是spoken这个单词就行不在乎字母大小写.
  2. format:'normal'或缺省format字段时其为默认输出样式,输出结果与format:'cn'输出结果类似,只是format:'cn'输出结果用'〇'表示,不太自然,除非你需要用'〇'表示0,此时使用format:'cn'即可.
  3. spoken 表示口语化输出, 本质差别为口语中部分量词'2'读作'两'而不说'二',例如:'我的车买的时候花了二十万.我的MacbookPro原价两万多.在场两千多人.我兜里只剩二百块千'等等此时虽然都是数字'2'但却有不同的读法,算是中文口语特色了.spoken属性为附加属性,一般不单独使用.使用时需要与'normal','cn','CN'一起出现组成format:'normal spoken',format:'cn spoken',format:'CN spoken',原理上可以与money或MONEY同时使用format:'money spoken',用于收款播报读音.但是,一般需要转换成人民币金额的情况直接使用format:'money'或format:'MONEY'即可.
  4. 理论上使用数组表示数字可以无限长度,但是根据实际情况和现实世界可观测数量级这里设置上限24位数字,数字再长程序写着费劲,也没有意义毕竟目前已观测星星也仅有一千亿多颗,全球美元总量也仅有13万亿多元.相对24位10进制数来讲可真是个大数了.
  5. v1.0.1添加了对小数的支持,其中用于表示人民币金额的金融数字输出规则为小数点后保留3位,并按照角/分/厘的数量单位进行划分.其他格式化方法按照数字简单中文转换进行,但是如果小数位为0,称为假小数则按照整数处理.
  6. v1.0.2添加了输入中文数字输出阿拉伯数字的方法.此方法只保证转换此包生成的中文数字,不保证其他可能不合法的中文数字的正常转换.
  7. v1.0.2添加对天干地支的支持.虽然用途有限,但不能没有.

优势

  • 基于字符串和数组模拟大数,突破JavaScript内置number类型运算极限,内部算法优化,减少重复操作次数,相对于数学除法和取模运算,访问一个最大长度才12位的数组运算量小得多.各种极限测试降低bug出现概率.

  • 相对于现存的npm库,功能更全面,运算速度快,bug少,支持最大长度长,可扩展性好,最最重要一点使用TypeScript编写(面向TypeScript,就是面向未来),自动生成.d.ts类型标注文件,可以更好适应使用TypeScript开发.

历史版本

  • ✅v1.0.0 发布chinesenum包,实现基本功能
  • ✅v1.0.1 添加对小数的支持,实现一般小数转换和金额角分厘的转换
  • ✅v1.0.2 实现将中文数字转换成阿拉伯数字,添加对天干地支的支持,添加对中文星期的支持,添加中国农历日期支持
  • 🟩v1.0.X 添加更多支持,优化算法,修复潜在BUG
  • ...