Author Topic: Variable types and 32-bit color values  (Read 2137 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
Variable types and 32-bit color values
« on: December 03, 2020, 09:03:57 am »
I finally sat down and came up with the perfect example to help highlight for folks why they should use UNSIGNED LONG variable types when working with 32-bit color values. 

Copy and run the simple code below:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(640, 480, 32)
  2.  
  3. 'Demo #1 -- why we can't stick to the default SINGLE type
  4. SB = SkyBlue
  5. LINE (0, 0)-STEP(320, 480), SkyBlue, BF
  6. LINE (321, 0)-STEP(320, 480), SB, BF
  7.  
  8. LOCATE 1, 1: PRINT SkyBlue
  9. LOCATE 1, 40: PRINT SB
  10.  
  11.  
  12. 'Demo #2 -- why you should choose UNSIGNED LONG over LONG
  13. CLS , SkyBlue
  14. p = POINT(0, 0)
  15. up = POINT(0, 0)
  16. LOCATE 1, 1: PRINT p, up, POINT(0, 0)
  17. IF p = POINT(0, 0) THEN PRINT "P Matches" ELSE PRINT "P wrong"
  18. IF up = POINT(0, 0) THEN PRINT "UP Matches" ELSE PRINT "UP wrong"

With the first demo, SkyBlue is such a large number, that it exceeds the point of perfect precision with SINGLE-type variables.  By the very nature of real precision, there comes a point where you just can't keep track of minute changes to a value.

1E100 is 1 with 100 0's behind it.  Add 1E50 to it (which is 1 with 50 zeros behind it), and you still have 1E100 -- the value simply isn't big enough to be an increment on our overall rounded total.

With SkyBlue, the value is so large that it gets rounded to become 4287090000 instead of 4287090411.  That loss of precision affects us in such a way that it turns our blue green.  It's fairly obvious that we can't rely on SINGLE variable types to hold a 32-bit color value.



So hit a key and look at the second half of the demo.

We color the whole screen SkyBlue.  We get the color value for a single point on that screen, and we save it as both a LONG and an UNSIGNED LONG.  Then we try and compare it back against the POINT command...

And only the UNSIGNED LONG works.

Once again, the LONG variable type isn't large enough to hold the unsigned value that POINT is returning back to us.  We end up getting overflow, which leads to negative values for us.  Since POINT returns UNSIGNED values, we can't just compare them to SIGNED values and expect them to match all the time.  They don't, and won't -- as illustrated above.

You can probably use DOUBLE or _FLOAT, without any problems, but why would you want to?  They use more memory and generally process slower.  Same with _INTEGER64 and _UNSIGNED _INTEGER64s -- they'll work, but are less efficient and have a larger memory overhead.

If you're working with 32-bit colors, _UNSIGNED LONG is the best variable type to use to assign the values to, hands down.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline NOVARSEG

  • Forum Resident
  • Posts: 509
    • View Profile
Re: Variable types and 32-bit color values
« Reply #1 on: December 07, 2020, 05:38:08 pm »


 Nice feature, as QUICK BASIC did not have any unsigned variables.