因為從來沒有過這種需要, 所以沒去思考這種問題, 還以為 .Net 一定有提供相關的函數。不過等到真正需要這種功能時, 才發現 .Net 似乎並沒有提供如此功能, 找過 Visual Basic 程式庫, 也沒有找到...
因為從來沒有過這種需要, 所以沒去思考這種問題, 還以為 .Net 一定有提供相關的函數。不過等到真正需要這種功能時, 才發現 .Net 似乎並沒有提供如此功能, 找過 Visual Basic 程式庫, 也沒有找到。沒辦法, 只好自己寫一個, 程式如下:
/// <summary>
/// 將國字數字轉換為阿拉伯數字 - 僅支援一億以下之數字; 若格式有誤, 可能出現 Exception
/// </summary>
/// <param name="cnum">請輸入正確格式之國字數字, 如 "八千四百二十一萬三千五百六十三"</param>
public static int convChineseNumber(string cnum)
{
cnum = cnum.Replace("一十", "十");cnum = cnum.TrimEnd();
char[] cnums = cnum.ToCharArray();
int sum = 0, sectionUnit = 0, sectionsum = 0;
foreach (char c in cnums)
{
int arab = mapCnumLetters(c);
if (isMultiplier(c))
{
if (isSegmentDelimeter(c)) // 萬/億
{
sectionsum = sum * arab;
sum = sectionsum;
if (sum < 0)
throw new Exception("輸入的字串無法解析!");
sectionsum = 0;
}
else // 十/百/千
{
if (sectionUnit == 0)
sectionsum = 10; // 特別處理 "十萬", "十一萬" 之類的狀況
else
{
sectionsum -= sectionUnit;
sum -= sectionUnit;
sectionsum = sectionUnit * arab;
}
sum += sectionsum;
if (sum < 0)
throw new Exception("輸入的字串無法解析!");
}
}
else
{
sectionUnit = arab;
sum += arab;
if (sum < 0)
throw new Exception("輸入的字串無法解析!");
sectionsum += arab;
}
}
return sum;
}private static bool isSegmentDelimeter(char cnum)
{
switch (cnum)
{
case '萬':
return true;
case '億':
return true;
default:
return false;
}
}private static bool isMultiplier(char cnum)
{
switch (cnum)
{
case '十':
return true;
case '拾':
return true;
case '百':
return true;
case '佰':
return true;
case '千':
return true;
case '仟':
return true;
case '萬':
return true;
case '億':
return true;
default:
return false;
}
}private static int mapCnumLetters(char cnum)
{
switch (cnum)
{
case '零':
return 0;
case '一':
return 1;
case '壹':
return 1;
case '二':
return 2;
case '貳':
return 2;
case '三':
return 3;
case '參':
return 3;
case '四':
return 4;
case '肆':
return 4;
case '五':
return 5;
case '伍':
return 5;
case '六':
return 6;
case '陸':
return 6;
case '七':
return 7;
case '柒':
return 7;
case '八':
return 8;
case '捌':
return 8;
case '九':
return 9;
case '玖':
return 9;
case '十':
return 10;
case '拾':
return 10;
case '廿':
return 20;
case '丗':
return 30;
case '百':
return 100;
case '佰':
return 100;
case '千':
return 1000;
case '仟':
return 1000;
case '萬':
return 10000;
case '億':
return 100000000;
default:
return 0;
}
}
先聲明一下, 這個程式尚未經過嚴謹的測試, 也沒有提供防呆或偵錯的功能, 所以如果你打算拿去使用在重要的情境中 (例如薪資計算、財報編彙等), 你必須自己好好測試一番; 萬一有任何問題, 我可不負任何責任喔!
在我自己的測試中, 我已經測試過幾組數字:
- 五
- 十五
- 三十五
- 廿五
- 丗五
- 二十
- 二十一
- 二十一萬
- 二十一萬三千五百
- 十一萬三千五百六十三
- 一十一萬三千五百六十三
- 八千四百萬零六十三
- 捌仟肆佰萬零陸拾參
- 八千四百二十一萬三千五百六十三
- 捌仟肆佰貳拾壹萬參仟伍佰陸拾參
不過如果輸入的數字有錯亂, 例如 「二十一千」, 則會得到錯誤的數字。此外, 這個函數只支援一億以下的數字, 如果你需要支援到一億以上, 你最好自己修改一下。
Microsoft 自己有提供一個 Visual Studio International Pack, 裡面的功能當中即有一項就是把阿拉伯數字轉換為中文數字(很可惜, 好像不能轉回來), 你如果有興趣, 不妨前往參考一下: