## Section 15. Floating Point

### 15.1: My floating-point calculations are acting strangely and giving me different answers on different machines.

First, make sure that you have #included `<math.h>`, and correctly declared other functions returning `double`.

If the problem isn't that simple, recall that most digital computers use floating-point formats which provide a close but by no means exact simulation of real number arithmetic. Underflow, cumulative precision loss, and other anomalies are often troublesome.

Don't assume that floating-point results will be exact, and especially don't assume that floating-point values can be compared for equality. (Don't throw haphazard "fuzz factors" in, either.)

These problems are no worse for C than they are for any other computer language. Floating-point semantics are usually defined as "however the processor does them;" otherwise a compiler for a machine without the "right" model would have to do prohibitively expensive emulations.

This article cannot begin to list the pitfalls associated with, and workarounds appropriate for, floating-point work. A good programming text should cover the basics.

References: EoPS Sec. 6 pp. 115-8.

### 15.2: I'm trying to do some simple trig, and I am #including `<math.h>`;, but I keep getting "`undefined: _sin`" compilation errors.

Make sure you're linking with the correct math library. For instance, under Unix, you usually need to use the` -lm `option, and at the end of the command line, when compiling/linking. See also question 12.14.

### 15.3: Why doesn't C have an exponentiation operator?

Because few processors have an exponentiation instruction. Instead, you can `#include <math.h>` and use the `pow()` function, although explicit multiplication is often better for small positive integral exponents.

References: ANSI Sec. 4.5.5.1 .

### 15.4: How do I round numbers?

The simplest and most straightforward way is with code like

```        (int)(x + 0.5)
```

This won't work properly for negative numbers, though.

### 15.5: How do I test for IEEE NaN and other special values?

Many systems with high-quality IEEE floating-point implementations provide facilities (e.g. an isnan() macro) to deal with these values cleanly, and the Numerical C Extensions Group (NCEG) is working to formally standardize such facilities. A crude but usually effective test for NaN is exemplified by

```        #define isnan(x) ((x) != (x))
```

although non-IEEE-aware compilers may optimize the test away.

### 15.6: I'm having trouble with a Turbo C program which crashes and says something like "floating point formats not linked."

Some compilers for small machines, including Turbo C (and Ritchie's original PDP-11 compiler), leave out floating point support if it looks like it will not be needed. In particular, the non-floating-point versions of printf and scanf save space by not including code to handle `%e`, `%f`, and `%g`. It happens that Turbo C's heuristics for determining whether the program uses floating point are insufficient, and the programmer must sometimes insert an extra, explicit call to a floating-point library routine to force loading of floating-point support.