1

I am trying to understand this answer here.

How do both these 0xf2 and 0xfffffff2 values represent -14? Can you elaborate with the conversion process?

I know what is Two's complement, though.

Community
  • 1
  • 1
Kevin Rave
  • 13,876
  • 35
  • 109
  • 173
  • *two*'s complement, not Tow's complement... – hyde Nov 13 '12 at 21:28
  • Note that `0xf2 == -14` *only* if your word size is 8 bits, and similarly, `0xfffffff2 == -14` *only* for a 32 bit word size; in addition to the requirement for using twos-complement representation. – twalberg Nov 13 '12 at 21:32
  • In Java, 0xf2 does _not_ represent -14. 0xf2 is not a `byte` constant; an `int` constant, which will have the value 242. Try compiling `byte b = 0xf2;` and you'll get an error. – Ted Hopp Nov 13 '12 at 21:34
  • Perfectly explained here [Two's complement](http://en.wikipedia.org/wiki/Two%27s_complement), i remember it this way: Read a two's complement like a regular binary number, but instead of adding subtract the value of the highest bit. – jlordo Nov 13 '12 at 21:35

3 Answers3

3
0xf2 = 11110010

The first bit is sign-bit. So sign is minus. To get actual value, take 2's compliment.

11110010 -> 1's complement -> 00001101 -> Add 1 -> 00001110 = -14

Similarly, take 0xfffff...f2. Sign bit at the beginning. Take 2's complement.

1111-1111-1111.....0010 -> 1's complement -> 00000000000...1101 -> Add 1 -> 0000...1110 -> -14

Any number of preceding 1111... wouldn't make a difference to the value of a negative signed number, just as 0000.. wouldn't for positive values.


The above calculation is for 8-bit signed 0xf2 against 32-bit signed 0xfffffff2 which are both mathematically equal.

Anirudh Ramanathan
  • 46,179
  • 22
  • 132
  • 191
  • In Java 0xf2 is a (32-bit) `int` value, not an 8-bit byte. If you try `byte b = 0xf2;`, you'll get a compilation error. – Ted Hopp Nov 13 '12 at 21:36
  • @TedHopp This isn't in the Java perspective, but in general. I understand, there is 32-bit granularity with most programming languages, so it wouldn't be a -ve number at all. – Anirudh Ramanathan Nov 13 '12 at 21:37
  • With 32-bit granularity, `0xf2 === 0x000000f2.` (32-bits). But when you compare 8-bit `0xf2` against 32-bit `0xfffffff2`, they are exactly equal. – Anirudh Ramanathan Nov 13 '12 at 21:39
  • 2
    @KevinRave - According to the [Java Language Specification](http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.1): _"An integer literal is of type long if it is suffixed with an ASCII letter L or l (ell); otherwise it is of type int (§4.2.1)._" When you initialize a `byte` variable with an `int` literal, the compiler will try to down-cast the value automatically. However, it will complain if the value doesn't fit. Since 0xf2 (an `int` value of 242 base 10) doesn't fit in a `byte`, you get an error. You need to explicitly cast it: `byte b = (byte) 0xf2;`. – Ted Hopp Nov 13 '12 at 21:47
2

In binary numbers, when using two's complement, negative values have the most significant bit set to 1. Which bit it is, that depends on how many bit number it is.

0xf2 interpreted as 8-bit signed value is -14, while 0xfffffff2 interpreted as 32-bit signed value is same -14.

32-bit 0x000000f2 would be 242, same as unsigned 8-bit 0xf2 (note: Java does not have any unsigned integer types).

hyde
  • 60,639
  • 21
  • 115
  • 176
  • Actually, in Java 0xf2 is 32-bit 242. – Ted Hopp Nov 13 '12 at 21:36
  • @TedHopp Yeah, AFAIK Java does not have byte literals at all, I'll edit the answer to be more clear. – hyde Nov 13 '12 at 21:48
  • @TedHopp Can you point me an article to read more about this 'Granularity' please? – Kevin Rave Nov 13 '12 at 21:53
  • 1
    @KevinRave - Well, "granularity" is not my terminology. In my previous comment to @Cthulhu's answer I linked to the Java Language Specification section that specifies that in Java, integer literals that don't have an "L" (in upper or lower case) at the end are `int` values. That section then links to section 4.2.1, which descibes `int` as ranging from -2147483648 to 2147483647, inclusive. That's the range of a 32-bit representation. The Java Virtual Machine Specification also says that `int` values are 32-bit, signed, two's-complement values. – Ted Hopp Nov 13 '12 at 22:14
  • 1
    @KevinRave - In the post you referenced in your question, it described "the byte 0xf2". This indicates a `byte` (8-bit) primitive that happens to have the hex value 0xf2. My only point is that `0xf2` _as a Java literal_ is _not_ a `byte` value but an `int` value. It's basically a cautionary warning that you can't use 0xf2 (or anything above 0x7f) to initialize a `byte` variable without explicitly casting it to a `byte`. – Ted Hopp Nov 13 '12 at 22:18
  • @TedHopp. Just a quick questions. I understand unsigned `F2` is `242`. But since Java has all signed, shouldn't this be 114 (leaving the most significant bit aka sign bit)? and Actually -114? – Kevin Rave Nov 13 '12 at 22:29
  • 1
    @KevinRave it's two's complement... `0xF2` = `11110010` bin. Negating that, ie. taking two's complement of that is `00001101` bin + 1 = `00001110` bin = 14. – hyde Nov 13 '12 at 22:36
  • 1
    @KevinRave - As an `int` literal, 0xf2 is short for 0x000000f2 (a 32-bit value). The sign bit is not set. As an 8-bit value, hyde covered this in his last comment. – Ted Hopp Nov 13 '12 at 22:39
  • So when we say `x = F2`, then `x` actually has Two's complimented value? – Kevin Rave Nov 13 '12 at 22:42
  • 1
    @KevinRave There are two different things here. One being the width of the field (8 v/s 32 bits) and other being whether it is signed or unsigned. 0xF2 in an 8-bit field is -14 when signed, and 242 when unsigned. 32-bit 0xF2 (equivalent to 0x000000F2) is 242 always(signed/unsigned). 0xFFFFFFF2 in a 32-bit field is -14 when signed and +4294967282 when unsigned. – Anirudh Ramanathan Nov 14 '12 at 09:41
0

How do both these 0xf2 and 0xfffffff2 values represent -14?

They don't.

int a = 0xf2;
int b = 0xfffffff2;

are different values. The only case where they represent the same number is:

byte a = (byte)0xf2;
byte b = 0xfffffff2;

and that's because of sign extension when the byte is used in an integer context. Note that

byte a = 0xf2;

doesn't even compile, so it's hard to see what your question is really about.

user207421
  • 305,947
  • 44
  • 307
  • 483