Tech Support > Computers & Technology > Programming > Converting Numbers to Words in English by recursion.
Converting Numbers to Words in English by recursion.
Posted by jedale@gmail.com on March 10th, 2007


I am trying to convert numbers to there corresponding words but it
only works for numbers under 1,000 but need it to work for 1 billion.

Here is the code I have so far:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

/* Prototype */
void print_num(int num);

char *digits[] = {
"zero", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine"};

char *tens[] = {
"ten", "twenty", "thirty", "fourty", "fifty", "sixty",
"seventy", "eighty", "ninety"};

char *places[] = {"hundred", "thousand", "hundred", "million",
"hundred", "billion"};

int main(){

int num = 120394;

print_num(num);
printf("%d ", num); /* Print that number */

}

/* Print out the number sequence */
void print_num(int num){


if(num < 10){
printf("%s ", digits[num]);

}
else if(num < 100){
//print_num(num/10);
printf("%s ", tens[num/10]);
print_num(num%10 +1);
}

else if(num < 1000){
print_num(num/100);
printf("%s ", places[num/1000]);
print_num(num/10);

}else{


print_num(num/10);
print_num(num%10);

}
}

Posted by Phlip on March 10th, 2007


jedale wrote

Where are your unit tests?

I would use C++, and would start like this:

assert("zero" == convert(0));

Then I would write convert like this:

string
convert(int x)
{
return "0";
}

Then I would assert for "one" == convert(1), and change the code to say if(x
== 1) return "one".

That sounds silly, but it isn't. At the time you have 2, you should refactor
the convert function into a little lookup table. Then 3 thru 19 are easy,
because you add them to the table. Then for 20 you add another if statement,
and around 30 you refactor to introduce another table.

Growing the code like that, and refactoring aggressively to remove
duplicated lines, is a great way to grow a clean design.

If you must use C, you can write similar code with character arrays, for a
bit more work.

--
Phlip
http://www.greencheese.us/ZeekLand <-- NOT a blog!!!



Posted by Richard Heathfield on March 10th, 2007


Phlip said:

Well, that's up to you. :-) Not everyone shares your enthusiasm for
that language.

Yes, it does.

Yes, it is.

A lookup table is an inadequate solution here. Why bother to code an
inadequate solution? And you've completely ignored the spec, too.


....or would like to...

Why is it more work?

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.

Posted by Randy Howard on March 10th, 2007


On Sat, 10 Mar 2007 02:07:39 -0600, Richard Heathfield wrote
(in article <dqadnTh4WpCZ-m_YnZ2dnUVZ8vmdnZ2d@bt.com>):

That's because the end-game of any form of zealotry is silliness.

It's okay as long as you have unit tests, apparently.

--
Randy Howard (2reply remove FOOBAR)
"The power of accurate observation is called cynicism by those
who have not got it." - George Bernard Shaw






Posted by Steve O'Hara-Smith on March 10th, 2007


On 9 Mar 2007 20:03:09 -0800
jedale@gmail.com wrote:

It doesn't even work for numbers between 10 and 20 - you need to
special case those - and the handling above 1000 is completely off. Try
the code below (and if you switch to unsigned long long instead of int and
extend the places and place_sizes lists and the loop you can go much higher)

With regard to testing which has occupied most of this thread I
suggest a middle ground of making a test script that excercises the program
testing for expected results on spot checks in the range 0-9, 10-20, 20-100,
100-1000, 1000-100000, and so forth. I didn't bother with a script I jyst
hand spot checked the results - but then I don't intend to keep this code.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

/* Prototype */
void print_num(int num);

char *smallnum[] = {
"zero", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten", "eleven", "twelve",
"thirteen", "fourteen", "fifteen", "sizteen", "seventeen",
"eighteen", "nineteen"
};

char *tens[] = {
"twenty", "thirty", "fourty", "fifty", "sixty",
"seventy", "eighty", "ninety"};

char *places[] = {"thousand", "million", "billion"};
int place_sizes[] = {1000, 1000000, 1000000000};

int main(int arcg, char **argv)
{
int num = atoi(argv[1]);

printf("%d\n", num); /* Print that number */
print_num(num);
}

/* Print out the number sequence */
void print_num(int num)
{
int i;
if (num < 20)
{
printf("%s ", smallnum[num]);
}
else if (num < 100)
{
printf("%s ", tens[num/10 - 2]);
if (num % 10)
print_num(num%10);
}
else if(num < 1000)
{
print_num(num/100);
printf("hundred ");
if (num % 100)
print_num(num%100);
}
else
{
for (i = 2; i >= 0; i--)
{
if (num / place_sizes[i])
{
print_num(num / place_sizes[i]);
printf ("%s ", places[i]);
num = num % place_sizes[i];
}
}
if (num)
print_num(num);
}
}


--
C:>WIN | Directable Mirror Arrays
The computer obeys and wins. | A better way to focus the sun
You lose and Bill collects. | licences available see
| http://www.sohara.org/

Posted by rossum on March 10th, 2007


On 9 Mar 2007 20:03:09 -0800, jedale@gmail.com wrote:

program needs to take account of that. What you have handles most
three digit combinations (000 to 999) in most situations. You need to
work on where to put the other words that describe the three digit
combinations, and to handle the exceptions to the standard wording of
some three digit groups.

123,000 = "one hundred and twenty three thousand" (drop the "and" if
you are American). That is 123 -> "one hundred and twenty three" plus
some extra verbiage for the 000 at the end. Now think about
123,000,000 and 123,000,000,000.

Extend to 123,456,000, 123,456,908 and 123,456,908,436.

Look for patterns and think about how to program them.

rossum



Similar Posts