Number To Word (Arabic Version)

Download NumberToWord.zip – 78.64 KB

Download NumberToWord – Java (Thanks to Mike)

Introduction

In this article I will talk about converting Numbers to written words in English & Arabic (Tafqeet as pronounced in Arabic).

Background

I was in the middle of programming my project when I needed a code to convert a number to written text.

Our project is mulltilingual, so I needed two versions: one for English and one for Arabic.

I googled “Number to Text” or “Number to Word” and I found a lot of code to convert number to written words for English language and many of them worked fine.

I also found code to convert number to words for Arabic language but unfortunately many of them didn’t work as expected!

So I have decided to go the long way to build a class to do the conversion to Arabic & added also English language support.

Here is a screen shot of a test project that uses the class:


Using the code

I have to mention that I used a code written by Justin Rogers from this link as a start:http://weblogs.asp.net/justin_rogers/articles/151757.aspx

This article contains a code that do a good convert for a decimal value into its equivalent English words, but numbers from my application were actually money amounts, so I needed to add currency names to it ( our project is also multinational, so I had to build the string dynamically from the country’s currency).

This was the easy part after I made a few small changes to Justin’s code to fulfill my English-Number-To-Words requirements.

Now comes the complicated part: converting Numbers to written words in Arabic language!

Arabic language is very complicated, and when it comes to converting it to words I think it is the most difficult language because it has so many rules that depend on the “number” state and the “counted” state.

For example:

The number one & two matches the counted in its feminine state, where the numbers from 3 to 10 are contrary to the counted … etc.

So I have used one method to determine a digit feminine status using its group level & Currency Name Feminine field status, here is the method:

private string GetDigitFeminineStatus(int digit, int groupLevel)

{

if (groupLevel == -1)

{ // if it is in the decimal part

if (Currency.IsCurrencyPartNameFeminine)

return arabicFeminineOnes[digit]; // use feminine field

else

return arabicOnes[digit];

}

else

if (groupLevel == 0)

{

if (Currency.IsCurrencyNameFeminine)

return arabicFeminineOnes[digit];// use feminine field

else

return arabicOnes[digit];

}

else

return arabicOnes[digit];

}

The whole convert process depends on dividing the number into Group Levels, each group contains 3 digits & these levels are numbered as in this example:

Number: 987,654,321.345

345: Group Level -1

321: Group Level 0

654: Group Level 1

987: Group Level 2

this is accomplished by this code:

Byte group = 0;

while (tempNumber >= 1)

{

// seperate number into groups

int numberToProcess = (int)(tempNumber % 1000);

tempNumber = tempNumber / 1000;

// convert group into its text

string groupDescription = ProcessArabicGroup(numberToProcess, group, Math.Floor(tempNumber));

group++;

}

Then we have to process each group & convert it to its text depending on its group level.

Inside the ProcesArabicGroup Method, we check for the special case for 200 as it has its special rule in Arabic:

if (hundreds > 0)

{

if (tens == 0 && hundreds == 2) // حالة المضاف

retVal = String.Format(“{0}”, arabicAppendedTwos[0]);

else // الحالة العادية

retVal = String.Format(“{0}”, arabicHundreds[hundreds]);

}

Also the number 2 has another special rule which is dicussed by this code:

if (tens == 2 && hundreds == 0 && groupLevel > 0)

{ // This is special case for number 2 when it comes alone in the group

if (_intergerValue == 2000 || _intergerValue == 2000000 || _intergerValue == 2000000000 || _intergerValue == 2000000000000 || _intergerValue == 2000000000000000 || _intergerValue == 2000000000000000000)

retVal = String.Format(“{0}”, arabicAppendedTwos[groupLevel]); // في حالة الاضافة

else

retVal = String.Format(“{0}”, arabicTwos[groupLevel]);// في حالة الافراد

}

For group numbers over 20, it is considered as complicated of 2 digits so each one will get its own converted text.

int ones = tens % 10;

tens = (tens / 10) – 2; // 20’s offset

if (ones > 0)

{

if (retVal != String.Empty)

retVal += ” و “;

// Get Feminine status for this digit

retVal += GetDigitFeminineStatus(ones, groupLevel);

}

if (retVal != String.Empty)

retVal += ” و “;

// Get Tens text

retVal += arabicTens[tens];

Also Arabic language is sensitive to currency names which also depends on the number state so I had to add four different names for the same currency name to support all states, There fields are used at the end of the method when constructing the final String:

if (_intergerValue != 0)

{ // here we add currency name depending on _intergerValue : 1 ,2 , 3—>10 , 11—>99

int remaining100 = (int)(_intergerValue % 100);

if (remaining100 == 0)

formattedNumber += Currency.Arabic1CurrencyName;

else

if (remaining100 == 1)

formattedNumber += Currency.Arabic1CurrencyName;

else

if (remaining100 == 2)

{

if (_intergerValue == 2)

formattedNumber += Currency.Arabic2CurrencyName;

else

formattedNumber += Currency.Arabic1CurrencyName;

}

else

if (remaining100 >= 3 && remaining100 <= 10)

formattedNumber += Currency.Arabic310CurrencyName;

else

if (remaining100 >= 11 && remaining100 <= 99)

formattedNumber += Currency.Arabic1199CurrencyName;

I have created one class to simplify the process, it is called: CurrencyInfo which contains the definition for Currency object, it has the following properties:

CurrencyID = 0;

Just ID

CurrencyCode = “SYP”;

Its Code

IsCurrencyNameFeminine = true;

Is the currency name feminine or no?

EnglishCurrencyName = “Syrian Pound”;

Like: one Syrian Pound

EnglishPluralCurrencyName = “Syrian Pounds”;

Like: thirty four Syrian Pounds

EnglishCurrencyPartName = “Piaster”;

For the decimal part

EnglishPluralCurrencyPartName = “Piasteres”;

For the decimal part

Arabic1CurrencyName = ليرةسورية;

For the number one in Arabic

Arabic2CurrencyName = ليرتانسوريتان;

For the number two in Arabic

Arabic310CurrencyName = ليراتسورية;

For numbers between 3 and 10 in Arabic

Arabic1199CurrencyName = ليرةسورية;

For numbers above 11 in Arabic

Arabic1CurrencyPartName = قرش;

For the decimal part in Arabic

Arabic2CurrencyPartName = قرشان;

For the decimal part in Arabic

Arabic310CurrencyPartName = قروش;

For the decimal part in Arabic

Arabic1199CurrencyPartName = قرشاً;

For the decimal part in Arabic

PartPrecision = 2;

Part precision, like: 1 Syrian Pound = 100 Piasters ( 2 is number of Zeros)

IsCurrencyPartNameFeminine

Is the currency part name feminine or no?

As you can see from the table, it is very easy to setup any other currency by filling the specified fields.

Points of Interest

I hope this was helpful to you.

Please feel free to correct/suggest any modifications to the code.

Advertisements
Posted in Programming | Tagged , | 13 Comments

Introduction

Assalam Alaikom.

This is my first post at my first blog 🙂

I hope that I can share my experience with other people.

Posted in General | Leave a comment