Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there any (valid) C implementations where float cannot represent the value 0?

If all floats are represented as x = (-1)^s * 2^e * 1.m , there is no way to store zero without support for special cases.

like image 552
user3737289 Avatar asked Oct 27 '14 21:10

user3737289


2 Answers

No, all conforming C implementations must support a floating-point value of 0.0.

The floating-point model is described in section 5.2.4.2.2 of the C standard (the link is to a recent draft). That model does not make the leading 1 in the significand (sometimes called the mantissa) implicit, so it has no problem representing 0.0.

Most implementations of binary floating-point don't store the leading 1, and in fact the formula you cited in the question:

x = (-1)^s * 2^e * 1.m

is typically correct (though the way e is stored can vary).

In such implementations, including IEEE, a special-case bit pattern, typically all-bits-zero, is used to represent 0.0.

Following up on the discussion in the comments, tmyklebu argues that not all numbers defined by the floating-point model in 5.2.4.2.2 are required to be representable. I disagree; if not all such numbers are required to be representable, then the model is nearly useless. But even leaving that argument aside, there is an explicit requirement that 0.0 must be representable. N1570 6.7.9 paragraph 10:

If an object that has static or thread storage duration is not initialized explicitly, then:

  • ...
  • if it has arithmetic type, it is initialized to (positive or unsigned) zero;
  • ...

This is a very long-standing requirement. A C reference from 1975 (3 years before the publication of K&R1) says:

The initial value of any externally-defined object not explicitly initialized is guaranteed to be 0.

which implies that there must be a representable 0 value. K&R1 (published in 1978) says, on page 198:

Static and external variables which are not initialized are guaranteed to start off as 0; automatic and register variables which are not initialized are guaranteed to start off as garbage.

Interestingly, the 1990 ISO C standard (equivalent to the 1989 ANSI C standard) is slightly less explicit than its predecessors and successors. In 6.5.7, it says:

If an object that has static storage duration is not initialized explicitly, it is initialized implicitly as if every member that has arithmetic type were assigned 0 and every member that has pointer type were assigned a null pointer constant.

If a floating-point type were not required to have an exact representation for 0.0, then the "assigned 0" phrase would imply a conversion from the int value 0 to the floating-point type, yielding a small value close to 0.0. Still, C90 has the same floating-point model as C99 and C11 (but with no mention of subnormal or unnormalized values), and my argument above about model numbers still applies. Furthermore, the C90 standard was officially superseded by C99, which in turn was superseded by C11.

like image 175
Keith Thompson Avatar answered Sep 30 '22 19:09

Keith Thompson


After o search a while a found this.

ISO/IEC 9899:201x section 6.2.5, Paragraph 13

Each complex type has the same representation and alignment requirements as an array type containing exactly two elements of the corresponding real type; the first element is equal to the real part, and the second element to the imaginary part, of the complex number.

section 6.3.1.7, Paragraph 1

When a value of real type is converted to a complex type, the real part of the complex result value is determined by the rules of conversion to the corresponding real type and the imaginary part of the complex result value is a positive zero or an unsigned zero.

So, if i understand this right, any implementations where supports C99 (first C standard with _Complex types), must support a floating-point value of 0.0.

EDIT Keith Thompson pointed out that complex types are optional in C99, so this argument is pointless.

like image 43
user3737289 Avatar answered Sep 30 '22 17:09

user3737289