Thread: Writing numbers in letters is there a easier way ?

  1. #1
    Registered User
    Join Date
    Jan 2013
    Posts
    25

    Writing numbers in letters is there a easier way ?

    Code:
    #include<stdio.h>
    #include<string.h>
    #define a 9
    #define b 9
    #define c 3
    int main()
    {
    char *num[]={"","one","two","three","four","five","six","seven","eight","nine"};
    char *num10[]={"","ten","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"};
    char *num100[]={"","hundred","thousand","million"};
    longint n;
    printf("type a number to see its spelling:");
    	scanf("%li",&n);
    	
    	if (n>=0&&n<10) {
    	printf("%s",num[n]);
    	}
    	else if (n>=10&&n<100){
    		if (n%10==0) 
    			printf("%s",num10[(n/10)]);
    		else if(n%10!=0)
    			printf("%s%s",num10[(n/10)],num[n%10]);
    	}
    	else if (n>=100&&n<1000){
    		if (n%100==0) 
    			printf("%s%s",num[n/100],num100[1]);
    		else if (n%100!=0)
    			printf("%s%s%s%s",num[n/100],num100[1],num10[((n%100)/10)],num[(n%100)%10]);
    	}
    	else if (n>=1000&&n<10000){
    		if (n%1000==0) 
    			printf("%s%s",num[n/1000],num100[2]);
    		else if (n!=0&&(n%1000)>99)
    			printf("%s%s%s%s%s%s",num[n/1000],num100[2],num[(n%1000)/100],num100[1],num10[(((n%1000)%100)/10)],num[((n%1000)%100)%10]);
    		else if (n!=0&&(n%1000)<99)
    			printf("%s%s%s%s%s",num[n/1000],num100[2],num[(n%1000)/100],num10[(((n%1000)%100)/10)],num[((n%1000)%100)%10]);
    	}
    }
    In practice section there was a challenge to print up numbers in letters up to billion including negatives I didn't look at the solution and came up with this but it is getting difficult after this point and when I checked the solution I didn't understand so I thought maybe someone give me an idea

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Start with the biggest group (e.g. thousands) and work your way down. Use a chain of plain if statements, not if-else if. if-else if is for mutually exclusive conditions. This is not such a case. Having a number over 1000 (so you must print a thousands part) does not mean you do not have to print out the hundreds part. Think through how you do this yourself (e.g. if you're writing out a check -- if anybody still uses those things) it in plain English. Those steps will be the basis for your algorithm. Something like:
    Code:
    if the number is in the thousands
        print out the thousands part
        get rid of the thousands part  // now you're left with something less than 1000
    if the remaining number is in the hundreds
       ...
    Hopefully you see a pattern here.

    Now, if you think about it, you are doing roughly the same process for hundreds, tens and ones, just with slightly different words. Thus, putting the right elements in an array, and turning this into a loop, might help make the code "easier".

    For the extra challenge of numbers in the billions, note that once you can print the thousands, you can easily extend it to the millions, billions, trillions, etc. Each period (grouping separated by commas -- we use commas in the US, some places it's a . or something else), is just the same thing, with a different suffix:

    219,876,543,210
    two hundred nineteen billion,
    eight hundred seventy-six million,
    five hundred forty-three thousand,
    two hundred ten (no suffix)

    Notice that each grouping is basically just those three digits, printed as you would any three digit number, followed by the period name (thousand, million, billion).

    Hope that gives you some ideas.

  3. #3
    Ultraviolence Connoisseur
    Join Date
    Mar 2004
    Posts
    555
    Check this out:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    static const char * ones[] = {
        "", "one", "two", "three", "four",
        "five", "six", "seven", "eight", "nine",
        "ten", "eleven", "twelve", "thirteen",
        "fourteen", "fifteen", "sixteen", "seventeen",
        "eighteen", "nineteen"
    };
    static const char * tens[] = {
        "", "", "twenty", "thirty", "fourty",
        "fifty", "sixty", "seventy", "eighty", "ninety"
    };
    static const struct order {
        const char * s;
        const long v;
    } order[] = {
        {"billion",  1000000000},
        {"million",  1000000},
        {"thousand", 1000},
        {"hundred",  100}
    };
    
    #define HANDLE_REMAINDER(n) do {                                 \
                if ((n) > 19) {                                      \
                    printf((n)%10 ? "%s-" : "%s ", tens[(n)/10]);    \
                    (n)%=10;                                         \
                }                                                    \
                if ((n)>0) printf("%s ", ones[(n)]);                 \
    } while(0)
    
    void ordinal(long num)
    {
        unsigned int co;
    
        for (co = 0; co < sizeof order / sizeof order[0] && num > 0; ++co) {
            long n;
    
            if ((n = num/order[co].v) > 0) {
                if (n > 100) {
                    printf(n%100 ? "%s %s and " : "%s %s ", ones[n/100], "hundred") ;
                    n%=100;
                }
                HANDLE_REMAINDER(n);
                printf("%s ", order[co].s);
            }
    
            num %= order[co].v;
        }
    
        HANDLE_REMAINDER(num);
        printf("\n");
    }
    
    int main(void)
    {
        ordinal(411112302301);
        ordinal(102);
        ordinal(40239);
        ordinal(21003941);
        ordinal(20);
        ordinal(19);
        return 0;
    }
    $  ./a.out 
    four hundred and eleven billion one hundred and twelve million three hundred and two thousand three hundred one 
    one hundred two 
    fourty thousand two hundred thirty-nine 
    twenty-one million three thousand nine hundred fourty-one 
    twenty 
    nineteen
    Probably some bugs in it as well as the fact that is just prints to stdout (writing a function that instead takes a string and size to write to would be a good exercise) as well as fixing whatever bugs probably exist in this code...

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Poor old "zero" is feeling so neglected by those attempts!
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    @nonpuz:
    For the sake of correctness, I thought I should mention that those are not ordinal numbers, they are cardinal numbers. Ordinal is used for ordering things, first, second, etc. Cardinal numbers are used to describe cardinality, or size. Think of the numbers you use to count items: three, four, etc. I am aware of no term that describes whether the numbers are written out as words or using words, so 1st and first are both ordinal, 1 and one are both cardinal.

  6. #6
    Ultraviolence Connoisseur
    Join Date
    Mar 2004
    Posts
    555
    Good to know. I was just copying the naming convention used by similar functions in various scripting languages. I guess a better name then would be something like "num2text" or something

  7. #7
    Registered User
    Join Date
    Jan 2013
    Posts
    25
    Code:
    #include<stdio.h>
    #include<string.h>
    #define d 9
    #define e 9
    #define f 4
    int main()
    {
    char *num[]={"","one","two","three","four","five","six","seven","eight","nine"};
    char *num10[]={"","ten","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"};
    char *num11[]={"","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"};
    char *num100[]={"","hundred","thousand","million","billion"};
    longlongint n,n1;
    longlongint te=10,hu=100,th=1000,huth=100000,mi=1000000,humi=100000000,bi=1000000000,tr=1000000000000;
    	
    printf("type a number smaller than a trillion to see it in letters:");
    	scanf("%lli",&n);		
    	
    	if (n>=bi&&n<tr) {
    		n1=n/humi;
    		if (n1>=hu&&n1<th){
    			if (n1%100==0) 
    				printf("%s%s",num[n1/100],num100[1]);
    			if (n1%100!=0)
    				printf("%s%s",num[n1/100],num100[1]);
    			n1=n1%100;
    		}
    		if (n1>=te&&n1<hu){
    			if (n1%10==0) 
    				printf("%s",num10[(n1/10)]);
    			if(n1%10!=0&&n1>=20)
    				printf("%s%s",num10[(n1/10)],num[n1%10]);
    			if (n1>10&&n1<20) {
    				printf("%s",num11[n1%10]);
    			}
    		}
    		if (n1>=0&&n1<te){
    			printf("%s\n",num[n1]);
    		}
    		printf("%s ",num100[4]);
    		n=n%humi;
    	}
    	 if (n>=mi&&n<bi) {
    		n1=n/huth;
    		if (n1>=hu&&n1<th){
    			if (n1%100==0) 
    				printf("%s%s",num[n1/100],num100[1]);
    			if (n1%100!=0)
    				printf("%s%s",num[n1/100],num100[1]);
    			n1=n1%100;
    		}
    		if (n1>=te&&n1<hu){
    			if (n1%10==0) 
    				printf("%s",num10[(n1/10)]);
    			if(n1%10!=0&&n1>=20)
    				printf("%s%s",num10[(n1/10)],num[n1%10]);
    			if (n1>10&&n1<20) {
    				printf("%s",num11[n1%10]);
    			}
    		}
    		if (n1>=0&&n1<10){
    			printf("%s\n",num[n1]);
    		}
    		printf("%s ",num100[3]);
    		n=n%huth;
    	}
    	 if (n>=th&&n<huth) {
    		n1=n/1000;
    		if (n1>=100&&n1<1000){
    				if (n1%100==0) 
    					printf("%s%s",num[n1/100],num100[1]);
    				if (n1%100!=0)
    					printf("%s%s",num[n1/100],num100[1]);
    				n1=n1%100;
    			}
    		if (n1>=10&&n1<100){
    			if (n1%10==0) 
    				printf("%s",num10[(n1/10)]);
    			if(n1%10!=0&&n1>=20)
    				printf("%s%s",num10[(n1/10)],num[n1%10]);
    			if (n1>10&&n1<20) {
    				printf("%s",num11[n1%10]);
    			}
    		}
    		if (n1>=0&&n1<10){
    			printf("%s\n",num[n1]);
    		}
    		printf("%s ",num100[2]);
    		n=n%1000;
    	}
    	 if (n>=hu&&n<th){
    			if (n%100==0) 
    				printf("%s%s",num[n/100],num100[1]);
    			if (n%100!=0)
    				printf("%s%s",num[n/100],num100[1]);
    			n=n%100;
    		}
    	 if (n>=te&&n<hu){
    			if (n%10==0) 
    				printf("%s",num10[(n/10)]);
    			if(n%10!=0&&n>=20)
    				printf("%s%s",num10[(n/10)],num[n%10]);
    			if (n>10&&n<20) {
    				printf("%s",num11[n%10]);
    			}
    		}
    	 if (n>=0&&n<te){
    			printf("%s\n",num[n]);
    		}
    	 if (n==0) {
    printf("zero");
    	}
    return0;
    }
    Here is what I did after reading anduril467's suggesstion. This might look too long but only copy several copy paste thanks everybody.

  8. #8
    Registered User
    Join Date
    Jan 2013
    Posts
    25
    Quote Originally Posted by anduril462 View Post
    For the extra challenge of numbers in the billions, note that once you can print the thousands, you can easily extend it to the millions, billions, trillions, etc. Each period (grouping separated by commas -- we use commas in the US, some places it's a . or something else), is just the same thing, with a different suffix:

    219,876,543,210
    two hundred nineteen billion,
    eight hundred seventy-six million,
    five hundred forty-three thousand,
    two hundred ten (no suffix)

    Notice that each grouping is basically just those three digits, printed as you would any three digit number, followed by the period name (thousand, million, billion).

    Hope that gives you some ideas.
    Thanks for lightening my mind after reading your comment it made perfect sense. for extra challenge, I put blanks after every 3 digit

  9. #9
    Registered User
    Join Date
    Jan 2013
    Posts
    25
    Quote Originally Posted by iMalc View Post
    Poor old "zero" is feeling so neglected by those attempts!
    zero is not neglected anymore
    Code:
     if (n==0) {
    printf("zero");
    	}

  10. #10
    Registered User
    Join Date
    Jan 2013
    Posts
    25
    Quote Originally Posted by nonpuz View Post
    Check this out:
    Code:
    ....
    Probably some bugs in it as well as the fact that is just prints to stdout (writing a function that instead takes a string and size to write to would be a good exercise) as well as fixing whatever bugs probably exist in this code...
    I was working on my own approach. now I will check yours and learn and hopefully fix bugs and convert characters to numbers as well
    thank you!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Numbers to Letters
    By flip114 in forum C Programming
    Replies: 5
    Last Post: 09-24-2003, 03:18 AM
  2. Letters-numbers
    By wuzzuppy_123 in forum C++ Programming
    Replies: 4
    Last Post: 05-09-2003, 02:51 PM
  3. scanning for numbers - not letters
    By volk in forum C++ Programming
    Replies: 7
    Last Post: 04-07-2003, 03:44 PM
  4. Transforming letters to numbers...
    By N8760 in forum C++ Programming
    Replies: 2
    Last Post: 12-23-2001, 03:26 PM
  5. How do you allocate numbers to letters?
    By face_master in forum C++ Programming
    Replies: 9
    Last Post: 11-14-2001, 06:47 AM