byte from 0-255 , create byte from 255-0 with overflow in the basic

All aspects of programming on the Commander X16.
funkheld
Posts: 322
Joined: Mon Feb 26, 2024 11:11 am

Re: byte from 0-255 , create byte from 255-0 with overflow in the basic

Post by funkheld »

hey... thanks, you can do magic. :o
counting with if is very fast.

Thanks.
greeting
User avatar
desertfish
Posts: 1098
Joined: Tue Aug 25, 2020 8:27 pm
Location: Netherlands

Re: byte from 0-255 , create byte from 255-0 with overflow in the basic

Post by desertfish »

Note that the 'trick' with AND only works with cycles of powers of 2 , in this case 0-255, a cycle of length 256
TomXP411
Posts: 1785
Joined: Tue May 19, 2020 8:49 pm

Re: byte from 0-255 , create byte from 255-0 with overflow in the basic

Post by TomXP411 »

funkheld wrote: Tue Mar 26, 2024 5:40 pm hello thanks for info.

with basic z is not 0 but z=0.0000001...

greeting
This is not correct. A 40 bit float can represent any 32 bit integer with perfect precision. In fact, my tests show you can go as high as 2^33 with full precision. The first lost bit happens at 2^33+1.

Here's the brief explanation:

A CBM float uses 31 bits to represent the mantissa, which you can think of as the digits of a number. It also stores an exponent, which is actually a power of two multiplier.

The mantissa is actually stored as a binary fraction. You're used to working with binary integers, where the bit values are 1,2,3,8, and so on. With binary fractions, the bit values are reversed: the leftmost bit is 1, then each bit after that is half of the previous bit: 0.5, 0.25, 0.125, and so on.

The exponent is then used to convert the fractional values to a real value that we can print on the screen. Since the exponent is also binary, this means we're basically just shifting the bits left or right a certain number of places (up to 127 places either direction.)

So let's look at how this actually works:

We all know how to represent a decimal integer as a binary integer. 5 decimal becomes 101 binary, for example (I'll write that as %101). Breaking that down, we're adding 4 and 1 to make 5.

Floating values work the same way, but instead of each bit being a whole value, they are fractional values; the leftmost bit in a float represents 1.0, and each bit to the right is 1/2 of that value. So the float bit positions look like 1.0, 0.5, 0.25, 0.125, and so on. The difference is that we can use the exponent to shift those bits left and right, so that 1 bit can actually be 2, 4, 8, or any other power of two.

So what does 5 look like as a floating point binary? %1.01. Actually, that's just the mantissa. We also need an exponent: 2, in this case. That exponent of 2 shifts the bits over, and we get: %101. I'm sure by now that you recognize the binary pattern for 5.

So since floats are just bit shifted integers, we can represent any integer as a binary number, then just bit shift it to get a float.

For example: 2368 is %100101000000. This is a 12 digit binary number.

To make this a float, we just take the number of digits, minus 1, and move the decimal point over:
%1.00101000000 e 11

Finally, both CBM floats don't actually store the "1" bit, because that's implied by the format. That's discarded, and CBM replaces it with the sign. So the mantissa for 2368 is actually .00101...

So a value of 1.0 is not something like 1.000000001 in floating point format. It's exactly 1.0.

As a final test, let's try converting the integer 2368 to a float on the X16 emulator and inspect the raw data of the variable:
10 X = 2368
20 P = POINTER(X)
30 FOR I=P TO P+4
40 PRINT BIN$(PEEK(I));" ";
50 NEXT
60 PRINT
READY.

10001100 00010100 00000000 00000000 00000000
So this requires some parsing, so let's take apart the binary number:

The first 8 bits are the exponent. We have to subtract 129 to get the actual value.
%10001100 = 140
140-129 = 11

The next bit (the first bit in the second octet) is the sign. That's 0, so this is a positive number.

So we have the implied 1, followed by the remaining bits. Let's write that out:
10010100 00000000 00000000 00000000

Shift left 11 places and drop the trailing zeroes:
%100 1010 0000 = 2368

Just for fun, let's do 1.0:

10000001 00000000 00000000 00000000 00000000

Exponent 129 = 0 (no shift)
sign 0 (positive)
mantissa: 1.0 (implied 1, remaining bits are zero.)
TomXP411
Posts: 1785
Joined: Tue May 19, 2020 8:49 pm

Re: byte from 0-255 , create byte from 255-0 with overflow in the basic

Post by TomXP411 »

Here's a more general purpose "print the bits of a float" program:

10 CLS 20 X=1 30 GOSUB 1000 40 END 1000 REM PRINT BINARY 1010 PRINT " VALUE";TAB(18);"EXP";TAB(28);"MANTISSA" 1020 P=POINTER(X) 1030 PRINT X;TAB(18); 1040 PRINT BIN$(PEEK(P));" ";TAB(28); 1050 SI=PEEK(P+1) AND $80 1060 FOR PP=P+1 TO P+4 1070 PRINT BIN$(PEEK(PP));" "; 1080 NEXT 1090 REM REPLACE BIT 0 OF MANTISSA WITH SIGN AND IMPLIED 1 1100 PRINT:PRINT"\X91";TAB(27);"\X9F"; 1110 IF SI>0 THEN PRINT "-"; 1120 IF SI=0 THEN PRINT "+"; 1130 PRINT "\X9E1\X05" 1140 RETURN
Post Reply