- 2/14/2017 – Fixed numeric typo (thanks, Geroge P!).
HEX versus DECimal Numbers
As Barbie once said*…
Math is hard! – Barbie
While Mattel’s Math-Is-Hard Barbie never quite made the splash the marketing team had hoped for, her sentiment lives on.
Side Note: *This is in reference to a the Teen Talk Barbie doll released in 1992, and out of the 270 phrases the doll could say, that was not one of them. The real quote was “Math class is tough!”
Earlier in this series, I touched on the fact that dealing with numbers is time consuming for BASIC. Something as simple as B=65535 takes time to process as the interpreter translates that base-10 decimal number in to an internal floating point value. The more digits, the more work. For instance:
0 REM NUMBERS.BAS 10 TIMER=0:TM=TIMER 20 FOR A=1 TO 1000 30 B=1 40 NEXT 50 PRINT TIMER-TM
That prints a value of 183. If you change line 3 to read “B=12345” the number jumps to 485. You can see the increase:
- B=1 – 183
- B=12 – 262
- B=123 – 337
- B=1234 – 408
- B=12345 = 485
Obviously, the more numbers to parse and convert, the more time it will take. It also seems to matter if the value has a decimal point in it:
- B=1.0 – 403
- B=1.1 – 476
Even though that is only three characters to process, it takes longer than B=123. Clearly, more work is being done on floating point values. Even though all Color BASIC numbers are represented internally as floating point, it still makes sense to avoid using them unless you really need them.
You can also represent a base-16 number in hexadecimal. For the value of 1, it feels like parsing “&H1” should take longer than parsing “1”. Let’s try:
- B=&H1 – 180
- B=&H12 – 175
- B=&H123 – 200
- B=&H1234 – 203
It seems that parsing a hexadecimal value is much faster than dealing with base-10 values. Using this, you could speed up a program just by switching to hex, provided that your numbers are between 0 and 65535 (the values that can be represented in hex). I was surprised to see that negative values also work:
- B=&HFFFF – 201
- B=-&HFFFF – 230
It seems dealing with the negative takes a bit of more time, though, so it makes sense to avoid using them unless you really need them. ;-)
With this in mind, let’s test a FOR/NEXT loop:
10 TIMER=0:TM=TIMER 20 FOR A=&H1 TO &H3E8 30 B=&H1 40 NEXT 50 PRINT TIMER-TM
This prints 182, which is basically the same speed as the original that used 0 TO 1000. I guess hexadecimals don’t really help out FOR/NEXT.
Why? Because the FOR/NEXT statement is only parsed once, then the loop counters are set up and done. It is probably a tad faster to use hex, but that savings only happens once in the “do it 1000 times” test.
But, as you see, USING the variables gets faster. Any place we use a number, it seems using a hex version of that number may speed it up:
10 TIMER=0:TM=TIMER 20 FOR A=1 TO 1000 30 IF A>&HFF THEN REM 40 NEXT 50 PRINT TIMER-TM
This prints 278. Doing it with A>255 prints 427! Imagine if you could speed up every time you used a number in your code:
10 TIMER=0:TM=TIMER 20 FOR A=1 TO 1000 30 PRINT@&H20,"HELLO" 40 NEXT 50 PRINT TIMER-TM
That prints 391, but changing it to PRINT@32 prints 469! If you use a bunch of PRINT@s in your code, you can speed them up just by switching to hex!
Math could be accelerated, too, simply due to the number conversion being faster. The more digits, the better advantage hex has:
- B=A+&H270F – 285
- B=A+9999 – 483
And the more numbers, the more time you can save by using hex. A common PRINT thing is to use the length of a string to figure out how to center is on the screen:
0 REM NUMBERS.BAS 10 TIMER=0:TM=TIMER 15 CLS:A$="HELLO, WORLD!":LN=LEN(A$) 20 FOR A=1 TO 1000 25 PRINT@32*8+16-LN/2,A$ 40 NEXT 50 PRINT TIMER-TM
That prints 1284. Converting line 24 to HEX:
And now it prints 1097.
In a game where you might be PRINTing things on the screen constantly, those savings could really add up.
Pity that math is hard, else we could just use hex in our programs and get a free speed boost.
Until next time…