iOS 浮点型四舍五入精确值问题

热门标签

特别声明:文章多为网络转载,资源使用一般不提供任何帮助,特殊资源除外,如有侵权请联系!

在开发过程中总是会碰到字符串类型转换成浮点型进行运算。但是每当float—>String 或 Sting —> float 转换四舍五入时总会碰上一堆精度失准的问题。即使转成double型也无济于事。先做个总结和分享。提供几种方法思路来解决这个问题:

如果涉及到时金额计算时,对数字的精确度要求很高时,最简单也是最粗暴的方法是直接交于后台处理,由后台处理返回字符串。这算是最安全也算客户端最轻松的方法。(就看后台刁不刁你咯~~~)。
还有一种方式就是在转换double 计算完成时,对相应的结果着手。  看你想要的精度情况。这里以保留两位小数为例。举个栗子:

// 用于计算的连个字符串
      NSString *strA = @"9.5";
    NSString *strB = @"15.11";
    CGFloat fltA  = [strA doubleValue]; /// 转成double时的值:15.109999999999999
    CGFloat fltB  = [strB doubleValue]; /// 转成double时的值: 9.5
    CGFloat mutli = fltA * fltB; ///  断点得到: 143.54499999999999
    NSLog(@"Normally unrounding = %f",mutli); /// 输出 143.545000
    NSLog(@"Normally rounding = %@",[NSString stringWithFormat:@"%.2f",mutli]); //实际输出143.54

 

跟想要的四舍五入还是存在一定的差距。解决的方法是在得出计算结果时。首先对结果加上 5/( 比想要精度还小一位)。 比如上面例子上面想要的是2位精度。则可以在计算的结果时加上千分之5。即 0.005,然后进行两次字符串取值。第一次先按小数的后三位进行字符串转换。再从字符串的中截取到小数点的后2位。 同样用上面的结果举栗:

/// 将计算的数值加千分之五。精度
    CGFloat i = mutli + 0.005;
    /// 首先保留三位小数
    NSString *strTemp       = [NSString stringWithFormat:@"%.3f",i];
    NSRange range           = [strTemp rangeOfString:@"."];
    /// 在截取两位小数
    NSString *strLastResult = [strTemp substringWithRange:NSMakeRange(0, range.location+3)];
    NSLog(@"first method = %@",strLastResult);//实际输出143.55

    3.直接使用官方自带的货币计算用的类: NSDecimalNumberd
    NSDecimalNumber *numberA = [NSDecimalNumber decimalNumberWithString:strA];
    NSDecimalNumber *numberB = [NSDecimalNumber decimalNumberWithString:strB];
   
    /// 这里不仅包含Multiply还有加 减 除。
    NSDecimalNumber *numResult = [numberA decimalNumberByMultiplyingBy:numberB];
   
    NSString *strResult = [numResult stringValue];
    NSLog(@"NSDecimalNumber method  unrounding = %@",strResult);
   
    /// 如果要四舍五入的话还要使用另一个类 NSDecimalNumberHandler
    /*
     讲述下参数的含义:
     RoundingMode: 简单讲就是你要四舍五入操作的标准.
     // 原始数据
     //    值 1.2  1.21  1.25  1.35  1.27
     各个model转换后的值
     // Plain    1.2  1.2   1.3   1.4   1.3
     // Down     1.2  1.2   1.2   1.3   1.2
     // Up       1.2  1.3   1.3   1.4   1.3
     // Bankers  1.2  1.2   1.2   1.4   1.3

     scale : 需要保留的精度。
     raiseOnExactness : 为YES时在处理精确时如果有错误,就会抛出异常。
     raiseOnOverflow  : YES时在计算精度向上溢出时会抛出异常,否则返回。
     raiseOnUnderflow : YES时在计算精度向下溢出时会抛出异常,否则返回.
     raiseOnDivideByZero : YES时。当除以0时会抛出异常,否则返回。
     */
    NSDecimalNumberHandler *roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain
                                                                                                      scale:2
                                                                                           raiseOnExactness:NO
                                                                                            raiseOnOverflow:NO
                                                                                           raiseOnUnderflow:NO
                                                                                        raiseOnDivideByZero:NO];
   
   
    NSString *tempStr =[[numResult decimalNumberByRoundingAccordingToBehavior:roundingBehavior] stringValue];
    NSLog(@"NSDecimalNumber method  rounding = %@",tempStr);
    /// ps。计算的结果如果小数的位数不到你的要求精度。系统不会自动添加“0”,需自行处理 如用户需要小数点后两位小数但计算结果为142.5时。如需后面补“0”需用户自己添加
    /*
     这里主要就展示下怎么使用 NSDecimalNumber 具体的详细用法请戳 https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSDecimalNumber_Class/index.html
     */
   
   
    /*
     暂时就这么点,
     */

 

具体代码请戳:https://github.com/yuwuchiao/Rounding

ps: 目前就想到以上的几种方式,如有其它的方法或者文中有何错误。欢迎留言。

标签:

未经允许不得转载:作者:SheaYang, 转载或复制请以 超链接形式 并注明出处 技术Dog|博客
原文地址:《iOS 浮点型四舍五入精确值问题》 发布于2019-11-05

分享到:
赞(0) 打赏

评论 抢沙发

6 + 7 =


iOS 浮点型四舍五入精确值问题

长按图片转发给朋友

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

Vieu4.0主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。

登录

忘记密码 ?