เหตุที่เขียนบทความนี้ก็เพราะว่าบางครั้งที่ผมจะเขียนตัวเลขแล้วให้มันแปลงเป็นตัวอักษรเพื่อเอาไปพิมพ์เช็ค หรือว่าเราอาจจะแปลงโปรแกรมนี้ให้เป็นโปรแกรมที่อ่านออกเสียงก็ได้เช่น
เวลาเราเช็คเงินบนมือถือของเราครับ
มาดู Code กันเลยดีกว่าว่าเป็นยังไงในที่นี้ผมเขียนทั้งที่เป็นภาษาอังกฤษและที่เป็นภาษาไทย
ในภาษาอังกฤษนั้นเวลาอ่านตัวเลข จะมี one ten hundred thousand million billion และเลขที่ตั้งแต่ 11-19 ที่จะเป็น Eleven, Twelve, Thirteen ... ไปเรื่อยๆ และหลักสิบก็จะเป็น
Twenty , Thirty ไปเรื่อยๆเช่นกัน โดยใน ภาษาอังกฤษ นั้นไม่มีคำเรียกหลักหมื่น และหลักแสน เราจะเรียกเป็น ten thousand และ hundred thousand แทนและมักจะใส่ and ก่อนที่จะถึงตัวเลขสุดท้าย
ซึ่งต่างจากภาษาไทยครับ
แต่ภาษาไทยหากลงท้ายด้วยเลขหนึ่งแล้วมักจะใช้คำว่าเอ็ด เช่น 11 เราเรียกว่าสิบเอ็ดไม่ใช่สิบหนึ่งอซึ่งรายละเอียดตรงนี้ขึ้นอยู่กับว่าเราจะใช้แบบใดครับ ซึ่งบางคนก็เรียตัวเลขนี้ว่า 101 หนึ่งร้อยหนึ่ง บางคนก็เรียกว่า ร้อยเอ็ด
และในภาษาไทยหลัก 20-29 นั้นจะเรียกเป็นยี่ หลักการคล้ายๆกับ ภาษาอังกฤษในหลักสิบ
รายละเอียดว่าทำยังไงไปดูกันที่ Code เลย ครับ
public class NumberToWordsConvertor
{
private const int MAX_DIGIT_ARRAY_TH = 6;//สะหรับภาษาไทยแบ่งกันที่หลักล้าน
private const int MAX_DIGIT_ARRAY = 4;//สำหรับภาษาอังกฤษแบ่ที่หลักพัน
private string[] _smallNumbers = new string[] {"Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
private string[] _smallNumbersTh = new string[] { "ศูนย์", "หนึ่ง", "สอง", "สาม", "สี่", "ห้า", "หก", "เจ็ด", "แปด", "เก้า"};
private string[] _tens = new string[] { "", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" };
private string[] _scaleNumbers = new string[] { "", "Thousand", "Million", "Billion" };
private string[] _scaleNumbersTh = new string[] { "","สิบ","ร้อย", "พัน", "หมื่น", "แสน" };
//สำหรับแปลงเป็นภาษาอังกฤษ
public string NumberToWords(int number)
{
// หากเป็น 0 ให้ค่าแรกไปเลย
if (number == 0)
return _smallNumbers[0];
int[] digitGroups = new int[MAX_DIGIT_ARRAY];
// ทำให้เป็นพวกทังหมดก่อนครับ
int positive = Math.Abs(number);
for (int i = 0; i < MAX_DIGIT_ARRAY; i++)
{
digitGroups[i] = positive % 1000;
positive /= 1000;
}
string[] groupText = new string[MAX_DIGIT_ARRAY];
for (int i = 0; i < MAX_DIGIT_ARRAY; i++)
groupText[i] = ThreeDigitGroupToWords(digitGroups[i]);
string combined = groupText[0];
bool appendAnd;
appendAnd = (digitGroups[0] > 0) && (digitGroups[0] < 100);
for (int i = 1; i < MAX_DIGIT_ARRAY; i++)
{
if (digitGroups[i] != 0)
{
string prefix = groupText[i] + " " + _scaleNumbers[i];
if (combined.Length != 0)
prefix += appendAnd ? " and " : ", ";
appendAnd = false;
combined = prefix + combined;
}
}
if (number < 0)
combined = "Negative " + combined;
return combined;
}
// สำหรับภาษาไทย
public string NumberToWordsTh(int number) {
string combined = "";
int newnumber = 0;
if (number == 0)
return _smallNumbersTh[0];
int[] digitGroups = new int[MAX_DIGIT_ARRAY_TH];
int positive = Math.Abs(number);
if (positive > 999999)
{
newnumber = positive / 1000000;
positive = positive % 1000000;
}
for (int i = 0; i < MAX_DIGIT_ARRAY_TH; i++)
{
digitGroups[i] = positive % 10;
positive /= 10;
}
string[] groupText = new string[MAX_DIGIT_ARRAY_TH];
for (int i = 0; i < MAX_DIGIT_ARRAY_TH; i++)
{
if (digitGroups[i] > 0)
{
if (digitGroups[i] == 1 && i == 0 && digitGroups[i+1]>0)
{
groupText[i] = "เอ็ด";
}else if ((digitGroups[i] == 2 && i == 1))
{
groupText[i] = "ยี่";
}else if (!(digitGroups[i] == 1 && i == 1)) {
groupText[i] = _smallNumbersTh[digitGroups[i]];
}
}
}
combined += groupText[0];
for (int i = 1; i < MAX_DIGIT_ARRAY_TH; i++)
{
if (digitGroups[i] != 0)
{
string prefix = groupText[i] + _scaleNumbersTh[i];
combined = prefix + combined;
}
}
if (newnumber > 0) {
combined = NumberToWordsTh(newnumber) + "ล้าน" + combined;
}
if (number < 0)
combined = "ลบ " + combined;
return combined;
}
// ตรงนี้ใช้กับ ภาษาอังกฤษอย่างเดียวครับ
private string ThreeDigitGroupToWords(int threeDigits)
{
string groupText = "";
int hundreds = threeDigits / 100;
int tensUnits = threeDigits % 100;
if (hundreds != 0)
{
groupText += _smallNumbers[hundreds] + " Hundred";
if (tensUnits != 0)
groupText += " and ";
}
int tens = tensUnits / 10;
int units = tensUnits % 10;
if (tens >= 2)
{
groupText += _tens[tens];
if (units != 0)
groupText += " " + _smallNumbers[units];
}
else if (tensUnits != 0)
groupText += _smallNumbers[tensUnits];
return groupText;
}
}
หลังจากนั้นเวลาเรียกใช้ก็
int number = 2147483647;
NumberToWordsConvertor convertor = new NumberToWordsConvertor()
String resultEng = convertor.NumberToWords(number).ToUpper();
String resultTh = convertor. NumberToWordsTh (number);
จะได้ผลออกมาดังนี้ครับ
TWO BILLION, ONE HUNDRED AND FORTY SEVEN MILLION, FOUR HUNDRED AND EIGHTY THREE THOUSAND, SIX HUNDRED AND FORTY SEVEN
สองพันหนึ่งร้อยสี่สิบเจ็ดล้านสี่แสนแปดหมื่นสามพันหกร้อยสี่สิบเจ็ด
ในที่นี้เราใช้ตัวแปรประเภท int ใน C# จัมีค่ามากที่สุดคือ 2147483647 ฉนั้นหากตัวเลขมากกว่านี้แล้วจะทำให้ผลออกมาไม่ถูกต้องครับ
ผมคิดว่าแค่นี้ก็น่าจะพอนำไปใช้ได้แล้ว หากอยากจะให้มีอะไรเพิ่มเติมเช่นให้มีคำว่าบาทหรือว่ามี $ หรือว่ามีจุดทศนิยม เราก็สามารถไปเขียนเองได้ในภายหลังไม่ยากเลยใช่ไหมละครับ
1 comment:
ถ้าเปลี่ยน type จาก int เป็น double จะรับค่าได้มากขึ้นไหมคับ
Post a Comment