What are C++ Standard guarantees on relation between min and max values of signed integer types?
Asked Answered
C

2

6

Is it safe to assume that -LLONG_MAX (negated LLONG_MAX) belongs to long long range?

Is it safe to assume that if LLONG_MIN < -LLONG_MAX then LLONG_MIN == -LLONG_MAX - 1?

Is it guaranteed by the Standard or just all actual devices provide either LLONG_MIN == -LLONG_MAX - 1 or LLONG_MIN == -LLONG_MAX?

Cerveny answered 19/7, 2016 at 18:38 Comment(4)
Share your research.Drachma
@code0 What research? The OP wants to know if his conjecture is standard compliant.Cyd
@code0 could not find relationship between MIN and MAX of signed integer types neither in C++11 standard draft nor in C11 standard draft. Maybe I missed something.Cerveny
Thank you. I'm watching this post.Drachma
A
3

Is it safe to assume that -LLONG_MAX (negated LLONG_MAX) belongs to long long range?

Is it safe to assume that if LLONG_MIN < -LLONG_MAX then LLONG_MIN == -LLONG_MAX - 1?

Is it guaranteed by the Standard or just all actual devices provide either LLONG_MIN == -LLONG_MAX - 1 or LLONG_MIN == -LLONG_MAX?


Those three statements are true in the case the implementation uses one of 2's complement, 1's complement, or sign and magnitude to represent signed integer types. -LLONG_MAX is in the range of long long in all three schemes, and LLONG_MIN is -LLONG_MAX (1's complement, sign and magnitude, and possibly 2's complement) or is -LLONG_MAX-1 (possibly 2's complement). 2's complement machines might use that extra value as a trap representation, just as 1's complement and sign and magnitude machines might use negative zero as a trap representation. So the answer to your questions is "yes" if the standard mandates that an implementation use one of those schemes.

The C standard (to which the C++ standard defers in many places) mandates either 2's complement, 1's complement, or sign and magnitude:

C11 6.2.6.2 Integer types:

If the sign bit is one, the value shall be modified in one of the following ways:

— the corresponding value with sign bit 0 is negated (sign and magnitude);
— the sign bit has the value −(2M ) (two’s complement);
— the sign bit has the value −(2M − 1) (ones’ complement).

The C++ standard appears to be a bit more open:

C++14 3.9.1 Fundamental types:

The representations of integral types shall define values by use of a pure binary numeration system51. [Example: this International Standard permits 2’s complement, 1’s complement and signed magnitude representations for integral types. —end example]

Footnote 51, which defines what "a pure binary numeration system" means, appears to rule out decimal systems, and also offset systems (where 0 isn't all bits zero):

51) A positional representation for integers that uses the binary digits 0 and 1, in which the values represented by successive bits are additive, begin with 1, and are multiplied by successive integral power of 2, except perhaps for the bit with the highest position.

Practically speaking, all that's left are 2's complement, 1's complement, and sign and magnitude: The same schemes mandated by the C standard. I doubt a vendor would touch a machine that uses a new 21st century scheme to represent the integers and somehow meets the letter of the law of the C++ standard (but hence is noncompliant with C).

Aptitude answered 19/7, 2016 at 20:3 Comment(5)
Have I understood right? Practically speaking, this is true, but theoretically if two values with top bit 1 are reserved for special values such as "not initialized" and "error" then the range of negative numbers can be less than the range of positive numbers.Cerveny
@FyodorMenshikov - You read it wrong (or I wrote it wrong). With each of those three schemes, there's one value that doesn't quite fit in. With 1's complement and sign-magnitude, it's negative zero. (The IEEE floating point representation also has negative zero, but that standard has specific rules about how to deal with negative zero.) With 2's complement, that extra value is -LLONG_MAX-1. Using that as a trap representation would mean that LLONG_MIN is -LLONG_MAX, same as in the other two schemes.Aptitude
Can theoretically there be the 4th scheme that differs from one of these only in one extra negative value reserved? Maybe reserved not on the level of hardware but on the level of compiler.Cerveny
@FyodorMenshikov -- Google Protocol Buffers, but they're used for transporting data between processes and processors. It uses sign- magnitude, but in a weird way. Most numbers are small. (It's amazing how much can be saved in serialization simply by not recording all the zeros that are in memory, and making sure objects are zero-initialized prior to populating them with deserialized data.) Google went a step further. There's no reason to use 32 bits to represent 42 (for example), so they don't.Aptitude
IIRC, trap representations are allowed for non-char types. These are effectively independent from the binary representation scheme. That is to say, 2's complement only tells you what the value of a specific bit pattern would be, not whether that bit pattern actually represents a value.Allfired
L
0

No. The Standard does not prescribe two's complement integer representation.

That said, the vast majority of C and C++ implementations are on 2's comp machines.

Lozoya answered 19/7, 2016 at 18:44 Comment(4)
The question addresses 2's complement, 1's complement, and signed magnitude.Aptitude
OP specifically asks the same question three times: is this 2's comp relationship safe and guaranteed? The answer is no.Conflation
Read the last item again: LLONG_MIN == -LLONG_MAX is not true on 2's complement machines.Aptitude
@Lozoya the question has two sides. 2. Is there any device that is neither 1's complement nor 2's complement? 1. Is it guaranteed by the Standard that min and max of signed types are in the same relationship as in 1's complement or 2's complement implementation?Cerveny

© 2022 - 2024 — McMap. All rights reserved.