# Number To Word (Arabic Version)

By , 21 Mar 2012

## 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 & also added 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 code written by Justin Rogers from this link as a start: http://weblogs.asp.net/justin_rogers/articles/151757.aspx

This article contains code that does 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)
{
// separate 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 discussed 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. Their 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.

## History

• 27th September, 2010: Initial post
• 9th April, 2011: Fixed a small issue (noted by one member) in the solution attached to the article
• 5th May, 2011: Added VB.NET equivalent code for the article
• 17th February, 2012: Fixed a small bug in the code

 Adel Khayata Software Developer (Senior) Taiba Syrian Arab Republic Member
MCSE,MCSD,MCTS,MCITP
Working as I.T Manager for Taiba Gold & Jewels (http://khayata.org)

Votes of 3 or less require a comment

 Search this forum Profile popups    Spacing RelaxedCompactTight   Noise Very HighHighMediumLowVery Low   Layout Open AllThread ViewNo JavascriptPreview   Per page 102550
 First PrevNext
 number to word m-a-abudrais 22 Mar '13 - 22:10
 Re: number to word Adel Khayata 23 Mar '13 - 6:59
 config rasel202078 16 Nov '12 - 6:43
 I am not sure how it works. i want to know how did i input this all file in my excel. Sign In·View Thread·Permalink
 Re: config Adel Khayata 18 Nov '12 - 4:45
 Number To Word [modified] mustafa salman 5 May '12 - 20:52
 Re: Number To Word Adel Khayata 6 May '12 - 2:57
 Re: Number To Word mustafa salman 7 May '12 - 22:56
 Good Job Adel Aamer Alduais 22 Mar '12 - 4:14
 يعطيك العافية عالمجهود Mazen el Senih 20 Mar '12 - 10:25
 Re: يعطيك العافية عالمجهود Adel Khayata 21 Mar '12 - 0:41
 NumberToArabic code gave a wrong translation for the number 101000 [modified] Member 8736079 19 Mar '12 - 6:02
 Al-salamu Alikum,   Thank you for your code   While translating your code to adobe Actionscript 3.0, I found that your code gave a wrong translation for the number 101000   فقط مائة و ألف جرام لا غير   Not sure if there are other numbers.   Best Regards, Muharrem Drebimodified 19 Mar '12 - 12:16. Sign In·View Thread·Permalink
 Salamu Alaikom, Thank you for the feedback. I am not that expert in Arabic Grammers, but I think the app did a correct translate What should be the result to: 101000 ? Sign In·View Thread·Permalink
 Salamu Alaikum,   The translation of the number 101000 should be   فقط مائة و واحد ألف جرام لا غير   Instead of   فقط مائة و ألف جرام لا غير   There is a big difference.   Best Regards, Muharrem Drebi Sign In·View Thread·Permalink
 Salamu Alaikom,   The Arabic sentence: فقط مائة و ألف جرام لا غير means 100 + 1000 gram and it is equivalent to 1100 so it does not translate to 101,000   So we can say   مائة ألف و ألف   or precisely   مائة و واحد ألف   but we can not say   مائة و ألف   I hope you find my explanation reasonable.   Best Regards, Muharrem Drebi Sign In·View Thread·Permalink
 My vote of 3 Tammam Koujan 21 Feb '12 - 22:43
 My vote is 5 muhamd yusuf 20 Feb '12 - 20:01
 Re: My vote is 5 Adel Khayata 20 Feb '12 - 22:44
 Fix if there is one Number after decimal pionts Smart Arab 17 Feb '12 - 1:23
 Nice Job Man ,   But I had to fix the issue for not getting result if there is only one number after decimal points ,   And here is my modification   ``` if (decimalPart.Length == 1) //Fix for 1 number after decimal ( 10.5 , 1442.2 , 375.4 ) decimalPart += "0"; ```   And is goes to this function ```private string GetDecimalValue(string decimalPart) { string result = String.Empty;   if (Currency.PartPrecision != decimalPart.Length) { if (decimalPart.Length == 1) //Fix for 1 number after decimal ( 10.5 , 1442.2 , 375.4 ) decimalPart += "0"; result = String.Format("{0}.{1}", decimalPart.Substring(0, Currency.PartPrecision), decimalPart.Substring(Currency.PartPrecision, decimalPart.Length - Currency.PartPrecision));   result = (Math.Round(Convert.ToDecimal(result))).ToString(); } else result = decimalPart;   for (int i = 0; i < Currency.PartPrecision - result.Length; i++) { result += "0"; }   return result; } ```   Thank you Sign In·View Thread·Permalink
 Re: Fix if there is one Number after decimal pionts Adel Khayata 17 Feb '12 - 3:32
 Hi. Thank you for the feedback. Actually to make the fix general for all kind of Currencies, I did it this way: ``` int decimalPartLength = decimalPart.Length;   for (int i = 0; i < Currency.PartPrecision - decimalPartLength; i++) { decimalPart += "0"; //Fix for 1 number after decimal ( 10.5 , 1442.2 , 375.4 ) }``` Sign In·View Thread·Permalink
 Wonderful! Abdo W Achkar 7 Feb '12 - 0:52
 Nice job NewPast.Net 6 Jan '12 - 20:05
 Java version Member 7992659 4 Jul '11 - 23:04