Is there a mnemonic trick for switching numeric bases?

So in programming it’s often handy to handle numbers in something other than base-10, which we’re all used to.

Other common bases are:

base sigil range name
2 % 0–1 binary
8 @ 0–7 octal
10 0–9 decimal
16 $ 0–F hexadecimal

Are there especially efficient mnemonic tricks for switching bases quickly and easily? Also, what about dealing with two’s complement signed values?

I find two’s complement to be especially painful to deal with. As I write code in 6502 assembly as a hobby, I actually deal with signed binary numbers a lot. Signed binary forms the basis of how branching instructions work — usually as a relative jump — in multiple CPU architectures.

Tricks for switching between other bases are also welcome, I know there are quite a few people interested in duodecimal and sexagesimal.

1 Like

Is it answered somewhere in this thread already?

If not… could you be a bit more specific as far as what you’re looking for exactly.

2 Likes

3 posts were split to a new topic: 6502 Assembly, Raku

The thread that Björn is referencing contains all you need to know about calculating with different bases.

One thing we have never talked about on this forum is 2’s complement.

Mental calculation here is easier. Let’s assume we are working in hexadecimal.

A number is negative if the leftmost binary digit is 1. This is the sign bit.
in hexadecimal this translates to the leftmost digit being 8 or higher (so 8, 9, A, B, C, D, E or F).

The negative number is just the distance from zero. Let’s assume we look at byttes. In hexadecimal this means that we can hold a maximum of 2 digits.

“FF” is “-1”.
FF + 1 = 100.
Because we can hold only 2 (hex) digits, 100 is two zero digits with a carry.
We discard the carry, so if we have one byte of space, FF + 1 becomes 00.

Then FE = -2, because FE + 2 = 100. etc.

There are 2 methods for converting a negative number to positive.
First check if the sign bit is indeed set. Again, in hexadecimal, this means a digit of 8 or higher.

Then:
Method 1:
If we are working with 2 digit numbers, subtract the number from 100.
So if AE is the number, 100 - AE = 52. If you don’t know how to do this, AE is almost B0. 100 - B0 = 50. Calculating from left to right, we do 10 - B first. 10 in hex is 16 in decimal and B (hex) is 11 decimal and 16 - 11 = 5.
Last step 10 - E (hex) = 16 - 14 (dec) = 2.

With 2 digits, the number to subtract from is 100.
With n digits, the number to subtract from is 10^n (hex). This is a 1 followed by n number of zero’s.

Method 2:
This works best in binary. If our number is AE (hex), in binary this is:
1010 1110. Now convert all zero’'s into one’s and all one’s into zero’s:
0101 0001. Convert back to hexadecimal = 51.
Last step: add one. 51 + 1 = 52.

1 Like

A small addition to method 1 that Kinma mentioned:

In base ten, we take complements by subtracting the first few digits from 9, and the final digit from 10. For example, we might say the “complement” of 673 is 327, because 673+327=1000.

The same applies to taking a 2’s complement when you’re working in base 16. The process is to subtract each digit from F, then subtract the final digit from 10 (all of this in base 16). For example, the 2’s complement of 4A4 is B5C.

The only exception to these rules is if your number ends in zero. In base ten, we deal with this by ignoring the zero(s) at the end, take the complement of the number, and then add them back. We can do the same in base 16 or binary.

So in short, the process for 2’s complement in hexadecimal is as simple as taking the complement of each digit, just like you would in base 10.

In binary, it’s even easier: starting from the left, flip every bit until you reach the last (rightmost) 1. Leave the remaining bits alone. So the 2’s complement of 0110100 is 1001100.