qnyz
qnyz

Reputation: 469

Any reason to assign -0?

I am going through some old C code using Lint which stumbled upon this line:

int16_t max = -0;

The Lint message is that the "Constant expression evaluates to 0 in operation '-'".

Is there any reason why someone would use -0?

Upvotes: 5

Views: 478

Answers (4)

chux
chux

Reputation: 154280

No reason for it with C99 or later.

int16_t is an exact-width integer type.

The typedef name intN_t designates a signed integer type with width N, no padding bits, and a two’s complement representation. Thus, int8_t denotes such a signed integer type with a width of exactly 8 bits. C11dr §7.20.1.1 1

There is no signed zero with two’s complement. So code is equivalent to

int16_t max = 0;

IMO, the int16_t max = -0; hoped for result, on a non-2's complement platform, was to initialize max to -0 to flag an array of length 0 or one that only contained elements with the value -0.

Upvotes: 0

Joop Eggen
Joop Eggen

Reputation: 109597

That is for an architecture using a CPU with one's complement numbers.

  • Ones complement is a way to represent negative numbers, having a -0. Still in use for floating point.
  • For unsigned numbers the maximal number is indeed -0 : all 1s.

We are accustomed to two's complement numbers, having one negative number more. Though one's complement has some troubles around zero, the same holds for two's complement around MIN_INT: -MIN_INT == MIN_INT.

In the code above probably intended was unsigned numbers:

uint16_t max = (uint16_t) -1;

Upvotes: 0

Theodoros Chatzigiannakis
Theodoros Chatzigiannakis

Reputation: 29223

In the C specification (6.2.6.2 Integer types), it states the following (emphasis mine):

For signed integer types, the bits of the object representation shall be divided into three groups: value bits, padding bits, and the sign bit. There need not be any padding bits; there shall be exactly one sign bit. Each bit that is a value bit shall have the same value as the same bit in the object representation of the corresponding unsigned type (if there are M value bits in the signed type and N in the unsigned type, then M £ N). If the sign bit is zero, it shall not affect the resulting value. 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 -(2N) (two’s complement);
  • the sign bit has the value -(2N - 1) (one’s complement).

Which of these applies is implementation-defined, as is whether the value with sign bit 1 and all value bits zero (for the first two), or with sign bit and all value bits 1 (for one’s complement), is a trap representation or a normal value. In the case of sign and magnitude and one’s complement, if this representation is a normal value it is called a negative zero.

In other words, C supports three different representations for signed integers and two of them have the concept of signed zero, which makes a distinction between a positive and a negative zero.

So, my explanation is that perhaps the author of your code snippet was trying to produce a negative zero value. But, as pointed out in Jens Gustedt's answer, this expression cannot actually produce a negative zero, which means the author may have made a wrong assumption there.

Upvotes: 7

Jens Gustedt
Jens Gustedt

Reputation: 78943

No, I can't see any reason for this. Others have mentioned that it is possible to have platforms with "negative zero", but such a negative zero can never be produced by this expression, so this is useless.

The corresponding paragraph in the C standard is 6.2.6.2 p3, emphasis is mine:

If the implementation supports negative zeros, they shall be generated only by:

— the &, |, ^, ~, <<, and >> operators with operands that produce such a value;

— the +, -, *, /, and % operators where one operand is a negative zero and the result is zero;

— compound assignment operators based on the above cases.

To produce a negative zero on such a platform you could use ~INT_MAX, for example, but that would not be a zero for other representations, so the code wouldn't be very portable.

Upvotes: 4

Related Questions