Author Topic: Floating Point Illustrator  (Read 3613 times)

0 Members and 1 Guest are viewing this topic.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Floating Point Illustrator
« on: July 12, 2021, 02:21:54 pm »
As a few members don't seem to understand the relationship between decimal values and binary representation of them via floating point values, I thought I'd toss together this quick little program so someone could play around with it and see how our values are stored in memory.

Code: QB64: [Select]
  1. _Title "Floating Point Variables"
  2. Screen _NewImage(1024, 720, 32)
  3. _Delay .25
  4.  
  5. m = _Mem(s)
  6.  
  7. For i = 2 To 8: b(i) = 1: Next 'start with a 127 exponent for a value of 0, normalized
  8.  
  9.     Cls
  10.     k = _KeyHit
  11.  
  12.     Select Case k
  13.         Case 19200: p = p - 1: If p < 0 Then p = 31
  14.         Case 19712: p = p + 1: If p > 31 Then p = 1
  15.         Case 43, 61 'plus
  16.             If p > 0 And p < 9 Then
  17.                 For i = 8 To 1 Step -1
  18.                     If b(i) = 1 Then b(i) = 0 Else b(i) = 1: Exit For
  19.                 Next
  20.             End If
  21.         Case 45, 95 'minus
  22.             If p > 0 And p < 9 Then
  23.                 For i = 8 To 1 Step -1
  24.                     If b(i) = 0 Then b(i) = 1 Else b(i) = 0: Exit For
  25.                 Next
  26.             End If
  27.         Case 18432: b(p) = 1
  28.         Case 20480: b(p) = 0
  29.         Case 32: b(p) = Not (b(p))
  30.     End Select
  31.  
  32.  
  33.     l = 0: ex = 0
  34.  
  35.     b$ = "1."
  36.     For i = 1 To 8 'calculate the exponent value
  37.         If b(i) Then ex = ex Or 2 ^ (8 - i)
  38.     Next
  39.     For i = 0 To 31
  40.         Select Case i
  41.             Case 0: Color Green
  42.             Case Is < 9: Color Red
  43.             Case Else: Color White
  44.         End Select
  45.         Print b(i);
  46.         If b(i) <> 0 Then l = l Or 2 ^ (31 - i)
  47.     Next 'print the 32-bit SINGLE
  48.     For i = 9 To 31 'assemble the mantissa into a single string to display
  49.         If b(i) <> 0 Then b$ = b$ + "1" Else b$ = b$ + "0"
  50.     Next
  51.  
  52.     _MemPut m, m.OFFSET, l 'put our 4-byte value into the single variable
  53.     Print " = "; s
  54.     Locate 3, 3 * p + 2: Print "^"
  55.  
  56.     Print
  57.     Print
  58.     Print "Left/Right to move selector"
  59.     Print "Up/Down to select/unselect bit"
  60.     Print "Space to toggle bit"
  61.     Print "+/- to increment whole exponent by 1"
  62.     Print
  63.     Print "Your current sign is:"; b(0)
  64.     Print "Your current exponent is:"; ex - 127
  65.     Print
  66.     Print "The binary value (in formalized format) is: "; b$; "E"; _Trim$(Str$(ex - 127))
  67.     Print Using "Which in decimal value is: #################.###################"; s
  68.     _Display
  69.     _Limit 30

Now, the important things to keep in mind here is:

1) Your binary value is stored in formalized format.  Just as 1,234 is written as 1.234E3, the binary value of 111 (which is 7, in base-10 math) is written and stored as 1.11E2.
2) When looking at how this value is stored in memory, it's stored with:
    the first bit representing the sign.  (+ or -)
    the next 8 bits represent our exponent PLUS 127 (to store negative values)
    the remaining bits represent our formalized format
3) Now note, since formalized format will ALWAYS begin with a 1, storing that value is redundant and as such it isn't done.  We only store those values right of the period.

So, putting this together, The value for 1 would be:
0 --- 01111111 --- 0000000000000000000000

That first 0 represents that there's no negative sign.  (Toggle it and you'll see that our value swaps to become a -1)
The next 8 bits represent the value of 127; which as I mentioned before is an exponent of 0 PLUS 127.  This gives us an exponent of 0.
The rest of the bits are the mantissa, which in this case are just 0.

Put those together, and you have a binary value of: +1.0E0   (Remember, the leading 1 to the left of the period is implied and not stored.)
 

And, the value for 2 would be:
0 --- 10000000 --- 0000000000000000000000

That first 0 represents that there's no negative sign.  (Toggle it and you'll see that our value swaps to become a -1)
The next 8 bits represent the value of 128; which as I mentioned before is an exponent of 1 PLUS 127.  This gives us an exponent of 1.
The rest of the bits are the mantissa, which in this case are just 0.

Put those together, and you have a binary value of: +1.0E1   (Remember, the leading 1 to the left of the period is implied and not stored.)

Shift that to normalized format and the binary value is: 10.   (And, as everyone knows, 10 = 2.)


And, the value for 3 would be:
0 --- 10000000 --- 1000000000000000000000

That first 0 represents that there's no negative sign.  (Toggle it and you'll see that our value swaps to become a -1)
The next 8 bits represent the value of 128; which as I mentioned before is an exponent of 1 PLUS 127.  This gives us an exponent of 1.
The rest of the bits are the mantissa, which in this case are just 1, followed by a ton of zeros.

Put those together, and you have a binary value of: +1.1E1   (Remember, the leading 1 to the left of the period is implied and not stored.)

Shift that to normalized format and the binary value is: 11.   (And, as everyone knows, 11 = 3.)



And since we can now count from 1 to 3 in SINGLE, take a moment to look at how fractional values are stored:

0 --- 01111111 --- 1100000000000000000000

That first 0 represents that there's no negative sign.  (Toggle it and you'll see that our value swaps to become a -1)
The next 8 bits represent the value of 127; which as I mentioned before is an exponent of 0 PLUS 127.  This gives us an exponent of 0.
The rest of the bits are the mantissa, which in this case are two 1's, followed by all 0's.

Put those together, and you have a binary value of: +1.11E0   (Remember, the leading 1 to the left of the period is implied and not stored.)

In normalized format, that'd look like: 1.11 in binary.

In decimal (base-10) values, what we'd have is:
1 in the one's position.  (left of the period.)
1 in the one half's position.  (first one right of the period.)
1 in the one fourth's position.  (furthermost one on the right.)

Added together 1 + 1/2 + 1/4 = 1.75

1,11 binary (base-2) = 1.75 decimal (base-10)




Play around with it.  If nobody believes that our decimal values are stored as base-2 values after this, I don't know what to tell you.  Apparently I'll never be able to illustrate it, or explain it to the point where it makes sense for that person and they can connect the dots and put it all together.  I've tried, so all I can say is if this doesn't sort it out for you, "Find someone else to explain it and teach it to you."
« Last Edit: July 12, 2021, 05:44:22 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: Floating Point Illustrator
« Reply #1 on: July 16, 2021, 03:50:05 am »
That's a powerful user interface, nice work Steve!