Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correcting floating point numbers

I am wondering if there is a way that you can easily and safely correct floating point numbers.

For example,

When entered: " 32 + 32.1 " Result: "64.0999999999999"

Also I must mention that this occurs quite frequently when using scientific notation. " ( 2.3 * 10^23)*(1.452 * 10^23) " Returns: " 3.339599999999999999e+46"

And finally, sometimes the number that is returned is: ex. 123.0000000000001

Thanks for the help!

EDIT

The answer that was approved is great. But what I found worked for me was using %g with a double in NSString stringWithFormat. %g seems to round everything quite appropriately. ex.

    answer.text = [NSString stringWithFormat@" %g ", doubleAnswer];

Using doubles through your calculations and then using that method seemed to work for me, and I hope this helps others as well. If this isn't the answer your looking for, check out the approved answer!

like image 955
Neil Avatar asked Apr 06 '12 21:04

Neil


People also ask

How do you mitigate floating point errors?

One method to reduce high floating-point errors is to use higher precision to perform floating- point calculation of the original program. For example, one may replace a 32-bit single precision with a 64-bit double precision to improve the accuracy of results.

How can you make a floating point more accurate?

To make floating point operations more accurate, you need more bits in Floating point unit in CPU an for storing the result. There are 32 and 64 bit floating point format, but since the cooprocessor 287 there is also 80 bit format giving better accuracy.

What is the main problem with floating point numbers?

The Problem Since real numbers cannot be represented accurately in a fixed space, when operating with floating-point numbers, the result might not be able to be fully represented with the required precision. This inaccuracy ends up as information lost.

Why do computers mess up floating point math?

Because JavaScript uses the IEEE 754 standard for Math, it makes use of 64-bit floating numbers. This causes precision errors when doing floating point (decimal) calculations, in short, due to computers working in Base 2 while decimal is Base 10.


2 Answers

Floating point numbers do not represent specific numbers very well. Using double's will make this happen less often but you will still have the problem. For a technical description of how floating point numbers are stored (and why we have this problem in the first place) see this wikipedia article: IEEE 754-1985. (Basically, floats are stored as a binary representation of the value and only have so many bits to use, so they quickly run out and have to round to the nearest value that they are capable of representing.)

Typically you don't worry about the +/- .0000001 and just format them when you want to display them to the user with the appropriate number of decimal points and it will get rounded. Internally it doesn't really matter how it is stored though.

For instance, if you want to display the "result" you can do something like this:

float myFloat = 32 + 32.1;
NSString *result = [NSString stringWithFormat:%@"%.2f", myFloat];
// result will contain 64.10

If you don't want a fixed number of decimal points, you can also use the float to string conversion capability of NSNumber:

float myFloat = 32 + 32.1;
NSNumber *myNumber = [NSNumber numberWithFloat:myFloat];
NSString *result = [myNumber stringValue];
// result will contain 64.1

NSDecimalNumber will take care of all of this for you, but it a little more involved and involves more overhead but here's an example to get you started:

NSDecimalNumber *num1   = [NSDecimalNumber decimalNumberWithString:@"32"];
NSDecimalNumber *num2   = [NSDecimalNumber decimalNumberWithString:@"32.1"];
// Or since you use exponents:  
// NSDecimalNumber *num2   = [NSDecimalNumber decimalNumberWithMantissa:321 exponent:-1 isNegative:NO];

NSDecimalNumber *myNumber = [num1 decimalNumberByAdding:num2];
NSString *result = [myNumber stringValue];
// result will contain 64.1
like image 108
lnafziger Avatar answered Sep 28 '22 09:09

lnafziger


You can't "correct" a floating point number because floating point numbers simply cannot represent the number you want.

Floating point numbers are remarkably imprecise and, generally, shouldn't be used for anything that involves lots of calculations because the cumulative error is often catastrophically bad.

Use a double instead. They can represent a much greater range of values and, as a result, can represent many more values quite precisely. If that isn't good enough, you'll need to move to something with more precision. Possibly NSDecimalNumber.

like image 42
bbum Avatar answered Sep 28 '22 08:09

bbum