Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are items in the wrong cells in this Javascript array?

Somebody wrote this (very terrible) function to translate a numeric value from 0-999 to English words.

function getNumberWords(number) {
  var list = new Array(1000);
  list[000] = "zero";
  list[001] = "one";
  list[002] = "two";
  list[003] = "three";
  ///skip a few
  list[099] = "ninety nine";
  list[100] = "one hundred";
  list[101] = "one hundred and one";
  ///skip a few more
  list[997] = "nine hundred and ninety seven";
  list[998] = "nine hundred and ninety eight";
  list[999] = "nine hundred and ninety nine";
  return list[number];
}

There is some rather odd bug in here that I can't seem to figure out the cause of. Some, but not all of the elements are placed in the wrong cell.

I tried displaying the contentes of the list and it showed a pretty funky result:

> list.toString();
"zero,one,two,three,four,five,six,seven,ten,eleven,twelve,thirteen,fourteen,
fifteen,sixteen,seventeen,twenty,twenty one,twenty two,twenty three,twenty four,
twenty five,twenty six,twenty seven,thirty,thirty one,thirty two,thirty three,
thirty four,thirty five,thirty six,thirty seven,forty,forty one,forty two,"
///(skip a few)
"sixty six,sixty seven,seventy,seventy one,seventy two,seventy three,seventy four,
seventy five,seventy six,seventy seven,,,,,sixty eight,sixty nine,,,,,,,,,
seventy eight,seventy nine,eighty,eighty one,eighty two,eighty three,eighty four,"
///(and so on)

That is, elements 0-7 have the expected value. Elements 68, 69, and 78-999 also have the expected values. Elements 64-67 and 70-77 are empty. Elements 8-63 have incorrect values.

What in the world is going on here? Why are 15 cells empty, 56 cells incorrect, and the rest correct?

like image 963
Peter Olson Avatar asked May 01 '26 09:05

Peter Olson


2 Answers

Numeric literals starting with 0 are interpreted as octal values (if they can be) — that is, numbers in base-8. This is the case in Javascript, C, C++, PHP, Perl, Bash and many other languages.

Now, base-8 22 is base-10 18 so you're not accessing the elements that you think you are. Your first eight array elements were fine because, naturally, base-8 0 is also base-10 0, and so on up to 7. A value like 069 did not cause confusion because it cannot represent anything in base-8, so Javascript falls back to base-10. Yuck!


I suggest using spacing for alignment instead:

function getNumberWords(number) {
  var list = new Array(1000);
  list[  0] = "zero";
  list[  1] = "one";
  list[  2] = "two";
  list[  3] = "three";
  ///skip a few
  list[ 99] = "ninety nine";
  list[100] = "one hundred";
  list[101] = "one hundred and one";
  ///skip a few more
  list[997] = "nine hundred and ninety seven";
  list[998] = "nine hundred and ninety eight";
  list[999] = "nine hundred and ninety nine";
  return list[number];
}

I also suggest making a new function that generates the strings on-the-fly; it shouldn't be taxing and certainly no more so than creating this array on every call.

like image 192
Lightness Races in Orbit Avatar answered May 02 '26 23:05

Lightness Races in Orbit


In Javascript 022 means 22 in octal (18 in decimal).

Octal numeral system on Wikipedia

like image 45
kapa Avatar answered May 02 '26 22:05

kapa



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!