I understand this may be a silly question, but I’m curious if I missed something in researching for an approach to have both a signed and unsigned version of a value in a type. I expect the answer to my question to be no, given that the max value of say an i32 and an u32 is different (i.e. they both have the same memory size, but u32 does not use the first bit for a sign, so it can have a higher value, etc…)
I have a need to maintain a signed value for internal functionality, but need to display it’s absolute value in various places. Additionally I need to provide the absolute value to a vendor library as a pointer. Currently I’m doing alot of back and forth managment with multiple variables using the abs function, which is fine, but my geeky side was wanting to make this more streamlined.
I’ve tried the following, which understandably does not work. I wonder though, is there a way for the signed bit to be preserved in the i32, and for the u32 to keep the signed bit as 0, so that I can update either and the other reflect the same value but as their respective type as signed or unsigned?
Because -1 is stored in two’s complement - and as such has the sign bit set.
If you want to preserve information external to the i32 / u32 - you need to do so manually.
The most significant bit isn’t just a negation bit. That would be ones complement arithmetic, which isn’t how integers generally work. Instead, it’s twos complement arithmetic, meaning that the value of the most significant bit is effectively negated.
For example, -1 as an i8 isn’t 0b10000001/0x81 (i.e. 1 but with the most significant bit set), it’s 11111111/0xff (all bits set), as in -128 + 127, where the most significant bit is the -128. Taking the absolute value isn’t just “clear the most significant bit”. That’s why i32(-1) casts into max(u32)–that’s the unsigned value with the same bit pattern.
Floats do use the “most significant” bit as a pure negation bit, though.
This explains perfectly well why this is more complicated a wish than it appears on the surface. I had a feeling this was the case. I’ve worked with floats more than ints in my life and got it stuck in my head that they were handled the same. An old dog can relearn old tricks.
Now I wonder if a bit_field with bit shifting could be used for such a purpose? I don’t have much experience using bit_fields, so not sure how to start hacking that out.