CrossWorks C allows you to choose whether the double data type uses the IEC 60559 32-bit or 64-bit format. The following sections describe the details of why you would want to choose a 32-bit double rather than a 64-bit double in many circumstances.

##### Why choose 32-bit doubles?

Many users are surprised when using float variables exclusively that sometimes their calculations are compiled into code that calls for double arithmetic. They point out that the C standard allows float arithmetic to be carried out only using float operations and not to automatically promote to the double data type of classic K&R C.

This is valid point. However, upon examination, even the simplest calculations can lead to double arithmetic. Consider:

    // Compute sin(2x)
    float sin_two_x(float x)
    {
      return sinf(2.0 * x);
    }

This looks simple enough. We're using the sinf function which computes the sine of a float and returns a float result. There appears to be no mention of a double anywhere, yet the compiler generates code that calls double support routines—but why?

The answer is that the constant 2.0 is a double constant, not a float constant. That is enough to force the compiler to convert both operands of the multiplication to double format, perform the multiplication in double precision, and then convert the result back to float precision. To avoid this surprise, the code should have been written:

    // Compute sin(2x)
    float sin_two_x(float x)
    {
      return sinf(2.0F * x);
    }

This uses a single precision floating-point constant 2.0F. It's all too easy to forget to correctly type your floating-point constants, so if you compile your program with double meaning the same as float, you can forget all about adding the 'F' suffix to your floating point constants.

As an aside, the C99 standard is very strict about the way that floating-point is implemented and the lattitude the compiler has to rearrange and manipulate expressions that have floating-point operands. The compiler cannot second-guess user intention and use a number of useful mathematical identities and algebraic simplifications because in the world of IEC 60559 arithmetic many algebraic identities, such as x * 1 = x, do not hold when x takes one of the special values NaN, infinity, or negative zero.

##### More reasons to choose 32-bit doubles

Floating-point constants are not the only silent way that double creeps into your program. Consider this:

    void write_results(float x)
    {
      printf("After all that x=%f", x);
    }

Again, no mention of a double anywhere, but double support routines are now required. The reason is that ISO C requires that float arguments are promoted to double when they are passed to the non-fixed part of variadic functions such as printf. So, even though your application may never mention double, double arithmetic may be required simply because you use printf or one of its near relatives.

If, however, you compile your code with 32-bit doubles, then there is no requirement to promote a float to a double as they share the same internal format.

##### Why choose 64-bit doubles?

If your application requires very accurate floating-point, more precise than the seven decimal digits supported by the float format, then you have little option but to use double arithmetic as there is no simple way to increase the precision of the float format. The double format delivers approximately 15 decimal digits of precision.