「中文數字」是中文的數字表示方式,例如「123」,可以表示為「一百二十三」。中文數字如同英文字母一樣有區分大小寫,例如「123」的中文數字小寫為「一百二十三」,大寫則為「壹佰貳拾參」。至於單位則有個、十、百、千、萬、億、兆、京等等,相同單位的數量級也並非只有一種,而是分為下數、萬進、中數和上數這主要四種系統。中文數字是老祖宗的智慧,但對於現在的數位系統來說並不怎麼合適,還是得經過轉換才行。那麼要如何使用Rust程式語言進行中文數字的轉換呢?



在進入Rust程式語言之前,先來了解一下下數、萬進、中數和上數四種進位系統。北周甄鸞所作的《五經算術》有提到:

按黃帝為法,數有十等。及其用也,乃有三焉。十等者,謂「億、兆、京、垓、秭、壤、溝、澗、正、載」也。三等者,謂「上、中、下」也。其下數者,十十變之。若言十萬曰億,十億曰兆,十兆曰京也。中數者,萬萬變之。若言萬萬曰億,萬萬億曰兆,萬萬兆曰京也。上數者,數窮則變。若言萬萬曰億,億億曰兆、兆兆曰京也。

拿「一兆」來舉例的話,下數的「一兆」對應的數值為「1000000」(106);中數的「一兆」對應的數值為「10000000000000000」(1016);上數的「一兆」對應的數值同中數的「一兆」。以「一京」來舉例的話,下數的「一京」對應的數值為「107」;中數的「一京」對應的數值為「1016」;上數的「一京」對應的數值為「1032」。

而我們平常使用的進位系統為「萬進」,一遇到「萬」就變,因此萬進的「一兆」對應的數值為「1000000000000」(1012),「一京」對應的數值為「1016」。

Chinese Number

「Chinese Number」是筆者開發的套件,提供了「ChineseNumber」特性,可以將Rust程式語言的所有基本數值型別都擁有轉成中文數字的能力。也提供「ChineseNumberToNumber」特性,讓中文數字的字串可以轉成Rust程式語言的基本數值型別。這個套件除了有支援下數、萬進、中數和上數這四種進位系統外,還支援繁體字和簡體字的大小寫。

Crates.io

https://crates.io/crates/chinese-number

Cargo.toml

chinese-number = "*"

使用方法

數值轉中文數字

利用「use」關鍵字將「chinese_number」這個crate底下的「ChineseNumber」特性給引入到目前的程式範圍下,Rust程式語言的所有基本數值就會擁有「to_uppercase_high」、「to_uppercase_middle」、「to_uppercase_ten_thousand」、「to_uppercase_low」、「to_lowercase_high」、「to_lowercase_middle」、「to_lowercase_ten_thousand」、「to_lowercase_low」這幾種方法,能夠傳入要使用的中文變體(即繁體字或簡體字),將基本數值轉成中文數字,並儲存到String結構實體中。如果要將結果輸出到已存在的String結構實體,可以使用它們對應的「_mut」方法,例如「to_uppercase_high_mut」方法。

轉換的程式如下:

extern crate chinese_number;

use chinese_number::{ChineseNumber, ChineseVariant};

assert_eq!("壹佰貳拾參", 123i8.to_uppercase_ten_thousand(ChineseVariant::Traditional));
assert_eq!("壹佰贰拾参", 123i8.to_uppercase_ten_thousand(ChineseVariant::Simple));

assert_eq!("一百二十三", 123i8.to_lowercase_ten_thousand(ChineseVariant::Traditional));
中文數字轉數值

利用「use」關鍵字將「chinese_number」這個crate底下的「ChineseNumberToNumber」特性給引入到目前的程式範圍下,Rust程式語言的String結構實體和字串切片就會擁有「parse_chinese_number」方法,能夠傳入要使用的進位系統,將中文數字字串轉成Rust程式語言內的任意基本數值。

轉換的程式如下:

extern crate chinese_number;

use chinese_number::{ChineseNumberToNumber, ChineseNumberCountMethod};

assert_eq!(123i8, "一百二十三".parse_chinese_number(ChineseNumberCountMethod::TenThousand).unwrap());
assert_eq!(-30303i16, "負三萬零三百零三".parse_chinese_number(ChineseNumberCountMethod::TenThousand).unwrap());
assert_eq!(3212345678u32, "三十二億一千二百三十四萬五千六百七十八".parse_chinese_number(ChineseNumberCountMethod::TenThousand).unwrap());
assert_eq!(10010001001001001000u64, "一千零一京零一兆零一十億零一百萬一千".parse_chinese_number(ChineseNumberCountMethod::TenThousand).unwrap());