Hex literals, a compiler error, or a poorly written spec?

Scala spec says

1.3.1 Integer Letters

Syntax:

integerLiteral ::= (decimalNumeral | hexNumeral | octalNumeral) ['L' | 'l'] decimalNumeral ::= '0' | nonZeroDigit {digit} hexNumeral ::= '0' 'x' hexDigit {hexDigit} octalNumeral ::= '0' octalDigit {octalDigit} digit ::= '0' | nonZeroDigit nonZeroDigit ::= '1' | · · · | '9' octalDigit ::= '0' | · · · | '7' 

Integer literals are usually of type Int or type Long, followed by L or L suffix. Values ​​of type Int are integers between -2 31 and 2 31 -1 inclusive. Values ​​of type Long are integers between -2 63 and 2 63 -1 inclusive. A compile-time error occurs if an integer literal denotes a number outside these ranges

Last time, I checked 0x80000000 equal to 2147483648, which should be out of range for Int ("between -2 31 and 2 31 -1 inclusive").

However, the compiler does not complain, but instead translates the integer to -2147483648.

So, the wrong specification, the wrong compiler, or didn’t I understand something?

Edit: The same number written in decimal is processed correctly and generates an error.

+4
source share
3 answers

The most significant bit in the integer character is used to indicate the character, and not the high power 2 - so everything with this set of bits will be a negative, not a positive number. A two-component form is used , which means that 0x8000000 is really -2147483648.

To your reign: the same number written in decimal is -2147483638, not +2147483638, for the same reason.

+3
source

As dave pointed out, Scala's behavior in this regard is identical to Java. "

This makes me think that Scala chose a Java interpretation for integer literals.

This is very well described in the Java Language Specification, Section 3.10.1 Integer Literals :

The largest positive hexadecimal and octal literals of type int are 0x7fffffff and 017777777777 , 017777777777 , which are 2147483647 (2 31 -1). The most negative hexadecimal and octal literals of type int are 0x80000000 and 020000000000 respectively, each of which represents the decimal value -2147483648 (-2 31 ). The hexadecimal and octal literals 0xffffffff and 037777777777 , respectively, represent the decimal value -1. A.

In general, I would say that the specification implicitly inherits the Java specification for parts that are equal and seemingly obvious, and appears only in parts that (may) differ, such as syntax (the language is ultimately syntactically very different from Java).

+2
source

Unsigned hexadecimal numbers between 2 31 and 2 32 -1 are silently converted to negative numbers corresponding to their binary representation for Int . Negative numbers in this range (except -2 31 ) are silently converted to their complement-2, which turns into positive numbers. For Long , the equivalent rule applies. IMHO, the spec should say so, but I have not tested whether this is or not.

The compiler complains about numbers outside this range.

+1
source

Source: https://habr.com/ru/post/1395580/


All Articles