XZ_iOS about double/float data calculation accuracy

1. Our app has a judgment. When the value entered by the user is less than or equal to the remaining balance, a pop-up window will be given to the user, and the code will not be executed.
When the user enters 0.01, the result of po is: 0.10000.... When the user's balance is 0.01, the return result of the network request of po is: 0.009999...

When the user enters 66.05, the result of po is: 66.049999..., when the user's balance is 66.05, the return result of the network request is: 66.049999...
Therefore, when the data is large, it will not have an impact, because the data input by the user and the data returned by the network are changed into inaccurate small values; however, when the data is small, the data input by the user is not transferred, and the network The returned data is converted into an inaccurate small value, which causes the user input to always be greater than the data returned by the network, and the code cannot be executed;

Solution: Use NSDecimalNumber to convert float and double data into objects of type NSDecimalNumber for +, -, *, / calculations, and then get the value.
- (double)DecimalNumber:(double)num1 num2:(double)num2  {
    
    NSDecimalNumber *n1 = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%f",num1]];
    
    NSDecimalNumber *n2 = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%f",num2]];
    
    NSDecimalNumber *n3 = [n1 decimalNumberBySubtracting:n2];
    
    return n3.doubleValue;
}
// transfer:
double result = [self DecimalNumber: 2.01 num2: 2]; // result is 0.01

in:

decimalNumberBySubtracting: n1 - n2, returns the result value of n1 - n2
decimalNumberByMultiplyingBy:n1 * n2,
decimalNumberByDividingBy:n1 / n2,
decimalNumberByAdding:n1 + n2,
compare: compare n1 and n2, and return the comparison result;

2. Round off the data to get the result
- (NSString*)Rounding:(float)number afterPoint:(NSInteger)position
{
    NSDecimalNumberHandler *handler = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode: NSRoundPlain scale: position raiseOnExactness: NO raiseOnOverflow: NO raiseOnUnderflow:NO raiseOnDivideByZero: NO];
    
    NSDecimalNumber * floatDecimal = [[NSDecimalNumber alloc] initWithFloat: number];
    
    NSDecimalNumber * resultNumber = [floatDecimal decimalNumberByRoundingAccordingToBehavior: handler];
    
    return [NSString stringWithFormat:@"%@",resultNumber];
}
// transfer:
NSString *result = [self Rounding:8.00092 afterPoint:3]; // result is 8.001
Among them, the parameter number is the data that needs to be rounded, and the position is the number of digits reserved after the decimal point;

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325918341&siteId=291194637