66120

# Best practices for floating-point arithmetics

I was performing addition and subtraction on an input of decimals that are precise to the second decimal place. I tried to improve accuracy by converting them to integers through multiplying 100, but achieved opposite effects.

Consider the following code and output:

```double d = 2.01; int a = (int) (d * 100.0); cout << a << endl; ```

The output is:

```200 ```

Once and for all, what are some of the best practices regarding floating-point arithmetics? Is it at all feasible to first convert the `double` to an `int` using some variant of the code above, and then casting it back?

If you print out the result of `d*100.0` to (say) 20 decimal places, the problem will quickly become apparent:

```200.99999999999997 ```

Since that's (ever so minutely) less than 201, it gets truncated to 200 when you cast to `int`.

The obvious cure is to force rounding. At least if your inputs are all positive that can be as simple as adding 0.5 to the result:

```int a = (int)(d*100.0 + 0.5); ```

If you can count on your compiler supporting it, it's even easier to use the standard library's `round`:

```long a = lround(d*100.0); ```

This works correctly for both positive and negative numbers.

Use the standard math library's rounding functions. In C++ this means you will have to `#include <cmath>` and compile with `-lm`.

```double d = 2.01; long x = lround(d*100); cout << x << endl; // prints 201, for sure. ```

This will be the same as the "add .5" trick, but it will work correctly for positive and negative numbers.

What Every Computer Scientist Should Know About Floating-Point Arithmetic

Floating-point arithmetic is considered an esoteric subject by many people. This is rather surprising because floating-point is ubiquitous in computer systems. Almost every language has a floating-point datatype; computers from PCs to supercomputers have floating-point accelerators; most compilers will be called upon to compile floating-point algorithms from time to time; and virtually every operating system must respond to floating-point exceptions such as overflow. This paper presents a tutorial on those aspects of floating-point that have a direct impact on designers of computer systems. It begins with background on floating-point representation and rounding error, continues with a discussion of the IEEE floating-point standard, and concludes with numerous examples of how computer builders can better support floating-point.

In order to get well defined rouding, I would use floor() and ceil().

So, for the following code,

``` (int)floor( 2.01*100.) ```

I get:

```200 ```

But for:

```(int)ceil(2.01*100.) ```

I get:

```201 ```