# Displaying 24, 32, 48 and 64-bit hexadecimal, signed and unsigned decimal values

#### hippy

##### Senior Member
Displaying 24, 32, 48 and 64-bit hexadecimal, signed and unsigned decimal values

While greater than 16-bit maths can be relatively straightforward with the right code, showing multi-word numbers as decimal values can be a little complicated.

These routines show how that can be done with a brute-force approach rather than by creating a complicated algorithm. This uses more program memory but keeps the principles simple and minimises the number of variables which need to be used.

The basic principle used here is to use a number of words which each hold four digits of the decimal number. Then one adds to the words values which represent each bit value of the hexadecimal number, keeping them as four digits. Overflow, when a word in the decimal number becomes larger than 9999 is easily handled.

The lower 16-bits can be handled directly which minimises the iterations needed to perform the additions to just 8 for 24-bit, 16 for 32-bit, 32 for 48-bit, but a hefty 48 for 64-bit..

Being a brute force approach there is nothing particularly complicated about the code. It handles integer numbers and two's complement signed numbers. Negation is achieved by inverting and adding one, with any overflow then handled.

Take a look at the 24-bit code first, and you should how the 32-bit and 48-bit versions are just extensions of what is used there.

You will probably notice that the values added to the decimal words halve for each bit. And that's the principle behind a traditional algorithm; set the value for the highest bit, halve it for the next bit, while looping until all bit values have been added.

It would be possible to extend the principle here to larger bit-size numbers using the same principles. It would just require more words to store the decimal value and more program memory to do the additions for the individual bits.

Memory use does increase with bit-size and the 48-bit code won't fit in an M2's memory, and the 64-bit code won't even fit in an X2. There is probably some scope for optimisation but the goal was something 'straight forward' which worked.

Apart from that; this code should work on any M2, X1 and X2 PICAXE and will also run within the PE6 simulator.

If there are any questions; please do ask. If you spot any errors or bugs; please let me know.

#### hippy

##### Senior Member
Code:
``````; *********************************************
; * 24-Bit Number Printing Routines           *
; *********************************************

;     \$FFFFFF = 16777215 = 1677 7216
;
; Bit \$800000 =  8388608 =  838 8608
; Bit \$400000 =  4194304 =  419 4304
; Bit \$200000 =  2097152 =  209 7152
; Bit \$100000 =  1048576 =  104 8576
; Bit \$080000 =   524288 =   52 4288
; Bit \$040000 =   262144 =   26 2144
; Bit \$020000 =   131072 =   13 1072
; Bit \$010000 =    65536 =    6 5536
;
;     \$ABCDEF = 11259375 = 1125 9375
;     \$543211 =  5517841 =  551 7841

; *********************************************
; * Variables                                 *
; *********************************************

; Reserve w0, b1 and b0 for general purpose use

Symbol reserveW0 = w0  ; b1:b0

; The decimal number as two 4-digit words

Symbol dec.h     = w1  ; b3:b2 High digits
Symbol dec.l     = w2  ; b5:b4 Low digits

; The hexadecimal 24-bit number as bytes

Symbol hex.h     = b6  ; High byte
Symbol hex.m     = b7  ; Middle byte
Symbol hex.l     = b8  ; Low byte

; Decimal 4-digit display

Symbol n4        = b9  ; High digit
Symbol n3        = b10
Symbol n2        = b11
Symbol n1        = b12 ; Low digit

; *********************************************
; * Example Program                           *
; *********************************************

Test24BitNumbers:

SerTxd( "24-bit number example", CR, LF )

; Set a 24-bit hexadecimal number
;
;             hex.h   hex.m   hex.l
;           .-------.-------.-------.
; \$ABCDEF = |  \$AB  |  \$CD  |  \$EF  |
;           `-------^-------^-------'

hex.h = \$AB       ; High byte
hex.m = \$CD       ; Middle byte
hex.l = \$EF       ; Low byte

Gosub Show24BitNumber

; Now try the largest unsigned number, also -1

hex.h = \$FF       ; High word
hex.m = \$FF       ; Middle word
hex.l = \$FF       ; Low word

Gosub Show24BitNumber

End

; *********************************************
; * Show the 24-bit number                    *
; *********************************************

Show24BitNumber:

SerTxd( CR, LF )

; Show it as a hexadecimal number
;
; \$ABCDEF
; \$FFFFFF

Gosub ShowAsHex24
SerTxd( CR, LF )

; Show it as an unsigned decimal
;
; \$ABCDEF = 11259375
; \$FFFFFF = 16777215

SerTxd( "Unsigned", TAB )
Gosub ShowAsDec24
SerTxd( CR, LF )

; Show it as a signed decimal
;
; \$ABCDEF = -5517841
; \$FFFFFF = -1

SerTxd( "Signed", TAB )
Gosub ShowAsSignedDec24
SerTxd( CR, LF )

Return

; *********************************************
; * 24-bit number handling routines           *
; *********************************************

If b0 <> 0 Then
dec.l = dec.l + lAdd // 10000
End If
#EndMacro

ShowAsHex24:
SerTxd( "\$" )
b0 = hex.h : Gosub ShowHexByteInB0
b0 = hex.m : Gosub ShowHexByteInB0
b0 = hex.l : Gosub ShowHexByteInB0
Return

ShowHexByteInB0:
b1 = b0 / \$10 + "0" : If b1 > "9" Then : b1 = b1 + 7 : End If
b0 = b0 & \$0F + "0" : If b0 > "9" Then : b0 = b0 + 7 : End If
SerTxd( b1, b0 )
Return

ShowAsDec24:

dec.h = hex.m * 256 + hex.l /  10000
dec.l = hex.m * 256 + hex.l // 10000

If dec.h = 0 Then
SerTxd( #dec.l )
Else
BinToAscii dec.l, n4,n4,n3,n2,n1
SerTxd( #dec.h, n4,n3,n2,n1 )
End If

Return

ShowAsSignedDec24:

If hex.h < \$80 Then
SerTxd( "+" )
Gosub ShowAsDec24
Else
SerTxd( "-" )
Gosub NegateHex24
Gosub ShowAsDec24
Gosub NegateHex24
End If
Return

NegateHex24:
hex.h = hex.h ^ \$FF
hex.m = hex.m ^ \$FF
hex.l = hex.l ^ \$FF + 1
If hex.l = 0 Then
hex.m = hex.m + 1
If hex.m = 0 Then
hex.h = hex.h + 1
End If
End If
Return

; *********************************************
; * End of program                            *
; *********************************************``````
Code:
``````24-bit number example

Unsigned    11259375
Signed      -5517841

Unsigned    16777215
Signed      -1``````

#### hippy

##### Senior Member
Code:
``````; *********************************************
; * 32-Bit Number Printing Routines           *
; *********************************************

;     \$FFFFFFFF = 4294967295 = 42 9496 7295
;
; Bit \$80000000 = 2147483648 = 21 4748 3648
; Bit \$40000000 = 1073741824 = 10 7374 1824
; Bit \$20000000 =  536870912 =  5 3687 0912
; Bit \$10000000 =  268435456 =  2 6843 5456
; Bit \$08000000 =  134217728 =  1 3421 7728
; Bit \$04000000 =   67108864 =    6710 8864
; Bit \$02000000 =   33554432 =    3355 4432
; Bit \$01000000 =   16777216 =    1677 7216
;
; Bit \$00800000 =    8388608 =     838 8608
; Bit \$00400000 =    4194304 =     419 4304
; Bit \$00200000 =    2097152 =     209 7152
; Bit \$00100000 =    1048576 =     104 8576
; Bit \$00080000 =     524288 =      52 4288
; Bit \$00040000 =     262144 =      26 2144
; Bit \$00020000 =     131072 =      13 1072
; Bit \$00010000 =      65536 =       6 5536
;
;     \$89ABCDEF = 2309737967 = 23 0973 7967
;     \$76543211 = 1985229329 = 19 8522 9329

; *********************************************
; * Variables                                 *
; *********************************************

; Reserve w0, b1 and b0 for general purpose use

Symbol reserveW0 = w0  ; b1:b0

; The decimal number as three 4-digit words
; Note that 'dec.h' can be a byte variable

Symbol dec.h     = w1  ; b3:b2   High digits
Symbol dec.m     = w2  ; b5:b4   Middle digits
Symbol dec.l     = w3  ; b7:b6   Low digits

; The hexadecimal 32-bit number as two 16-bit words

Symbol hex.h     = w4  ; b9:b8   High word
Symbol hex.l     = w5  ; b11:b10 Low word

; Decimal 4-digit display

Symbol n4        = b12 ; High digit
Symbol n3        = b13
Symbol n2        = b14
Symbol n1        = b15 ; Low digit

; *********************************************
; * Example Program                           *
; *********************************************

Test32BitNumbers:

SerTxd( "32-bit number example", CR, LF )

; Set a 32-bit hexadecimal number
;
;               hex.h   hex.l
;             .-------.-------.
; \$89ABCDEF = | \$89AB | \$CDEF |
;             `-------^-------'

hex.h = \$89AB     ; High word
hex.l = \$CDEF     ; Low word

Gosub Show32BitNumber

; Now try the largest unsigned number, also -1

hex.h = \$FFFF     ; High word
hex.l = \$FFFF     ; Low word

Gosub Show32BitNumber

End

; *********************************************
; * Show the 32-bit number                    *
; *********************************************

Show32BitNumber:

SerTxd( CR, LF )

; Show it as a hexadecimal number
;
; \$89ABCDEF

Gosub ShowAsHex32
SerTxd( CR, LF )

; Show it as an unsigned decimal
;
; \$89ABCDEF = 2309737967

SerTxd( "Unsigned", TAB )
Gosub ShowAsDec32
SerTxd( CR, LF )

; Show it as a signed decimal
;
; \$89ABCDEF = -1985229329

SerTxd( "Signed", TAB )
Gosub ShowAsSignedDec32
SerTxd( CR, LF )

Return

; *********************************************
; * 32-bit number handling routines           *
; *********************************************

If w0 <> 0 Then
dec.l = dec.l + lAdd // 10000
dec.h = dec.m        /  10000 + dec.h + hAdd
dec.m = dec.m        // 10000
End If
#EndMacro

ShowAsHex32:
SerTxd( "\$" )
w0 = hex.h : Gosub ShowHexByteInB1
w0 = hex.h : Gosub ShowHexByteInB0
w0 = hex.l : Gosub ShowHexByteInB1
w0 = hex.l : Gosub ShowHexByteInB0
Return

ShowHexByteInB1:
b0 = b1

ShowHexByteInB0:
b1 = b0 / \$10 + "0" : If b1 > "9" Then : b1 = b1 + 7 : End If
b0 = b0 & \$0F + "0" : If b0 > "9" Then : b0 = b0 + 7 : End If
SerTxd( b1, b0 )
Return

ShowAsDec32:

dec.h = 0
dec.m = hex.l /  10000
dec.l = hex.l // 10000

AddHexBitToDec32( hex.h, \$0080,  0, 838,8608 )
AddHexBitToDec32( hex.h, \$0040,  0, 419,4304 )
AddHexBitToDec32( hex.h, \$0020,  0, 209,7152 )
AddHexBitToDec32( hex.h, \$0010,  0, 104,8576 )
AddHexBitToDec32( hex.h, \$0008,  0,  52,4288 )
AddHexBitToDec32( hex.h, \$0004,  0,  26,2144 )
AddHexBitToDec32( hex.h, \$0002,  0,  13,1072 )
AddHexBitToDec32( hex.h, \$0001,  0,   6,5536 )

If dec.h = 0 And dec.m = 0 Then
SerTxd( #dec.l )
Else
If dec.h = 0 Then
SerTxd( #dec.m )
Else
BinToAscii dec.m, n4,n4,n3,n2,n1
SerTxd( #dec.h, n4,n3,n2,n1 )
End If
BinToAscii dec.l, n4,n4,n3,n2,n1
SerTxd( n4,n3,n2,n1 )
End If
Return

ShowAsSignedDec32:

If hex.h < \$8000 Then
SerTxd( "+" )
Gosub ShowAsDec32
Else
SerTxd( "-" )
Gosub NegateHex32
Gosub ShowAsDec32
Gosub NegateHex32
End If
Return

NegateHex32:
hex.h = hex.h ^ \$FFFF
hex.l = hex.l ^ \$FFFF + 1
If hex.l = 0 Then
hex.h = hex.h + 1
End If
Return

; *********************************************
; * End of program                            *
; *********************************************``````
Code:
``````32-bit number example

Unsigned    2309737967
Signed      -1985229329

Unsigned    4294967295
Signed      -1``````

#### hippy

##### Senior Member
Code:
``````; *********************************************
; * 48-Bit Number Printing Routines           *
; *********************************************

;     \$FFFFFFFFFFFF = 281474976710655 = 281 4749 7671 0655
;
; Bit \$800000000000 = 140737488355328 = 140 7374 8835 5328
; Bit \$400000000000 =  70368744177664 =  70 3687 4417 7664
; Bit \$200000000000 =  35184372088832 =  35 1843 7208 8832
; Bit \$100000000000 =  17592186044416 =  17 5921 8604 4416
; Bit \$080000000000 =   8796093022208 =   8 7960 9302 2208
; Bit \$040000000000 =   4398046511104 =   4 3980 4651 1104
; Bit \$020000000000 =   2199023255552 =   2 1990 2325 5552
; Bit \$010000000000 =   1099511627776 =   1 0995 1162 7776
;
; Bit \$008000000000 =    549755813888 =     5497 5581 3888
; Bit \$004000000000 =    274877906944 =     2748 7790 6944
; Bit \$002000000000 =    137438953472 =     1374 3895 3472
; Bit \$001000000000 =     68719476736 =      687 1947 6736
; Bit \$000800000000 =     34359738368 =      343 5973 8368
; Bit \$000400000000 =     17179869184 =      171 7986 9184
; Bit \$000200000000 =      8589934592 =       85 8993 4592
; Bit \$000100000000 =      4294967296 =       42 9496 7296
;
; Bit \$000080000000 =      2147483648 =       21 4748 3648
; Bit \$000040000000 =      1073741824 =       10 7374 1824
; Bit \$000020000000 =       536870912 =        5 3687 0912
; Bit \$000010000000 =       268435456 =        2 6843 5456
; Bit \$000008000000 =       134217728 =        1 3421 7728
; Bit \$000004000000 =        67108864 =          6710 8864
; Bit \$000002000000 =        33554432 =          3355 4432
; Bit \$000001000000 =        16777216 =          1677 7216
;
; Bit \$000000800000 =         8388608 =          838 8608
; Bit \$000000400000 =         4194304 =          419 4304
; Bit \$000000200000 =         2097152 =          209 7152
; Bit \$000000100000 =         1048576 =          104 8576
; Bit \$000000080000 =          524288 =           52 4288
; Bit \$000000040000 =          262144 =           26 2144
; Bit \$000000020000 =          131072 =           13 1072
; Bit \$000000010000 =           65536 =            6 5536
;
;     \$89ABCDEFEDCB = 151370987466187
;     \$765432101235 = 130103989244469

; *********************************************
; * Variables                                 *
; *********************************************

; Reserve w0, b1 and b0 for general purpose use

Symbol reserveW0 = w0  ; b1:b0

; The decimal number as four 4-digit words

Symbol dec.x     = w1  ; b3:b2   Extra high digits
Symbol dec.h     = w2  ; b5:b4   High digits
Symbol dec.m     = w3  ; b7:b6   Middle digits
Symbol dec.l     = w4  ; b9:b8   Low digits

; The hexadecimal 48-bit number as three 16-bit words

Symbol hex.h     = w5  ; b11:b10  High word
Symbol hex.m     = w6  ; b13:b12 Middle word
Symbol hex.l     = w7  ; b15:b14 Low word

; Decimal 4-digit display

Symbol n4        = b16 ; High digit
Symbol n3        = b17
Symbol n2        = b18
Symbol n1        = b19 ; Low digit

; *********************************************
; * Example Program                           *
; *********************************************

Test48BitNumbers:

SerTxd( "48-bit number example", CR, LF )

; Set a 48-bit hexadecimal number
;
;                   hex.h   hex.m   hex.l
;                 .-------.-------.-------.
; \$89ABCDEFEDCB = | \$89AB | \$CDEF | \$EDCB |
;                 `-------^-------^-------'

hex.h = \$89AB     ; High word
hex.m = \$CDEF     ; Middle word
hex.l = \$EDCB     ; Low word

Gosub Show48BitNumber

; Now try the largest unsigned number, also -1

hex.h = \$FFFF     ; High word
hex.m = \$FFFF     ; Middle word
hex.l = \$FFFF     ; Low word

Gosub Show48BitNumber

End

; *********************************************
; * Show the 48-bit number                    *
; *********************************************

Show48BitNumber:

SerTxd( CR, LF )

; Show it as a hexadecimal number
;
; \$89ABCDEFEDCB
; \$FFFFFFFFFFFF

Gosub ShowAsHex48
SerTxd( CR, LF )

; Show it as an unsigned decimal
;
; \$89ABCDEFEDCB = 151370987466187
; \$FFFFFFFFFFFF = 281474976710655

SerTxd( "Unsigned", TAB )
Gosub ShowAsDec48
SerTxd( CR, LF )

; Show it as a signed decimal
;
; \$89ABCDEFEDCB = -130103989244469
; \$FFFFFFFFFFFF = -1

SerTxd( "Signed", TAB )
Gosub ShowAsSignedDec48
SerTxd( CR, LF )

Return

; *********************************************
; * 48-bit number handling routines           *
; *********************************************

If w0 <> 0 Then
dec.l = dec.l + lAdd // 10000
dec.h = dec.m        /  10000 + dec.h + hAdd
dec.m = dec.m        // 10000
dec.x = dec.h        /  10000 + dec.x + xAdd
dec.h = dec.h        // 10000
End If
#EndMacro

ShowAsHex48:
SerTxd( "\$" )
w0 = hex.h : Gosub ShowHexByteInB1
w0 = hex.h : Gosub ShowHexByteInB0
w0 = hex.m : Gosub ShowHexByteInB1
w0 = hex.m : Gosub ShowHexByteInB0
w0 = hex.l : Gosub ShowHexByteInB1
w0 = hex.l : Gosub ShowHexByteInB0
Return

ShowHexByteInB1:
b0 = b1

ShowHexByteInB0:
b1 = b0 / \$10 + "0" : If b1 > "9" Then : b1 = b1 + 7 : End If
b0 = b0 & \$0F + "0" : If b0 > "9" Then : b0 = b0 + 7 : End If
SerTxd( b1, b0 )
Return

ShowAsDec48:

dec.x = 0
dec.h = 0
dec.m = hex.l /  10000
dec.l = hex.l // 10000

AddHexBitToDec48( hex.h, \$0010,   0, 687,1947,6736 )
AddHexBitToDec48( hex.h, \$0008,   0, 343,5973,8368 )
AddHexBitToDec48( hex.h, \$0004,   0, 171,7986,9184 )
AddHexBitToDec48( hex.h, \$0002,   0,  85,8993,4592 )
AddHexBitToDec48( hex.h, \$0001,   0,  42,9496,7296 )

AddHexBitToDec48( hex.m, \$8000,   0,  21,4748,3648 )
AddHexBitToDec48( hex.m, \$4000,   0,  10,7374,1824 )
AddHexBitToDec48( hex.m, \$2000,   0,   5,3687,0912 )
AddHexBitToDec48( hex.m, \$1000,   0,   2,6843,5456 )
AddHexBitToDec48( hex.m, \$0800,   0,   1,3421,7728 )
AddHexBitToDec48( hex.m, \$0400,   0,   0,6710,8864 )
AddHexBitToDec48( hex.m, \$0200,   0,   0,3355,4432 )
AddHexBitToDec48( hex.m, \$0100,   0,   0,1677,7216 )

AddHexBitToDec48( hex.m, \$0080,   0,   0, 838,8608 )
AddHexBitToDec48( hex.m, \$0040,   0,   0, 419,4304 )
AddHexBitToDec48( hex.m, \$0020,   0,   0, 209,7152 )
AddHexBitToDec48( hex.m, \$0010,   0,   0, 104,8576 )
AddHexBitToDec48( hex.m, \$0008,   0,   0,  52,4288 )
AddHexBitToDec48( hex.m, \$0004,   0,   0,  26,2144 )
AddHexBitToDec48( hex.m, \$0002,   0,   0,  13,1072 )
AddHexBitToDec48( hex.m, \$0001,   0,   0,   6,5536 )

If dec.x = 0 And dec.h = 0 And dec.m = 0 Then
SerTxd( #dec.l )
Else
If dec.x = 0 Then
If dec.h = 0 Then
SerTxd( #dec.m )
Else
BinToAscii dec.m, n4,n4,n3,n2,n1
SerTxd( #dec.h, n4,n3,n2,n1 )
End If
Else
BinToAscii dec.h, n4,n4,n3,n2,n1
SerTxd( #dec.x, n4,n3,n2,n1 )
BinToAscii dec.m, n4,n4,n3,n2,n1
SerTxd( n4,n3,n2,n1 )
End If
BinToAscii dec.l, n4,n4,n3,n2,n1
SerTxd( n4,n3,n2,n1 )
End If
Return

ShowAsSignedDec48:

If hex.h < \$8000 Then
SerTxd( "+" )
Gosub ShowAsDec48
Else
SerTxd( "-" )
Gosub NegateHex48
Gosub ShowAsDec48
Gosub NegateHex48
End If
Return

NegateHex48:
hex.h = hex.h ^ \$FFFF
hex.m = hex.m ^ \$FFFF
hex.l = hex.l ^ \$FFFF + 1
If hex.l = 0 Then
hex.m = hex.m + 1
If hex.m = 0 Then
hex.h = hex.h + 1
End If
End If
Return

; *********************************************
; * End of program                            *
; *********************************************``````
Code:
``````48-bit number example

Unsigned    151370987466187
Signed      -130103989244469

Unsigned    281474976710655
Signed      -1``````

#### hippy

##### Senior Member
Reserved for 64-bit - If that gets done!

#### hippy

##### Senior Member
With the brute-force approach under our belt we can consider turning what we have into an algorithm which, while more complicated and using more variables, does have the benefit of reducing memory usage. That allows us to create a 48-bit version which will fit within even an M2, though the 64-bit version uses more variables than the M2 provides for.

Previously the programs were all extensions of the 24-bit version. Development of the algorithmic programs here started with the 48-bit version, which was then modified for 64-bit, 32-bit and 24-bit use. It is probably best to start with the 32-bit version to get the clearest understanding of what is being done.

There are a number of things which need to be described for these algorithms -

Because we are no longer adding hard-coded values for bits in a brute-force way, we need an additional set of variables which hold the number we are adding for each bit value. These are the 'add' variables. Those are initialised to the MSB value when we start and then divided by two subsequently, which is done by a shift right. Note that a decimal 1 divided by 2 or shifted right becomes 0.5, which becomes 5000 in the lower set of four-digit words which represents our adding value.

We also need an additional set of variables to hold a temporary copy of the 'hex' value while operating on it. These are our 'tmp' variables. We left shift the 'tmp' value and check the MSB to see if a decimal value has to be added. We could have moved a bit through a bit mask to determine which bits are set but that would also require additional values, and what we have is simpler to implement and easier to follow.

The algorithm is pretty much like the brute-force approach, except rather than adding a specific value for each bit, we loop through all bits which are set, adding to the decimal value, adjusting the bit looked at and the bit value as we go. We finish when there are no more bits set.

Note that, because we can easily handle the least 16-bits separately, these lower 16-bits are not included as a 'tmp' variable, and the looping code and terminating check does not have to deal with those bits.

The handling of the various parts of the algorithm, shifting the 'tmp' value, adding and shifting the 'add' value, is all specified within macro routines to keep code memory usage lower. The number printing output routines have also been slightly modified to earlier to reduce code space.

As noted, all but the 64-bit version will run on an M2, X1 and X2 and in the PE6 simulator. The results generated should of course be identical to those from the brute force method.

Again, if there are any questions then please do ask and please let me know if you spot any bugs.

#### hippy

##### Senior Member
Code:
``````; *********************************************
; * 24-Bit Number Printing Algorithm Routines *
; *********************************************

; Bit \$800000 =  8388608 =  838 8608
;
;     \$ABCDEF = 11259375 = 1125 9375
;     \$543211 =  5517841 =  551 7841
;     \$FFFFFF = 16777215 = 1677 7216

; *********************************************
; * Variables                                 *
; *********************************************

; Reserve w0, b1 and b0 for general purpose use

Symbol reserveW0 = w0  ; b1:b0

; The decimal number as two 4-digit words

Symbol dec.h     = w1  ; b3:b2 High digits
Symbol dec.l     = w2  ; b5:b4 Low digits

; The decimal addition values for bits

Symbol add.h     = w3  ; b7:b6 High digits
Symbol add.l     = w4  ; b9:b8 Low digits

; The hexadecimal 24-bit number as bytes

Symbol hex.h     = b10 ; High byte
Symbol hex.m     = b11 ; Middle byte
Symbol hex.l     = b12 ; Low byte

; Temporary storage for the hexadecimal 24-bit number
; Note tmp.m and tmp.l not needed

Symbol tmp.h     = b13 ; High byte

; Decimal 4-digit display
; Note partly reuses the temporary storage above

Symbol n4        = b13 ; High digit
Symbol n3        = b14
Symbol n2        = b15
Symbol n1        = b16 ; Low digit

; *********************************************
; * Example Program                           *
; *********************************************

Test24BitNumbers:

SerTxd( "24-bit number algorithm example", CR, LF )

; Set a 24-bit hexadecimal number
;
;             hex.h   hex.m   hex.l
;           .-------.-------.-------.
; \$ABCDEF = |  \$AB  |  \$CD  |  \$EF  |
;           `-------^-------^-------'

hex.h = \$AB       ; High byte
hex.m = \$CD       ; Middle byte
hex.l = \$EF       ; Low byte

Gosub Show24BitNumber

; Now try the largest unsigned number, also -1

hex.h = \$FF       ; High word
hex.m = \$FF       ; Middle word
hex.l = \$FF       ; Low word

Gosub Show24BitNumber

End

; *********************************************
; * Show the 24-bit number                    *
; *********************************************

Show24BitNumber:

SerTxd( CR, LF )

; Show it as a hexadecimal number
;
; \$ABCDEF
; \$FFFFFF

Gosub ShowAsHex24
SerTxd( CR, LF )

; Show it as an unsigned decimal
;
; \$ABCDEF = 11259375
; \$FFFFFF = 16777215

SerTxd( "Unsigned", TAB )
Gosub ShowAsDec24
SerTxd( CR, LF )

; Show it as a signed decimal
;
; \$ABCDEF = -5517841
; \$FFFFFF = -1

SerTxd( "Signed", TAB )
Gosub ShowAsSignedDec24
SerTxd( CR, LF )

Return

; *********************************************
; * 24-bit number handling routines           *
; *********************************************

#Macro MoveHexToTmp24
tmp.h = hex.h
#EndMacro

#Macro ShiftTmp24Left
tmp.h = tmp.h + tmp.h
#EndMacro

#EndMacro

dec.l = dec.l + add.l // 10000
#EndMacro

#EndMacro

ShowAsHex24:
SerTxd( "\$" )
b0 = hex.h : Gosub ShowHexByteInB0
b0 = hex.m : Gosub ShowHexByteInB0
b0 = hex.l : Gosub ShowHexByteInB0
Return

ShowHexByteInB0:
b1 = b0 / \$10 + "0" : If b1 > "9" Then : b1 = b1 + 7 : End If
b0 = b0 & \$0F + "0" : If b0 > "9" Then : b0 = b0 + 7 : End If
SerTxd( b1, b0 )
Return

ShowAsDec24:

; Move hex to tmp so we don't corrupt hex

MoveHexToTmp24

; Initialise decimal total

dec.h = hex.m * 256 + hex.l /  10000
dec.l = hex.m * 256 + hex.l // 10000

; Set the addition value for MSB
;
; \$800000 = 8388608 = 838 8608

; Add all the remaining bit values

Do While tmp.h <> 0
If tmp.h >= \$80 Then
End If
ShiftTmp24Left
Loop

; Print the resulting decimal digits

If dec.h = 0 Then
SerTxd( #dec.l )
Else
BinToAscii dec.l, n4,n4,n3,n2,n1
SerTxd( #dec.h, n4,n3,n2,n1 )
End If

Return

ShowAsSignedDec24:

If hex.h < \$80 Then
SerTxd( "+" )
Gosub ShowAsDec24
Else
SerTxd( "-" )
Gosub NegateHex24
Gosub ShowAsDec24
Gosub NegateHex24
End If
Return

NegateHex24:
hex.h = hex.h ^ \$FF
hex.m = hex.m ^ \$FF
hex.l = hex.l ^ \$FF + 1
If hex.l = 0 Then
hex.m = hex.m + 1
If hex.m = 0 Then
hex.h = hex.h + 1
End If
End If
Return

; *********************************************
; * End of program                            *
; *********************************************``````
Code:
``````24-bit number algorithm example

Unsigned    11259375
Signed      -5517841

Unsigned    16777215
Signed      -1``````

#### hippy

##### Senior Member
Code:
``````; *********************************************
; * 32-Bit Number Printing Algorithm Routines *
; *********************************************

; Bit \$80000000 = 2147483648 = 21 4748 3648
;
;     \$89ABCDEF = 2309737967 = 23 0973 7967
;     \$76543211 = 1985229329 = 19 8522 9329
;     \$FFFFFFFF = 4294967295 = 42 9496 7295

; *********************************************
; * Variables                                 *
; *********************************************

; Reserve w0, b1 and b0 for general purpose use

Symbol reserveW0 = w0  ; b1:b0

; The decimal number as three 4-digit words
; Note that 'dec.h' can be a byte variable

Symbol dec.h     = w1  ; b3:b2   High digits
Symbol dec.m     = w2  ; b5:b4   Middle digits
Symbol dec.l     = w3  ; b7:b6   Low digits

; The decimal addition values for bits

Symbol add.h     = w4  ; b9:b8   High digits
Symbol add.m     = w5  ; b11:b10 Middle digits
Symbol add.l     = w6  ; b13:b12 Low digits

; The hexadecimal 32-bit number as two 16-bit words

Symbol hex.h     = w7  ; b15:b14 High word
Symbol hex.l     = w8  ; b17:b16 Low word

; Temporary storage for the hexadecimal 32-bit number
; Note tmp.l not needed

Symbol tmp.h     = w9  ; b19:b18 High word

; Decimal 4-digit display
; Note partly reuses the temporary storage above

Symbol n4        = b18 ; High digit
Symbol n3        = b19
Symbol n2        = b20
Symbol n1        = b21 ; Low digit

; *********************************************
; * Example Program                           *
; *********************************************

Test32BitNumbers:

SerTxd( "32-bit number algorithm example", CR, LF )

; Set a 32-bit hexadecimal number
;
;               hex.h   hex.l
;             .-------.-------.
; \$89ABCDEF = | \$89AB | \$CDEF |
;             `-------^-------'

hex.h = \$89AB     ; High word
hex.l = \$CDEF     ; Low word

Gosub Show32BitNumber

; Now try the largest unsigned number, also -1

hex.h = \$FFFF     ; High word
hex.l = \$FFFF     ; Low word

Gosub Show32BitNumber

End

; *********************************************
; * Show the 32-bit number                    *
; *********************************************

Show32BitNumber:

SerTxd( CR, LF )

; Show it as a hexadecimal number
;
; \$89ABCDEF
; \$FFFFFFFF

Gosub ShowAsHex32
SerTxd( CR, LF )

; Show it as an unsigned decimal
;
; \$89ABCDEF = 2309737967
; \$FFFFFFFF = 4294967295

SerTxd( "Unsigned", TAB )
Gosub ShowAsDec32
SerTxd( CR, LF )

; Show it as a signed decimal
;
; \$89ABCDEF = -1985229329
; \$FFFFFFFF = -1

SerTxd( "Signed", TAB )
Gosub ShowAsSignedDec32
SerTxd( CR, LF )

Return

; *********************************************
; * 32-bit number handling routines           *
; *********************************************

#Macro MoveHexToTmp32
tmp.h = hex.h
#EndMacro

#Macro ShiftTmp32Left
tmp.h = tmp.h + tmp.h
#EndMacro

#Macro SetAdd32( iniH, iniM, iniL )
#EndMacro

dec.l = dec.l + add.l // 10000
dec.h = dec.m         /  10000 + dec.h + add.h
dec.m = dec.m         // 10000
#EndMacro

#EndMacro

ShowAsHex32:
SerTxd( "\$" )
w0 = hex.h : Gosub ShowHexByteInB1
w0 = hex.h : Gosub ShowHexByteInB0
w0 = hex.l : Gosub ShowHexByteInB1
w0 = hex.l : Gosub ShowHexByteInB0
Return

ShowHexByteInB1:
b0 = b1

ShowHexByteInB0:
b1 = b0 / \$10 + "0" : If b1 > "9" Then : b1 = b1 + 7 : End If
b0 = b0 & \$0F + "0" : If b0 > "9" Then : b0 = b0 + 7 : End If
SerTxd( b1, b0 )
Return

ShowAsDec32:

; Move hex to tmp so we don't corrupt hex

MoveHexToTmp32

; Initialise decimal total

dec.h = 0
dec.m = hex.l /  10000
dec.l = hex.l // 10000

; Set the addition value for MSB
;
; \$80000000 = 2147483648 = 21 4748 3648

; Add all the remaining bit values

Do while tmp.h <> 0
If tmp.h >= \$8000 Then
End If
ShiftTmp32Left
Loop

; Print the resulting decimal digits

If dec.h <> 0 Then
SerTxd( #dec.h ) : Goto ShowDigitsInM
End If
If dec.m <> 0 Then
SerTxd( #dec.m ) : Goto ShowDigitsInL
Else
SerTxd( #dec.l )
End If
Return

ShowDigitsInM:
w0 = dec.m : Gosub ShowDigitsInW0
ShowDigitsInL:
w0 = dec.l

ShowDigitsInW0:
BinToAscii w0, n4,n4,n3,n2,n1
SerTxd( n4,n3,n2,n1 )
Return

ShowAsSignedDec32:

If hex.h < \$8000 Then
SerTxd( "+" )
Gosub ShowAsDec32
Else
SerTxd( "-" )
Gosub NegateHex32
Gosub ShowAsDec32
Gosub NegateHex32
End If
Return

NegateHex32:
hex.h = hex.h ^ \$FFFF
hex.l = hex.l ^ \$FFFF + 1
If hex.l = 0 Then
hex.h = hex.h + 1
End If
Return

; *********************************************
; * End of program                            *
; *********************************************``````
Code:
``````32-bit number algorithm example

Unsigned    2309737967
Signed      -1985229329

Unsigned    4294967295
Signed      -1``````

#### hippy

##### Senior Member
Code:
``````; *********************************************
; * 48-Bit Number Printing Algorithm Routines *
; *********************************************

; Bit \$800000000000 = 140737488355328 = 140 7374 8835 5328
;
;     \$89ABCDEFEDCB = 151370987466187
;     \$765432101235 = 130103989244469
;     \$FFFFFFFFFFFF = 281474976710655

; *********************************************
; * Variables                                 *
; *********************************************

; Reserve w0, b1 and b0 for general purpose use

Symbol reserveW0 = w0  ; b1:b0

; The decimal number as four 4-digit words

Symbol dec.x     = w1  ; b3:b2   Extra high digits
Symbol dec.h     = w2  ; b5:b4   High digits
Symbol dec.m     = w3  ; b7:b6   Middle digits
Symbol dec.l     = w4  ; b9:b8   Low digits

; The decimal addition values for bits

Symbol add.x     = w5  ; b11:b10 Extra high digits
Symbol add.h     = w6  ; b13:b12 High digits
Symbol add.m     = w7  ; b15:b14 Middle digits
Symbol add.l     = w8  ; b17:b16 Low digits

; The hexadecimal 48-bit number as three 16-bit words

Symbol hex.h     = w9  ; b19:b18  High word
Symbol hex.m     = w10 ; b21:b20 Middle word
Symbol hex.l     = w11 ; b23:b22 Low word

; Temporary storage for the hexadecimal 48-bit number
; Note tmp.l not needed

Symbol tmp.h     = w12 ; b25:b24  High word
Symbol tmp.m     = w13 ; b27:b26 Middle word

; Decimal 4-digit display
; Note reuses the temporary storage above

Symbol n4        = b24 ; High digit
Symbol n3        = b25
Symbol n2        = b26
Symbol n1        = b27 ; Low digit

; *********************************************
; * Example Program                           *
; *********************************************

Test48BitNumbers:

SerTxd( "48-bit number algorithm example", CR, LF )

; Set a 48-bit hexadecimal number
;
;                   hex.h   hex.m   hex.l
;                 .-------.-------.-------.
; \$89ABCDEFEDCB = | \$89AB | \$CDEF | \$EDCB |
;                 `-------^-------^-------'

hex.h = \$89AB     ; High word
hex.m = \$CDEF     ; Middle word
hex.l = \$EDCB     ; Low word

Gosub Show48BitNumber

; Now try the largest unsigned number, also -1

hex.h = \$FFFF     ; High word
hex.m = \$FFFF     ; Middle word
hex.l = \$FFFF     ; Low word

Gosub Show48BitNumber

End

; *********************************************
; * Show the 48-bit number                    *
; *********************************************

Show48BitNumber:

SerTxd( CR, LF )

; Show it as a hexadecimal number
;
; \$89ABCDEFEDCB
; \$FFFFFFFFFFFF

Gosub ShowAsHex48
SerTxd( CR, LF )

; Show it as an unsigned decimal
;
; \$89ABCDEFEDCB = 151370987466187
; \$FFFFFFFFFFFF = 281474976710655

SerTxd( "Unsigned", TAB )
Gosub ShowAsDec48
SerTxd( CR, LF )

; Show it as a signed decimal
;
; \$89ABCDEFEDCB = -130103989244469
; \$FFFFFFFFFFFF = -1

SerTxd( "Signed", TAB )
Gosub ShowAsSignedDec48
SerTxd( CR, LF )

Return

; *********************************************
; * 48-bit number handling routines           *
; *********************************************

#Macro MoveHexToTmp48
tmp.h = hex.h
tmp.m = hex.m
#EndMacro

#Macro ShiftTmp48Left
tmp.h = tmp.m / \$8000 + tmp.h + tmp.h
tmp.m =                 tmp.m + tmp.m
#EndMacro

#Macro SetAdd48( iniX, iniH, iniM, iniL )
#EndMacro

dec.l = dec.l + add.l // 10000
dec.h = dec.m         /  10000 + dec.h + add.h
dec.m = dec.m         // 10000
dec.x = dec.h         /  10000 + dec.x + add.x
dec.h = dec.h         // 10000
#EndMacro

#EndMacro

ShowAsHex48:
SerTxd( "\$" )
w0 = hex.h : Gosub ShowHexByteInB1
w0 = hex.h : Gosub ShowHexByteInB0
w0 = hex.m : Gosub ShowHexByteInB1
w0 = hex.m : Gosub ShowHexByteInB0
w0 = hex.l : Gosub ShowHexByteInB1
w0 = hex.l : Gosub ShowHexByteInB0
Return

ShowHexByteInB1:
b0 = b1

ShowHexByteInB0:
b1 = b0 / \$10 + "0" : If b1 > "9" Then : b1 = b1 + 7 : End If
b0 = b0 & \$0F + "0" : If b0 > "9" Then : b0 = b0 + 7 : End If
SerTxd( b1, b0 )
Return

ShowAsDec48:

; Move hex to tmp so we don't corrupt hex

MoveHexToTmp48

; Initialise decimal total

dec.x = 0
dec.h = 0
dec.m = hex.l /  10000
dec.l = hex.l // 10000

; Set the addition value for MSB
;
; \$800000000000 = 140737488355328 = 140 7374 8835 5328

; Add all the remaining bit values

Do While tmp.h <> 0 Or tmp.m <> 0
If tmp.h >= \$8000 Then
End If
ShiftTmp48Left
Loop

; Print the resulting decimal digits

If dec.x <> 0 Then
SerTxd( #dec.x ) : Goto ShowDigitsInH
End If
If dec.h <> 0 Then
SerTxd( #dec.h ) : Goto ShowDigitsInM
End If
If dec.m <> 0 Then
SerTxd( #dec.m ) : Goto ShowDigitsInL
Else
SerTxd( #dec.l )
End If
Return

ShowDigitsInH:
w0 = dec.h : Gosub ShowDigitsInW0
ShowDigitsInM:
w0 = dec.m : Gosub ShowDigitsInW0
ShowDigitsInL:
w0 = dec.l

ShowDigitsInW0:
BinToAscii w0, n4,n4,n3,n2,n1
SerTxd( n4,n3,n2,n1 )
Return

ShowAsSignedDec48:

If hex.h < \$8000 Then
SerTxd( "+" )
Gosub ShowAsDec48
Else
SerTxd( "-" )
Gosub NegateHex48
Gosub ShowAsDec48
Gosub NegateHex48
End If
Return

NegateHex48:
hex.h = hex.h ^ \$FFFF
hex.m = hex.m ^ \$FFFF
hex.l = hex.l ^ \$FFFF + 1
If hex.l = 0 Then
hex.m = hex.m + 1
If hex.m = 0 Then
hex.h = hex.h + 1
End If
End If
Return

; *********************************************
; * End of program                            *
; *********************************************``````
Code:
``````48-bit number algorithm example

Unsigned    151370987466187
Signed      -130103989244469

Unsigned    281474976710655
Signed      -1``````

#### hippy

##### Senior Member
Code:
``````; *********************************************
; * 64-Bit Number Printing Algorithm Routines *
; *********************************************

; Bit \$8000000000000000 =  9223372036854775808 = 922 3372 0368 5477 5808
;
;     \$89ABCDEFEDCBA987 =  9920249034584074631
;     \$7654321012345679 =  8526495039125476985
;     \$FFFFFFFFFFFFFFFF = 18446744073709551615

; *********************************************
; * Variables                                 *
; *********************************************

; Reserve w0, b1 and b0 for general purpose use

Symbol reserveW0 = w0  ; b1:b0

; The decimal number as five 4-digit words

Symbol dec.u     = w1  ; b3:b2   Uppermost high digits
Symbol dec.x     = w2  ; b5:b4   Extra high digits
Symbol dec.h     = w3  ; b7:b6   High digits
Symbol dec.m     = w4  ; b9:b8   Middle digits
Symbol dec.l     = w5  ; b11:b10 Low digits

; The decimal addition values for bits

Symbol add.u     = w6  ; b13:b12 Uppermost high digits
Symbol add.x     = w7  ; b15:b14 Extra high digits
Symbol add.h     = w8  ; b17:b16 High digits
Symbol add.m     = w9  ; b19:b18 Middle digits
Symbol add.l     = w10 ; b21:b20 Low digits

; The hexadecimal 64-bit number as four 16-bit words

Symbol hex.x     = w11 ; b23:b22 Extra High word
Symbol hex.h     = w12 ; b25:b24 High word
Symbol hex.m     = w13 ; b27:b26 Middle word
Symbol hex.l     = w14 ; b29:b28 Low word

; Temporary storage for the hexadecimal 64-bit number
; Note tmp.l not needed

Symbol tmp.x     = w15 ; b31:b30 High word
Symbol tmp.h     = w16 ; b33:b32 High word
Symbol tmp.m     = w17 ; b35:b34 Middle word

; Decimal 4-digit display
; Note reuses the temporary storage above

Symbol n4        = b30 ; High digit
Symbol n3        = b31
Symbol n2        = b32
Symbol n1        = b33 ; Low digit

; *********************************************
; * Example Program                           *
; *********************************************

Test48BitNumbers:

SerTxd( "64-bit number algorithm example", CR, LF )

; Set a 64-bit hexadecimal number
;
;                   hex.x   hex.h   hex.m   hex.l
;                 .-------.-------.-------.------.
; \$89ABCDEFEDCB = | \$89AB | \$CDEF | \$EDCB | A987 |
;                 `-------^-------^-------^------'

hex.x = \$89AB     ; Extra high word
hex.h = \$CDEF     ; High word
hex.m = \$EDCB     ; Middle word
hex.l = \$A987     ; Low word

Gosub Show64BitNumber

; Now try the largest unsigned number, also -1

hex.x = \$FFFF     ; Extra high word
hex.h = \$FFFF     ; High word
hex.m = \$FFFF     ; Middle word
hex.l = \$FFFF     ; Low word

Gosub Show64BitNumber

End

; *********************************************
; * Show the 64-bit number                    *
; *********************************************

Show64BitNumber:

SerTxd( CR, LF )

; Show it as a hexadecimal number
;
; \$89ABCDEFEDCBA987
; \$FFFFFFFFFFFFFFFF

Gosub ShowAsHex64
SerTxd( CR, LF )

; Show it as an unsigned decimal
;
; \$89ABCDEFEDCBA987 =  9920249034584074631
; \$FFFFFFFFFFFFFFFF = 18446744073709551615

SerTxd( "Unsigned", TAB )
Gosub ShowAsDec64
SerTxd( CR, LF )

; Show it as a signed decimal
;
; \$89ABCDEFEDCBA987 = -8526495039125476985
; \$FFFFFFFFFFFFFFFF = -1

SerTxd( "Signed", TAB )
Gosub ShowAsSignedDec64
SerTxd( CR, LF )

Return

; *********************************************
; * 64-bit number handling routines           *
; *********************************************

#Macro MoveHexToTmp64
tmp.x = hex.x
tmp.h = hex.h
tmp.m = hex.m
#EndMacro

#Macro ShiftTmp64Left
tmp.x = tmp.h / \$8000 + tmp.x + tmp.x
tmp.h = tmp.m / \$8000 + tmp.h + tmp.h
tmp.m =                 tmp.m + tmp.m
#EndMacro

#Macro SetAdd64( iniU, iniX, iniH, iniM, iniL )
#EndMacro

dec.l = dec.l + add.l // 10000
dec.h = dec.m         /  10000 + dec.h + add.h
dec.m = dec.m         // 10000
dec.x = dec.h         /  10000 + dec.x + add.x
dec.h = dec.h         // 10000
dec.u = dec.x         /  10000 + dec.u + add.u
dec.x = dec.x         // 10000
#EndMacro

#EndMacro

ShowAsHex64:
SerTxd( "\$" )
w0 = hex.x : Gosub ShowHexByteInB1
w0 = hex.x : Gosub ShowHexByteInB0
w0 = hex.h : Gosub ShowHexByteInB1
w0 = hex.h : Gosub ShowHexByteInB0
w0 = hex.m : Gosub ShowHexByteInB1
w0 = hex.m : Gosub ShowHexByteInB0
w0 = hex.l : Gosub ShowHexByteInB1
w0 = hex.l : Gosub ShowHexByteInB0
Return

ShowHexByteInB1:
b0 = b1

ShowHexByteInB0:
b1 = b0 / \$10 + "0" : If b1 > "9" Then : b1 = b1 + 7 : End If
b0 = b0 & \$0F + "0" : If b0 > "9" Then : b0 = b0 + 7 : End If
SerTxd( b1, b0 )
Return

ShowAsDec64:

; Move hex to tmp so we don't corrupt hex

MoveHexToTmp64

; Initialise decimal total

dec.u = 0
dec.x = 0
dec.h = 0
dec.m = hex.l /  10000
dec.l = hex.l // 10000

; Set the addition value for MSB
;
; \$8000000000000000 = 9223372036854775808 = 922 3372 0368 5477 5808

; Add all the remaining bit values

Do While tmp.x <> 0 Or tmp.h <> 0 Or tmp.m <> 0
If tmp.x >= \$8000 Then
End If
ShiftTmp64Left
Loop

; Print the resulting decimal digits

If dec.u <> 0 Then
SerTxd( #dec.u ) : Goto ShowDigitsInX
End If
If dec.x <> 0 Then
SerTxd( #dec.x ) : Goto ShowDigitsInH
End If
If dec.h <> 0 Then
SerTxd( #dec.h ) : Goto ShowDigitsInM
End If
If dec.m <> 0 Then
SerTxd( #dec.m ) : Goto ShowDigitsInL
Else
SerTxd( #dec.l )
End If
Return

ShowDigitsInX:
w0 = dec.x : Gosub ShowDigitsInW0
ShowDigitsInH:
w0 = dec.h : Gosub ShowDigitsInW0
ShowDigitsInM:
w0 = dec.m : Gosub ShowDigitsInW0
ShowDigitsInL:
w0 = dec.l

ShowDigitsInW0:
BinToAscii w0, n4,n4,n3,n2,n1
SerTxd( n4,n3,n2,n1 )
Return

ShowAsSignedDec64:

If hex.x < \$8000 Then
SerTxd( "+" )
Gosub ShowAsDec64
Else
SerTxd( "-" )
Gosub NegateHex64
Gosub ShowAsDec64
Gosub NegateHex64
End If
Return

NegateHex64:
hex.x = hex.x ^ \$FFFF
hex.h = hex.h ^ \$FFFF
hex.m = hex.m ^ \$FFFF
hex.l = hex.l ^ \$FFFF + 1
If hex.l = 0 Then
hex.m = hex.m + 1
If hex.m = 0 Then
hex.h = hex.h + 1
If hex.h = 0 Then
hex.x = hex.x + 1
End If
End If
End If
Return

; *********************************************
; * End of program                            *
; *********************************************``````
Code:
``````64-bit number algorithm example