Convert a Number to Text
This class takes a number and converts it to the equivalent text in English.
For example, the input 1 should return the string "one" and 123,456 should return the string "one hundred twenty three thousand four hundred fifty six." (The program does not try to insert the word "and" between any of the numbers.)
The class has one constructor, which takes the integer to convert as a parameter, and has a single methodgetString()that returns the string. This is not necessarily the ideal interface for such a class, but it works for these purposes.
The constructor uses the pow() method from the Math package, which raises a number to a power. It also uses the substring() method of the String class, which when called with one parameter, creates a new String starting at the specified offset in the original string. (The offset is zero-based.)
Source Code
1. class EnglishNumber { 2. 3. private static final String[] ones = { 4. " one", " two", " three", " four", " five", 5. " six", " seven", " eight", " nine", " ten", 6. " eleven", " twelve", " thirteen", " fourteen", 7. " fifteen", " sixteen", " seventeen", 8. " eighteen", " nineteen" 9. }; 10. private static final String[] tens = { 11. " twenty", " thirty", " forty", " fifty", 12. " sixty", " seventy", " eighty", " ninety" 13. }; 14. // 15. // so quintillions is as big as it gets. The 16. // program would automatically handle larger 17. // numbers if this array were extended. 18. // 19. private static final String[] groups = { 20. "", 21. " thousand", 22. " million", 23. " billion", 24. " trillion", 25. " quadrillion", 26. " quintillion" 27. }; 28. 29. private String string = new String(); 30. 31. public String getString() { return string; } 32. 33. public EnglishNumber ( long n ) { 34. 35. // Go through the number one group at a time. 36. 37. for (int i = groups.length-1; i >= 0; i--) { 38. 39. // Is the number as big as this group? 40. 41. long cutoff = 42. (long)Math.pow((double)10, 43. (double)(i*3)); 44. 45. if ( n >= cutoff ) { 46. 47. int thisPart = (int)(n / cutoff); 48. 49. // Use the ones[] array for both the 50. // hundreds and the ones digit. Note 51. // that tens[] starts at "twenty". 52 53. if (thisPart >= 100) { 54. string += 55. ones[thisPart/100] + 56. " hundred"; 57. thisPart = thisPart % 100; 58. } 59. if (thisPart >= 20) { 60. string += tens[(thisPart/10)-1]; 61. thisPart = thisPart % 10; 62. } 63. if (thisPart >= 1) { 64. string += ones[thisPart]; 65. } 66. 67. string += groups[i]; 68. 69. n = n % cutoff; 70. 71. } 72. } 73. 74. if (string.length() == 0) { 75. string = "zero"; 76. } else { 77. // remove initial space 78. string = string.substring(1); 79. } 80. } 81. }
Suggestions
Look at the main for loop, running from lines 3873. What is the goal of one iteration of this loop?
What is the meaning of the variable thisPart?
The functionality is split because the return string is computed in the constructor, but not returned until getString() is called. What variable is returned? Where is it modified?
What is the trivial input for this program? How is it handled in the code?
Hints
Walk through the constructor with the following inputs to the constructor, and determine what value getString() would return:
The trivial case: n == 0.
Test one iteration of the loop, including one case where a digit is 0: n == 102.
Test several iterations of the loop: n == 1234567.
Explanation of the Bug
The code indexes into the ones and tens array incorrectly. Because arrays are zero-based, the number 1 corresponds to ones[0], not ones[1]. Thus, the various accesses need to be adjusted for this. Lines 5557 should change from
string += _ones[thisPart/100] + __" hundred";
to
string += ones[(thisPart/100)-1] + " hundred";
Line 61 should change from
string += tens[(thisPart/10)-1];
to
string += tens[(thisPart/10)-2];
Line 65 should change from
string += ones[thisPart];
to
string += ones[thisPart-1];
This is an A.off-by-one error that becomes a D.index error. It can actually lead to an ArrayIndexOutOfBoundsException being thrown in certain cases. (Can you determine which ones?)