11

Why does 0x1p3 equal 8.0? Why does 0x1e3 equal 483, whereas 0x1e3d equals 7741? It is confusing since 1e3d equals 1000.0.

The Guy with The Hat
  • 10,836
  • 8
  • 57
  • 75
serious
  • 271
  • 2
  • 7
  • @marcog this is part of a way to express floating point numbers, see the JLS: http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.2 – Jesper Dec 28 '10 at 13:53
  • @marcog: that's the exponent marker for a hexadecimal floating point literal, as defined in the Java and C99 standards. – Stephen Canon Dec 29 '10 at 23:20

2 Answers2

10

0x1e3 and 0x1e3d are hexadecimal integer literals. Note that e and d are hexadecimal digits, not the exponent indicator or double type indicator in this case.

1e3d is a decimal floating-point literal. The e is the exponent indicator, the d says that this is a double rather than a float.

The notation 0x1p3 is a way to express a floating-point literal in hexadecimal, as you can read in section 3.10.2 of the Java Language Specification. It means 1 times 2 to the power 3; the exponent is binary (so, it's 2-to-the-power instead of 10-to-the-power).

Line
  • 1,529
  • 3
  • 18
  • 42
Jesper
  • 202,709
  • 46
  • 318
  • 350
  • But 0x1p3 should be as same as 1e3 in this case, right? But they are not. – serious Dec 28 '10 at 14:02
  • @serious No, because the exponent is binary, not decimal. Its 2^3 not 10^3. – Jesper Dec 28 '10 at 14:02
  • Btw, is there any reason why it is binary? I mean, why it is not base of 16? – serious Dec 28 '10 at 14:05
  • Base 16 (hex) is a human construction to help us manage long strings of bits without going mad. In a computer, it's all binary - there's no hex. Note that one binary nybble (4 bits) maps directly to 1 hex digit. So the byte 11010111 becomes (1101)(0111) = 0xD7. – Tony Ennis Dec 28 '10 at 14:24
  • Yes, but in the 1e3 notation exponent is decimal. – serious Dec 28 '10 at 14:30
  • in 0x1e3 there is no exponent. That's an integer. – Tony Ennis Dec 28 '10 at 14:42
  • Sorry, I meant 0x1p3d which contains binary exponent (as mentioned before by Jesper) as opposite to 1e3d with "decimal" exponent. – serious Dec 28 '10 at 14:56
  • I don't know why with the p-notation the exponent is binary. This notation is something that Java inherited from C or C++. It's hard to find out after the fact why someone somewhere long ago thought this would be a useful feature... – Jesper Dec 28 '10 at 15:48
  • @serious, you're getting your terminology and representations mixed up. 1e3d doesn't mean the 3 is in decimal. According to jesper, it means the value is a _double_. If this isn't what you meant, then the confusion might be that the default representation in Java is decimal. So 1e3 is 1000 base 10. 0x1p3 is 8 since the 0x means "this representation is in hex". The reason 'e' is not used for the hex floating point exponent is that it probably leads to an ambiguous situation - 'e' is a valid hex digit, 'p' is not. Thus 'p' is never ambiguous. – Tony Ennis Dec 28 '10 at 16:24
  • Checking the spec linked waaay above, we see that if 'e' were allowed to denote a floating point literal's exponent, then 0x1e3 would be ambiguous. Is it the integer 483 or is it the floating point 8? The (perhaps ham-handed) 'p' removes this ambiguity. – Tony Ennis Dec 28 '10 at 16:31
  • @Jesper: It's an extraordinarily useful feature, whether or not you see a use for it. In particular, it makes it quite easy straightforward to exactly specify a floating point constant without any rounding. – Stephen Canon Dec 29 '10 at 23:23
2

0x1e3 is hex for 483, as is 0x1e3d hex for 7741. The e is being read as a hex digit with value 14.

moinudin
  • 134,091
  • 45
  • 190
  • 216
  • 1
    Ah, 0x1e3 is a hex number, so "e" doesn't mean an exponent here. – serious Dec 28 '10 at 13:58
  • 1
    @serious, the difference is that 0x1e3 is an integer, not a floating point number. The 'e' in that integer is just an unfortunate coincidence that confuses. 0x1p3 is a floating point number. It is interpreted _very_ differently. The interpretation includes a _mantissa_ and an _exponent_. The former is the 1.0 part (note the assumed decimal point.) The latter is the 'p3' part which which reads 'to the 3rd power.' Since we're in binary, taking a number to to the 3rd power is the same as shifting it 3 bits to the left, so the 0b1 becomes 0b1000. That's 8 in decimal. – Tony Ennis Dec 28 '10 at 14:38