zoukankan      html  css  js  c++  java
  • OC,iOS浮点型数据的计算不正确问题

    举个例子,有时候float类型的数据参与计算的时候,如果要求精度高的话,往往可能出现各种各样特别神奇的问题,所以NSDecimalNumber 应运而生。NSDecimalNumber继承自NSNumber,用于对浮点型数据的精度计算

    举个例子

            float a = 10.33;
            float b = 10.3;
            NSLog(@"a * b = %f",a * b);
            NSLog(@"a + b = %f",a + b);
    

    解决方案

    第一种解决方案

    如果准确的知道最大的小数保留位数,可以先去整,在计算,比方一下的方法

            float a = 10.33;
            float b = 10.3;
            float c = (a * 100) * (b * 100);
            float d = a * 100 + b * 100;
            NSLog(@"a * b = %f",c / 10000.0);
            NSLog(@"a + b = %f",d / 100.0);
    

    第二种解决方案

       NSDecimalNumber *a = [NSDecimalNumber decimalNumberWithString:@"10.33"];
        NSDecimalNumber *b = [NSDecimalNumber decimalNumberWithString:@"10.3"];
        NSDecimalNumber *c = [NSDecimalNumber decimalNumberWithString:@"2"];
        
        NSLog(@"a + b = %@",[a decimalNumberByAdding:b]);
        NSLog(@"a - b = %@",[a decimalNumberBySubtracting:b]);
        NSLog(@"a * b = %@",[a decimalNumberByMultiplyingBy:b]);
        NSLog(@"a / b = %@",[a decimalNumberByDividingBy:b]);
        NSLog(@"a / b = %@",[a decimalNumberByDividingBy:b]);
        NSLog(@"a的2次方 %@",[a decimalNumberByRaisingToPower:2]);
        NSLog(@"a * 10的2次方 %@",[a decimalNumberByMultiplyingByPowerOf10:2]);
        NSLog(@"a * 10的2次方 %@",[a decimalNumberByMultiplyingByPowerOf10:2]);
    

    NSDecimalNumberHandler的使用
          /*
            NSRoundPlain:四舍五入  NSRoundDown:向下取正   NSRoundUp:向上取正     NSRoundBankers:(特殊的四舍五入,碰到保留位数后一位的数字为5时,根据前一位的奇偶性决定。为偶时向下取正,为奇数时向上取正。如:1.25保留1为小数。5之前是2偶数向下取正1.2;1.35保留1位小数时。5之前为3奇数,向上取正1.4)
            scale:精确到几位小数
            raiseOnExactness:发生精确错误时是否抛出异常,一般为NO
            raiseOnOverflow:发生溢出错误时是否抛出异常,一般为NO
            raiseOnUnderflow:发生不足错误时是否抛出异常,一般为NO
            raiseOnDivideByZero:被0除时是否抛出异常,一般为YES
            */
           
           NSDecimalNumberHandler *roundUp = [NSDecimalNumberHandler
                                              decimalNumberHandlerWithRoundingMode:NSRoundPlain
                                              scale:2
                                              raiseOnExactness:NO
                                              raiseOnOverflow:NO
                                              raiseOnUnderflow:NO
                                              raiseOnDivideByZero:YES];
           NSDecimalNumber * inputNumber = [[NSDecimalNumber alloc]initWithString:@"10.0790001"];
           NSDecimalNumber * number = [inputNumber decimalNumberByRoundingAccordingToBehavior: roundUp];
           NSLog(@"%@",number);//10.08
    

    总结

    因为第一种方案需要准确知道精度,如果精度改了,就可能达不到我们想要的效果,代码需要重构,不建议使用。

  • 相关阅读:
    Linux終端一行命令发送邮件
    团队冲刺2.4
    团队冲刺2.3
    团队冲刺2.2
    找水王
    评价win10自带输入法——微软拼音输入法
    梦断代码阅读笔记01
    团队冲刺2.1
    第十三周总结
    第十二周总结
  • 原文地址:https://www.cnblogs.com/hualuoshuijia/p/14073690.html
Copyright © 2011-2022 走看看