How does C handle the number 0 in a single padding architecture?

Recently I studied the complement system of the representation of numbers and from what I understand there are two options for the number 0. There is a negative zero (-0) and positive zero (+0).

My question is, on which architecture complements how exactly does this anomaly be considered in C? C makes a distinction between -0 and +0, or both of these forms are simply treated as zero.

If it is that both +0 and -0 return TRUE when checking for zero, then I wonder how the following code example will work, which calculates the number of given bits in integers if we enter -0 as our input.

int bitcount(int x) { int b; for (b = 0; x != 0; b++) x &= (x-1); return b; } 

Since -0, in one addition, all its bits set to 1, -0 should return the largest number of bits set from any other number; however, it seems that this code will complete the test condition of the loop x != 0 and not even go into the loop, which will give an incorrect result.

It would be possible somehow in C in architecture with one addition to make the loop condition sensitive to positive zeros, as in: x != +0 Also, if I subtracted 1 from +0, I would get -0 or -1 . In other words, +0 - 1 = -0 in the same complement architecture?

In general, so as not to go too far in this discussion, I just wonder how C considers the features of the number 0 in architecture with the addition.

+3
c ones-complement
Jul 22 '17 at 23:54 on
source share
2 answers

Implementation-specific, whether in a single-add architecture, the value “with a familiar bit and all bits of values ​​1” is a “trap representation” or a normal value. If it is a trap, any attempt to do something with it or even create it primarily causes undefined behavior. If this is a normal value, it is a "negative zero", and there is an explicit list of operations that are allowed to create it:

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

  • operators &, |, ^, ~, <<and → with operands that create such a value;
  • +, -, *, / and% operators, where one operand is negative zero and the result is zero;
  • compound assignment operators based on the above cases.

It is not known whether these cases actually generate negative zero or normal zero, and whether negative zero is a normal zero when stored in an object.

(C11 / N1570, section 6.2.6.2, paragraph 3).

It also seems unspecified (by omission) whether the negative zero is equal to normal zero. Similar rules apply to architecture with signs and values.

So, what it boils down to, the behavior of your sample code is determined by the implementation, and the implementation may not determine it using the service. You will need to consult the compiler and architecture guides for this hypothetical add-on machine to find out if it does what you want.

However, the whole question is controversial, because no one has produced a processor without two-component processors for at least 25 years. It is hoped that a future revision of standard C will no longer allow this possibility; it would simplify many things.

+7
Jul 23 '17 at
source share

To answer your question, there are 2 options to consider:

  • if the bit pattern with all the bits set is a trap representation (which is explicitly permitted by the C standard), passing this value to the function has undefined behavior.

  • if this bit pattern is enabled, this is a one-component representation of negative zero, which should be compared to 0 . In this case, the function recorded will determine the behavior and return 0 , since the initial loop test is false.

The result will be different if the function was written as follows:

 int bitcount32(int x) { // naive implementation assuming 31 value bits int count = 0, b; for (b = 0; b < 31; b++) { if (x & (1 << b)) count++; } } return count; } 

In this one add-on architecture, bitcount32(~0) will be evaluated as 31 :

(x & (1 << b)) with x argument with a specific bit pattern and b in the range for 1 << b to be determined, evaluated to 1 << b , another result value from two additions and the sign / magnitude of the architecture .

Note, however, that the published implementation has undefined behavior for the INT_MIN argument, since x-1 causes a signed arithmetic overflow. It is highly advisable to always use unsigned types for bitwise and shear operations.

0
Sep 25 '17 at 13:32
source share



All Articles