Hello,
The conversion of -1 to binary or hexadecimal is returning -1, is this normal?
val = -1
val.to_s(2) or val.to_s(16) is returning -1, while everywhere I look they use the 2-complement (for instance -1 in the windows calc gives FFFF FFFF FFFF FFFF)
Ruby also gives -1
. I think FFFF FFFF FFFF FFFF
meaning both -1 and 18446744073709551615 is confusing. I guess that if you want negative numbers to be converted like that you can do it yourself. The question is: how many "F"s do you want? Of course it depends on the type… but again, I think it’s not clear that -1
should be FFFF FFFF FFFF FFFF
because it’s not bijective: if you want to go back to the original value from that you have no idea which value was it.
1 Like
base 16 and binary representation are different things.
https://crystal-lang.org/api/0.30.1/IO/ByteFormat.html might help if you want to deal with the later.
Personally I think it is a bit strange that (-1).to_s(2) does not give the binary representation of -1 but if Ruby is doing the same then it is better to stick with this.
For how many ‘F’ I want, it would depend on the type of -1 (int32 or int64 for instance).
I can get what I want by doing this: (0_u32 -1).to_s(16), but it would be better to have something that works for any integer type.
You’re actually mixing up two completely different concepts.
A binary number is just a number expressed in base-2 notation. Apart from the digits, everything else is exactly the same as in other number systems like decimal or hexadecimal. For example, negative numbers are obviously prefixed by a minus sign.
The decimal number -1
expressed as binary number is also just -1
. The hexadecimal value FFFF FFFF FFFF FFFF
is just a simple number, equivalent to decimal 18446744073709551615
.
These conversions are all handled by .parse
and #to_s
methods on Crystal’s number types.
When you expect FFFF FFFF FFFF FFFF
to mean -1
, you’re actually talking about a integer data type representation which uses the two’s complement to encode a signed number. This is just a specific data format used to represent arbitrary values (in this case: a signed integer) as binary data.
This encoding is usually handled by Crystal internally and you don’t actually see it, but it can be explicitly used with the IO::ByteFormat
type.
2 Likes