Page 2 of 2 FirstFirst 12
Results 11 to 18 of 18

Thread: Numbers to Word

  1. #11
    Join Date
    Sep 2004
    Posts
    1,905
    Rep Power
    21

    Default

    @icymint3
    Thanks for showing me how it is done! Your code is cool.

    I am looking forward to your challenge

    My code still is not a short as yours. And it is still incomplete for writing the number 1001 = One Thousand and One, but I commented what needs to be done at the TODO label


    @everyone
    This was a good problem to practice on.

    When I was doing the optimising, at first, I did not know what to do. Then I thought about how a person writes a number on paper (like the procedure and logic used, eg "Find the biggest quantity first, like Million, then see how many Millions are there, etc". From there I was all right.

    <Analysis target_audience="noobies to gurus"
    1. Mimic the proceedure that an individual would do. (I used get the 3 digit amount of billions, then millions, then thousands, basically. I also used some logic for the foramt presentation with ',' and 'and')
    2. Name variables that will be needed based on the proceedure
    3. Follow the proceedure and make comments for sections that represent a step in the proceedure.(I lacked comments in my code about this approach mention in 1.)
    </Analysis>

    Code:
    /*
    NumbersToWord.cpp
    Copyright © 2005 JaGameDevelopers®
    by crosswire
    */
    
    
    
    
    
    /*
    Desired presentation format
    
          0		=	Zero
          1		=	One
         10		=	Ten
         11		=	Eleven
        100		=	One Hundred
        101		=	One Hundred and One
        110		=	One Hundred and Ten
        111		=	One Hundred and Eleven
       1000		=	One Thousand
       1001		=	One Thousand, and One
       1010		=	One Thousand, and Ten
       1011		=	One Thousand, and Eleven
       1100		=	One Thousand, and One Hundred*
       1101		=	One Thousand, One Hundred and One
       1110		=	One Thousand, One Hundred and Ten
       1111		=	One Thousand, One Hundred and Eleven
      10000		=	Ten Thousand
      10001		=	Ten Thousand, and One
      10010		=	Ten Thousand, and Ten
      10011		=	Ten Thousand, and Eleven
      10100		=	Ten Thousand, and One Hundred
      10101		=	Ten Thousand, One Hundred and One
      10110		=	Ten Thousand, One Hundred and Ten
      10111		=	Ten Thousand, One Hundred and Eleven
      11000		=	Eleven Thousand
    
    *If desired Eleven Hundred could be written using special logic could be used for this range.
    
    Same pattern is desired for higher numbers
    
      101011	=	One Hundred and One Thousand, and Eleven
      101101	=	One Hundred and One Thousand, One Hundred and One
      ...
      101000001	=	One Hundred and One Million, and One
      101000010	=	One Hundred and One Million, and Ten
      101000011	=	One Hundred and One Million, and Eleven
      101000101	=	One Hundred and One Million, One Hundred and One
      101000110	=	One Hundred and One Million, One Hundred and One
      ...
      101101101	=	One Hundred and One Million, One Hundred and One Thousand, One Hundred and One
      ...
      111111111	=	One Hundred and Eleven Million, One Hundred and Eleven Thousand, One Hundred and Eleven
    
      Therefore 1,100,100 would be written One Million, One Hundred Thousand, and One Hundred
    
    */
    
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    #include <math.h>
    
    
    
    #define		THOUSANDS_LIMIT		4
    //A limit of 4 represents the Billionth quantity max
    
    namespace utility
    {
    	//Get the word for numbers 0-19
    	char words_one_to_nineteen[20][64]	=	{
    		"",
    		"One",
    		"Two",
    		"Three",
    		"Four",
    		"Five",
    		"Six",
    		"Seven",
    		"Eight",
    		"Nine",
    		"Ten",
    		"Eleven",
    		"Twelve",
    		"Thirteen",
    		"Fourteen",
    		"Fifteen",
    		"Sixteen",
    		"Seventeen",
    		"Eighteen",
    		"Nineteen"
    	};
    
    	//Get the word for 20, 30, 40, ... 90
    	char words_twenty_to_ninety[10][64]	=	{
    		"",
    		"",
    		"Twenty",
    		"Thirty",
    		"Forty",
    		"Fifty",
    		"Sixty",
    		"Seventy",
    		"Eighty",
    		"Ninety"
    	};
    
    	char word_hundred[64]	=	"Hundred";
    
    	//Get the word for 100, 1000, 1000000
    	char words_thousand_million_billion[THOUSANDS_LIMIT][64]	=	{
    		"",
    		"Thousand",
    		"Million",
    		"Billion"
    	};
    
    	//Get a digit from Number given the index of the digit. Eg, return 2 when Number = 12345 and DigitIndex = 3
    	int GetDigitFromNumber(int Number, int DigitIndex)
    	{
    		return	(Number%(int)pow(10,DigitIndex+1))/(int)pow(10,DigitIndex);
    	}
    
    	//Get the word for 1, 10, 11, 100, 101, 110, 111, but the Number must be less than 1000
    	char * NumberToWordLessThanThousand(int Number, char * Word)
    	{
    		strcpy(Word, "");
    		int HundredDigit	=	utility::GetDigitFromNumber(Number, 2);
    		if(HundredDigit)														//If there is a hundreds digit
    		{
    			strcat(Word, utility::words_one_to_nineteen[HundredDigit]);			//Write One, Two, Three, ... or Nine
    			strcat(Word, " ");
    			strcat(Word, utility::word_hundred);								//Write Hundred
    			//if(HundredDigit > 1)
    			//	strcat(Word, "s");												//Write s
    		}
    
    		int	TensAndOnesDigits	=	Number % 100;
    		if(TensAndOnesDigits)
    		{
    			if(HundredDigit)
    				strcat(Word, " and ");
                if(TensAndOnesDigits < 20)
    				strcat(Word, utility::words_one_to_nineteen[TensAndOnesDigits]);//Write One, Two, Three, ... or Nineteen
    			else
    			{
    				strcat(Word, utility::words_twenty_to_ninety[TensAndOnesDigits/10]);//Write Twenty, Thirty, ...
    				if(TensAndOnesDigits%10)											//If the last digit is not zero
    					strcat(Word, "-");												//Write a dash
    				strcat(Word, utility::words_one_to_nineteen[TensAndOnesDigits%10]);	//Write One, Two, Three... This is the last digit
    			}
    		}
    		return	Word;
    	}
    
    
    	//Get the word for a Number, eg 101230019 
    	char * NumberToWord(int Number, char * Word)
    	{
    
    		int		NThousandQuantites		=	0;									//The number of times Billion, Million, or Thousand need to be written. A Thousand quantity is like Thousand, Million, Billion.
    		int		ThousandQuantitesAmount[THOUSANDS_LIMIT];						//The amount of Billions associated with the Billionth word, eg Ten in Ten Billion. Literally, ThousandQuantitesAmount is the amount of Billions.
    		int		ThousandQuantitesIndex[THOUSANDS_LIMIT];						//The index to make a Billionth, Millionth, or Thousand quantity, eg the indices 0,1,2 mark Thousand, Million, Billion respectively.
    
    		for(int i = 0; i < THOUSANDS_LIMIT; i++)								//Check the amount of Thousands, then Millions, then Billions, ...
    		{
    			int	Quantity	=	(Number%(__int64)pow(1000,i+1))/(__int64)pow(1000,i);	//Get the number of Billions, Millions, or Thousands. Here __int64 is used to count Billions.
    																				//Eg for Number = 123,456,789
    																				//when i = 1, then Quantity = 456
    																				//when i = 2, then Quantity = 123
    			if(Quantity > 0)
    			{
    				ThousandQuantitesAmount[NThousandQuantites]	=	Quantity;
    				ThousandQuantitesIndex[NThousandQuantites]	=	i;				//i represents the index of which Thousand quantity is being stored
    				NThousandQuantites++;
    			}
    		}
    
    		bool	ThousandQuantityWasWritten	=	false;
    		strcpy(Word, "");
    		for(i = NThousandQuantites - 1; i >= 0; i--)							//Write all the Thousand Quantity Amounts then the Thousand Quantity starting from the largest Thousand Quantity
    		{
    			if(ThousandQuantityWasWritten)										//If something was written before
    			{
    				strcat(Word, ", ");
    				//if(i == 0)														//TODO : And if this is the last quantity to be written which itself does not have an 'and' in it
    				//	strcat(Word, "and ");
    			}
    
    			char	buffer[1024];
    			strcat(Word, utility::NumberToWordLessThanThousand(ThousandQuantitesAmount[i], buffer));	//Write something like One Hundred and Twenty One
    			strcat(Word, " ");
    			strcat(Word, utility::words_thousand_million_billion[ThousandQuantitesIndex[i]]);			//Write something like Million
    			ThousandQuantityWasWritten	=	true;
    		}
    		return	Word;
    	}
    }
    
    
    
    int main(int argc, char* argv[])
    {
    
    	char * test = utility::words_one_to_nineteen[0];
    
    	while(true)
    	{
    		printf("Please enter your number (without commas and not greater than 2,147,483,647)\n:");
    
    		int		Number;
    		scanf("%d", &Number);
    
    		if(Number == 0)
    			return	0;
    
    		if(Number > 2147483647)
    		{
    			printf("No conversion made on '%d'\n", Number);
    			printf("Reason : the number it too big\n");
    		}
    		else
    		{
    			char	Word[128];
    			utility::NumberToWord(Number, Word);
    
    			printf("\n'%d' = %s\n\n", Number, Word);
    		}
    	}
    	return 0;
    
    }
    Let's act on what we agree on now, and argue later on what we don't.
    Black men leave Barbeque alone if Barbeque don't trouble you

  2. #12
    Join Date
    Sep 2004
    Posts
    1,905
    Rep Power
    21

    Default

    I looked on icymint3 code and wonder how the handle9Digits function was so short so I check why mine NumberToWord and I found I had unused logic so I remove the logic NThousandQuantites, but however, the remainding code is still too long.

    Code:
    /*
    NumbersToWord.cpp
    Copyright © 2005 JaGameDevelopers®
    by crosswire
    */
    
    
    
    #include <string.h>
    #include <stdio.h>
    #include <math.h>
    
    
    
    #define		THOUSANDS_LIMIT		4
    //A limit of 4 represents the Billionth quantity max
    
    namespace utility
    {
    	//Get the word for numbers 0-19
    	char words_one_to_nineteen[20][64]	=	{
    		"",
    		"One",
    		"Two",
    		"Three",
    		"Four",
    		"Five",
    		"Six",
    		"Seven",
    		"Eight",
    		"Nine",
    		"Ten",
    		"Eleven",
    		"Twelve",
    		"Thirteen",
    		"Fourteen",
    		"Fifteen",
    		"Sixteen",
    		"Seventeen",
    		"Eighteen",
    		"Nineteen"
    	};
    
    	//Get the word for 20, 30, 40, ... 90
    	char words_twenty_to_ninety[10][64]	=	{
    		"",
    		"",
    		"Twenty",
    		"Thirty",
    		"Forty",
    		"Fifty",
    		"Sixty",
    		"Seventy",
    		"Eighty",
    		"Ninety"
    	};
    
    	char word_hundred[64]	=	"Hundred";
    
    	//Get the word for 100, 1000, 1000000
    	char words_thousand_million_billion[THOUSANDS_LIMIT][64]	=	{
    		"",
    		"Thousand",
    		"Million",
    		"Billion"
    	};
    
    
    	//Get a digit from Number given the index of the digit. Eg, return 2 when Number = 12345 and DigitIndex = 3
    	int GetDigitFromNumber(int Number, int DigitIndex)
    	{
    		return	(Number%(int)pow(10,DigitIndex+1))/(int)pow(10,DigitIndex);
    	}
    
    
    	//Get the word for 1, 10, 11, 100, 101, 110, 111, but the Number must be less than 1000
    	char * NumberToWordLessThanThousand(int Number, char * Word)
    	{
    		strcpy(Word, "");
    		int HundredDigit	=	utility::GetDigitFromNumber(Number, 2);
    		if(HundredDigit)														//If there is a hundreds digit
    		{
    			strcat(Word, utility::words_one_to_nineteen[HundredDigit]);			//Write One, Two, Three, ... or Nine
    			strcat(Word, " ");
    			strcat(Word, utility::word_hundred);								//Write Hundred
    		}
    
    		int	TensAndOnesDigits	=	Number % 100;
    		if(TensAndOnesDigits)
    		{
    			if(HundredDigit)
    				strcat(Word, " and ");
                if(TensAndOnesDigits < 20)
    				strcat(Word, utility::words_one_to_nineteen[TensAndOnesDigits]);//Write One, Two, Three, ... or Nineteen
    			else
    			{
    				strcat(Word, utility::words_twenty_to_ninety[TensAndOnesDigits/10]);//Write Twenty, Thirty, ...
    				if(TensAndOnesDigits%10)											//If the last digit is not zero
    					strcat(Word, "-");												//Write a dash
    				strcat(Word, utility::words_one_to_nineteen[TensAndOnesDigits%10]);	//Write One, Two, Three... This is the last digit
    			}
    		}
    		return	Word;
    	}
    
    
    	//Get the word for a Number, eg 101230019 
    	char * NumberToWord(int Number, char * Word)
    	{
    		bool	ThousandQuantityWasWritten	=	false;
    		strcpy(Word, "");
    
    		for(int i = THOUSANDS_LIMIT; i >= 0; i--)								//Check the amount of Thousands, then Millions, then Billions, ... .Starting form the largest quantity, do the writing
    		{
    			int	Quantity	=	(Number%(__int64)pow(1000,i+1))/(__int64)pow(1000,i);	//Get the number of Billions, Millions, or Thousands. Here __int64 is used to count Billions.
    																				//Eg for Number = 123,456,789
    																				//when i = 1, then Quantity = 456
    																				//when i = 2, then Quantity = 123
    			if(Quantity > 0)
    			{
    				if(ThousandQuantityWasWritten)									//If something was written before
    				{
    					strcat(Word, ", ");
    					//if(i == 0)												//TODO : And if this is the last quantity to be written which itself does not have an 'and' in it
    					//	strcat(Word, "and ");
    				}
    				char	buffer[1024];
    				strcat(Word, utility::NumberToWordLessThanThousand(Quantity, buffer));	//Write something like One Hundred and Twenty One
    				strcat(Word, " ");
    				strcat(Word, utility::words_thousand_million_billion[i]);		//Write something like Million
    				ThousandQuantityWasWritten	=	true;
    			}
    		}
    		return	Word;
    	}
    }
    
    
    
    int main(int argc, char* argv[])
    {
    
    	char * test = utility::words_one_to_nineteen[0];
    
    	while(true)
    	{
    		printf("Please enter your number (without commas and not greater than 2,147,483,647)\n:");
    
    		int		Number;
    		scanf("%d", &Number);
    
    		if(Number == 0)
    			return	0;
    
    		if(Number > 2147483647)
    		{
    			printf("No conversion made on '%d'\n", Number);
    			printf("Reason : the number it too big\n");
    		}
    		else
    		{
    			char	Word[128];
    			utility::NumberToWord(Number, Word);
    
    			printf("\n'%d' = %s\n\n", Number, Word);
    		}
    	}
    	return 0;
    
    }
    Let's act on what we agree on now, and argue later on what we don't.
    Black men leave Barbeque alone if Barbeque don't trouble you

  3. #13
    Join Date
    Sep 2004
    Posts
    1,905
    Rep Power
    21

    Default

    PS : Until the last optimization mentioned, I had not plagurize any part of icymint3's code (I wanted to truly test myself). Thus I learnt how to use only necessary logic by doing that optimization. And since this is a learning problem, I am OK with that piracy.
    Let's act on what we agree on now, and argue later on what we don't.
    Black men leave Barbeque alone if Barbeque don't trouble you

  4. #14
    Join Date
    Dec 2002
    Posts
    500
    Rep Power
    0

    Default

    I see you tried to out-do my efforts by moving into the billions.
    I'll have you know that i can add just two lines of code to do that.
    Exactly two.

  5. #15
    Join Date
    Sep 2004
    Posts
    1,905
    Rep Power
    21

    Default

    I know. It wasnt an attempt. Mi done give you ratings for, and from, the other program in the other thread.

    I could set mine to a limit of unsigned 64 bit integer, without additional lines, but it would not be practical.

    Still, I did not want to sound petty, but mine has less formating bugs than yours, 1 that I know of while yours has 2. To correct mine would take 4-5 lines but yours would take only 2 lines So mi no bother mention them

    Looking back at your code, I see that you used the power of the printf which can cancatenate many strings in one line where I used strcat. I was aiming at easy portabilty but I could have used the power of sprintf.
    Also I see the logic hasHundred, at first I thought it was the right logic to use and I was going to ask your premission to use it in mine, but it does not cover the case for 1000100 which I just checked out. If you used that logic to do the inclusion of 'and' in cases like 1001=One thousand and one, it does not keep for 1000100, because instead of "and 1", there is "and 100". A better logic may be that the last printed quanty, whether 100 or 1, does not itself has 'and' included.

    Yours is very optimal but mine cut less corners. I know that you could easily fix it if you had the time and your code would still kick mine's butt anyday. Maybe a few lines on yours though.

    (Waiting on the storm)So what are the specific critiques of my code?
    Let's act on what we agree on now, and argue later on what we don't.
    Black men leave Barbeque alone if Barbeque don't trouble you

  6. #16
    Join Date
    Dec 2002
    Posts
    500
    Rep Power
    0

    Default

    well structured.
    solid.
    extendable.
    correctable.

    the namespace thingy makes it reusable without the globals clashing etc.eusa_hand

  7. #17
    Join Date
    Dec 2002
    Posts
    500
    Rep Power
    0

    Default

    hey i was working on one version that would translate as you entered the numbers.
    it aint done yet, since they can backspace the last zero and it would crash.
    soon correct that part. i wont worry about the rest.

  8. #18
    Join Date
    Jul 2005
    Posts
    75
    Rep Power
    0

    Default Crosswire A Question

    Do you really copyright your code?
    "A computer once beat me at chess, but it was no match for me at kick boxing." - Emo Philips -

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •