Search code examples
objective-cxcodemultiplication

Multiplying float with 100 sometimes gives a slightly unexpected result in Objective C


So I'm trying to convert the value of UISlider to an integer so I can use it as an index to get a value from an NSArray but multiplying the slider value sometimes gives an unexpected result..

int index = self.moveHistoryLabelSlider.value * 100;

The result's fine for the first few but when it reaches 0.15, it starts to give a different result. Here's an NSLog of the slider.value and slider.value*100:

slider value = 0.150000 slider * 100 = 14.999999

It happens in other float numbers too like 0.19 * 100 gives 19.999998. How do I fix this?


Solution

  • This problem is the nature of Floating Point Numbers (https://floating-point-gui.de/basic/). You can use two simple approaches to minimize rounding error:

    1. Calculate integers instead of floats with needed precision:
    // Float calculation
    float value = 0.15; // 0.150000006
    float multiplier = 100; // 100
    NSLog(@"%f", value * multiplier); // 15.000001
    
    // Convert float to integers and back
    int precision = 100;
    int intValue = value * precision; // 15
    float result = (intValue * (int)multiplier) / (float)precision;
    NSLog(@"%f", result); // 15.000000
    
    
    1. Use NSDecimalNumber for calculation
    NSDecimalNumber* decimalValue = [[NSDecimalNumber alloc] initWithDecimal:@(value).decimalValue]; // 15 x 10^-2
    NSDecimalNumber* decimalMultiplier = [[NSDecimalNumber alloc] initWithDecimal: @(multiplier).decimalValue]; // 10 x 10^2
    NSDecimalNumber* decimalResult = [decimalValue decimalNumberByMultiplyingBy:decimalMultiplier];
    NSLog(@"%f", decimalResult.floatValue); // 15.000000