Paulius Vindzigelskis
Paulius Vindzigelskis

Reputation: 2181

double to int (or long, long long) conversion sometimes is not good

I am trying to convert quite big double number to int (or long or long long), but have some difficulties. Almost always it converts good, but not sometimes:

My code:

double price = 12345678.900000;
double hundredNumber = price * 100;
NSNumber *number = [NSNumber numberWithDouble:hundredNumber];
int tempNumber = [number intValue];

All goes good, until tempNumber. it logs out 1234567889, but it should be 1234567890 (...89 - ...90) Does anyone know why it could happen and how to convert correctly?

P. S. I am trying to implement backspace to value (e.x. 123.45, after that it should be 12.34). Maybe anyone had implemented something like this?

Upvotes: 0

Views: 293

Answers (2)

atxe
atxe

Reputation: 5079

As commented, I would be careful with the roundings, because of the possible errors.

One possible solution is to work with doubles like Google does with coordinates in Android: multiplying them by 1E6. If you operate with integers then you'll safe much more CPU cycle than operating with doubles. Try this out:

double priceDouble = 33.f / 34.f;
NSLog(@"double: %f", priceDouble);

NSInteger priceInteger = (NSInteger)(priceDouble * 1E6);
NSLog(@"int: %d", priceInteger);

NSNumber * priceNumberWithDouble = [NSNumber numberWithDouble:priceInteger];
priceDouble = [priceNumberWithDouble doubleValue];
NSLog(@"double: %f", priceDouble);

NSNumber * priceNumberWithInteger = [NSNumber numberWithInteger:priceInteger];
priceInteger = [priceNumberWithInteger integerValue];
NSLog(@"int: %d", priceInteger);

double test = ((double)priceInteger)/1E6;
NSLog(@"Test: %f",test);

My output is the following:

double: 0.970588
int: 970588
double: 970588.000000
int: 970588
Test: 0.970588

Upvotes: 0

deanWombourne
deanWombourne

Reputation: 38475

You're always going to get the risk of rounding errors if you're using floating point numbers.

Why not always store prices as a long long?

i.e. instead of £5.50, store 550p. That way you will never have any rounding issues at all.

Upvotes: 2

Related Questions