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:
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:
Since that's (ever so minutely) less than 201, it gets truncated to 200 when you cast to
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
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
Then, for your example:
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.
Read this and reach enlightenment:
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,