iOS Question Why is "0xFF000000" equal to -16777216?

Mike1970

Well-Known Member
Licensed User
Longtime User
Hi everyone I'm using hex numbers to be comfortable with colors... I needed to add the Alpha channel to RGB color code.. for example
B4X:
dim rgb_color as int = 0xFF0000
dim rgba_color as int = rgb_color + 0xFF000000

this code does not work because "0xFF000000" is recognized as -16777216, do you know why?

In order to get it working I had to use the integer value -> 4278190080 instead of 0xFF000000... but it is ugly :(
 

William Lancee

Well-Known Member
Licensed User
Longtime User
As @Johan Schoeman said...

Signed integers range from -2147483648 to 2147483647
B4X:
    Log(0x7FFFFFFF) '2147483647
    Log(0x80000000) '-2147483648

    Log(0xFFFFFFFF)  '-1

To add/modify an opacity value, just use this
B4X:
    Dim c(3) As Int
    c(0) = Bit.And(0xff, Bit.UnsignedShiftRight(Color, 16))
    c(1) = Bit.And(0xff, Bit.UnsignedShiftRight(Color, 8))
    c(2) = Bit.And(0xff, Bit.UnsignedShiftRight(Color, 0))
    Dim newColor As Int = xui.Color_ARGB(opacity, c(0), c(1), c(2))
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
The beauty of 2's complement is that if you start at the minimum and keep on adding 1, you'll eventually get to 0xFFFFFFFF = -1
Now if you add 1 you get 0x0100000000 which in a 32 bit window is 0x00000000 = 0
Then you keep on adding 1 until you get to 0x7FFFFFFF which is the maximum.
If you add 1 more it starts all over again at 0x80000000 which is the minimum.
Don't you love Math?

On the way from 0x80000000 to 0xFFFFFFFF you pass 0xFF000000 = -16777216
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
this code does not work because "0xFF000000" is recognized as -16777216, do you know why?
How does this code not work?
B4X:
    Dim rgb_color As Int = 0xFF0000
    Dim rgba_color As Int = rgb_color + 0xFF000000
    Log(rgba_color)
    Log(Bit.ToHexString(rgba_color))
Output:
-65536
ffff0000
What does it matter that it is -65536 as long as the bits are set correctly to ffff0000. Don't look at the power of 10 representation, look at the hex representation of the value to determine if the bits are set correctly. Signed/unsigned does not change the bit value of the number itself.
 
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
Thank you all for answers :D

Don't look at the power of 10 representation
I answer Oliver on this observation but it is for everyone.

I need to look at the power of 10 representation because the app is connected to an ESP32 that sends HEX color code of some LEDs, in its power of 10 representation.

Long story short:
I'm using BLE on the ESP32, and for convenience it sends the power of 10 representation of the HEX color code (RGB, not RGBA) through the BLE characteristic, in this way I do not have to parse strings to pass from 0xFF00FF to actual number usable in its code, and also on B4X.
Less conversions.

Also I need to perform some checks on B4X like:
B4X:
'c is the color read from BLE (power of 10)'

If c = Colors.Transparent Then
    c = 0x3CFFFFFF    'set this default gray color'
   
Else if c < 0xFF000000 Then    'if the Alpha channel is not present in the color
    c = Bit.Or(c, 0xFF000000)     'i add it fully opaque -> 255'
End If

in this case the "Else If" does not work because, as I understood now, it is correct that 0xFF000000 is negative (I tought i would be represented as a UINT), so the checks fails even if the desired behaviour was the opposite.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
I need to look at the power of 10 representation
Not really, you (currently) need to look at bits, in this case, if some bits are set
Else if c < 0xFF000000 Then
Can be done with
B4X:
Else If Bit.And(c, 0xFF000000) = 0 Then ' If no upper bits are set, the AND'ing will return 0
Or
B4X:
Else If c = Bit.And(c, 0x00FFFFFF) Then ' If no upper bits are set, then c and the AND'ing will be the same (the AND'ing strips out the upper bits)
So here we just use Bit methods and equality and could not care less about signedness of c.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Thank you but if I need to have the values ranging from 0 to 16777215 (#000000 to #FFFFFF) without Alpha?
What is the problem here? To strip out the alpha you can do:
B4X:
'Where color is an Int
color = Bit.And(color, 0x00FFFFFF)
 
Last edited:
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
What is the problem here? To strip out the alpha you can do:
B4X:
'Where color is an Int
color = Bit.And(color, 0x00FFFFFF)
Ok. Thanks for that

The problem is that I need the unsigned decimal representation of the color in order to be able to send it over BLE to my Esp32.

Not the 2’s complement. since B4X supports Long data type it should be possible
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
unsigned decimal representation of the color in order to be able to send it over BLE to my Esp32.
I'm trying to tell you that it does not matter. What you are sending the printer is 32 bits. Don't matter signed or unsigned. It's 32 bits
 
Upvote 0

emexes

Expert
Licensed User
I'm trying to tell you that it does not matter. What you are sending the printer is 32 bits. Don't matter signed or unsigned. It's 32 bits
an ESP32 that sends HEX color code of some LEDs, in its power of 10 representation.

I agree that the problem description started out a bit hazy, but...

if the 32-bit value is being sent to printer in decimal ("power of 10") and one end is treating it as signed -2B to +2B and the other is treating it as unsigned 0 to 4B,

then maybe it might matter.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
if the 32-bit value is being sent to printer in decimal ("power of 10") and one end is treating it as signed -2B to +2B and the other is treating it as unsigned 0 to 4B,

then maybe it might matter.
It only matters if the side that uses signed bits does more than bit manipulations. Otherwise, bits are bits. As to power of 10, power of 16 (Hex) or any of that, that only matters (of the top of my head) for display purposes or if you want to send the information to the ESP32 in string format. At that time, the same 32 bits may be displayed / converted to string in different ways. Again, in just this specific case, I think the OP can directly work with the 32 bits and use Bit functions to manipulate the bits and only worry about B4X's bit-ness when shifting right (depending on case). But nowhere is the bit-ness encoded in the 32 bits and neither machine will suddenly complain about receiving incorrect bit-ness.

In the end it all depends on the interpretation of this:
'c is the color read from BLE (power of 10)'
I'm reading it as the OP is getting 32 bits of information from the ESP. If the OP is receiving a string (and later sending a string) with numeric content in base 10, then I'm slightly off base.
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
If you want a base 10 representation of a 4 element color or
the unsigned long equivalent of the bits in an Int , you could use

B4X:
    Log(Bit.AndLong(0x00000000FFFFFFFF, xui.Color_White))    '4294967295
 
Upvote 0
Top