Thread: Numbers to words

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    102

    Numbers to words

    I am trying to write a program that accepts numbers and prints them out word in words. Input: 1234
    Output: one-two-three-four

    Here is my idea of working around it.

    First using a loop and dividing continuously by 10, I work out the number of digits in the number. Then I extract the numbers each one one by one, pass them over to a do while loop that has switch case. Now I have a problem. My program seems to work with some numbers, e.g. 1234 but doesn't work with others because it prints out a false number.

    Test:
    Input: 1234
    Output: one-two-three-four-
    which is correct
    BUT this
    Input: 65767
    Output: six-five-four-six-seven
    is wrong.
    Code:
    #include <iostream>
    #include <cmath>
    using namespace std;
    int main()
    {   double counter =0;
        int x;
        int i = 1; 
        int num; 
        cout<<"Please enter a number"<<endl;
        cin>>num; 
        x = num;             
        
        for (num;num>0; num = num/10)
        {
            counter = counter + i;
            
            }
            
            do{
                    int y =  (x/(int(pow(10,(counter-1)))))%10;//Here is probably where
                //the problem is but I can't figure it out as it looks fine to me.    
                    switch(y){
                              case 0: cout<<"zero-";
                              break;
                              case 1: cout<<"one-";
                              break;
                              case 2: cout<<"two-";
                              break;
                              case 3: cout<<"three-";
                              break;
                              case 4: cout<<"four-";
                              break;
                              case 5: cout<<"five-";
                              break;
                              case 6: cout<<"six-";
                              break;
                              case 7: cout<<"seven-";
                              break;
                              case 8: cout<<"eight-";
                              break;
                              case 9: cout<<"nine-";
                              break;
                              default: cout<<"Not a number!"<<endl;}
                              counter --; }
                    while (counter);
                    return 0;
                              
    }

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Why not just read the number in as a string and then loop through the string checking the digits as characters (e.g. '3' instead of 3)?
    If you understand what you're doing, you're not learning anything.

  3. #3
    Registered User
    Join Date
    Mar 2009
    Posts
    102
    You mean as a character array or?

  4. #4
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    String, character array, whatever.
    If you understand what you're doing, you're not learning anything.

  5. #5
    Registered User
    Join Date
    Mar 2009
    Posts
    102
    OK I understand that and it is probably much easier but the problem is that we are not supposed to use strings or character arrays.

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Can't reproduce the result.

    Instead of calculating powers of ten with floating point (possible rounding error?), you could also just raise 10 to a suitable power first, and then use that value, dividing it by ten.

    Code:
        int power_of_ten = 1;
        for (;num>0; num = num/10)
        {
            power_of_ten *= 10;
    
        }
    
        do{
            power_of_ten /= 10;
            int y = (x / power_of_ten) % 10;
    It also seems that the problem might be nicely solved with recursion. It is easier to extract digits starting with the ones, and recursion can be easily used to reverse the order of actual output.

    As for a switch, you might rather use an array of strings for that.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #7
    Registered User
    Join Date
    Mar 2009
    Posts
    102
    OK thanks for that. It is strange that you can't reproduce the result. I seem to get that. With some numbers, the answer is 100% accurate, with others, no so accurate as one digit is often wrong. It is just strange.

  8. #8
    Registered User
    Join Date
    Mar 2011
    Posts
    546

    questions

    for the same input number, does your program give the same erroneous answer every time or does it vary?

    what compiler?
    Last edited by dmh2000; 03-24-2011 at 03:43 PM.

  9. #9
    Registered User
    Join Date
    Mar 2009
    Posts
    102
    It gives the same erroneous answer every time for a certain number (so it is not random) like the one in the example I gave in the OP. I am using Windows vista (32 bit).

  10. #10
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    is this your exact source code or is this an excerpt?

    i don't get the problem when i run your code and I don't see an immediate error.
    using a double for 'counter' is a little dubious because doubles can be inexact but in this case it should be ok.

    i would do the following:

    print the value of 'num' right after 'cin >> num' to make sure the input is working
    break down the compution of y into steps and print the value at each step to verify it looks right.
    print the value of 'y' just before the switch.

    also you will get a divide by 0 in the computation of y if too many digits are entered but that isn't the problem you are seeing right now.

  11. #11
    Registered User
    Join Date
    Mar 2009
    Posts
    102
    This is the exact source code. I also did the cout suggestion already to confirm. The value of num is consistent and right. However when printing out y, it gives exactly the same consistent erroneous answer so the problem seems to be with the 'y' but I don't understand why there should be a problem at all? I used double because when I used integer in the first place, I got an error because I was using the double function, the error was gone after I used double.

  12. #12
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    try this:

    change 'double counter = 1;' to 'int counter = 1;'

    in the call to 'pow', cast (counter - 1) to double to get rid of the compile error

    int y = (x/(int(pow(10,(double)(counter-1)))))%10;

    I'm just guessing but if when counter is a double it may not be exactly an even integer which would throw off the value computed by 'pow'.

    Quote Originally Posted by dmh2000 View Post
    try this:

    change 'double counter = 1;' to 'int counter = 1;'

    in the call to 'pow', cast (counter - 1) to double to get rid of the compile error

    int y = (x/(int(pow(10,(double)(counter-1)))))%10;

    I'm just guessing but if when counter is a double it may not be exactly an even integer which would throw off the value computed by 'pow'.
    oops i mean 'counter = 0'. not counter = 1; leave that as it was just change counter to an int

    EDIT : even that shouldn't matter it should still come out right.
    Last edited by dmh2000; 03-24-2011 at 04:06 PM.

  13. #13
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Does the problem persist if you replace calls to pow with a user-defined function that works with integers?

    Code:
    int pow10(int n)
    {
       int r = 1;
       while (n > 0) {
          r *= 10;
          --n;
       }
       return r;
    }
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  14. #14
    Registered User
    Join Date
    Mar 2009
    Posts
    102
    Quote Originally Posted by dmh2000 View Post
    try this:

    change 'double counter = 1;' to 'int counter = 1;'

    in the call to 'pow', cast (counter - 1) to double to get rid of the compile error

    int y = (x/(int(pow(10,(double)(counter-1)))))%10;

    I'm just guessing but if when counter is a double it may not be exactly an even integer which would throw off the value computed by 'pow'.



    oops i mean 'counter = 0'. not counter = 1; leave that as it was just change counter to an int

    EDIT : even that shouldn't matter it should still come out right.

    Tested: Problem still persists.

  15. #15
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    Quote Originally Posted by anon View Post
    Does the problem persist if you replace calls to pow with a user-defined function that works with integers?

    Code:
    int pow10(int n)
    {
       int r = 1;
       while (n > 0) {
          r *= 10;
          --n;
       }
       return r;
    }

    this is a good idea. either 'pow' is returning a weird value or something else in that expression is going wrong. besides this again you can do the 'y' calc step by step and look at each intermediate value to figure out at which point it goes wrong.
    Last edited by dmh2000; 03-24-2011 at 04:15 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  2. seg fault at vectornew
    By tytelizgal in forum C Programming
    Replies: 2
    Last Post: 10-25-2008, 01:22 PM
  3. converting numbers to words
    By dionys in forum C Programming
    Replies: 2
    Last Post: 05-08-2004, 09:34 AM
  4. the definition of a mathematical "average" or "mean"
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 12-03-2002, 11:15 AM
  5. A (complex) question on numbers
    By Unregistered in forum C++ Programming
    Replies: 8
    Last Post: 02-03-2002, 06:38 PM