美文网首页
iOS浮点数精度丢失问题及处理方案

iOS浮点数精度丢失问题及处理方案

作者: 叫我大表弟吧 | 来源:发表于2016-12-21 17:28 被阅读4035次

    为什么浮点数精度会丢失

    浮点十进制值通常没有完全相同的二进制表示形式。 这是 CPU 所采用的浮点数据表示形式的副作用。 为此,可能会经历一些精度丢失,并且一些浮点运算可能会产生意外的结果。

    导致此行为的原因是下面之一:
    十进制数的二进制表示形式可能不精确。
    使用的数字之间类型不匹配(例如,混合使用浮点型和双精度型)。

    &&
    代码之谜(五)- 浮点数(谁偷了你的精度?)

    解决方案

    如果你通读了上面的为什么就会知道,这是IEEE 754标准中二进制浮点数的缺陷,没有解决方案。

    处理方案

    • 高精度要求

    使用系统提供的NSDecimalNumber API进行计算,最后转换为字符串输出显示。NSDecimalNumber转换方法:

    #import "NSDecimalNumber+Y_Add.h"
    
    @implementation NSDecimalNumber (Y_Add)
    
    + (NSDecimalNumber *)y_decimalNumberWithFloat:(float)value{
        
        return [self y_decimalNumberWithFloat:value scale:2];
    }
    
    + (NSDecimalNumber *)y_decimalNumberWithFloat:(float)value scale:(short)scale{
        
        return [self y_decimalNumberWithFloat:value roundingMode:NSRoundBankers scale:scale];
    }
    
    + (NSDecimalNumber *)y_decimalNumberWithFloat:(float)value roundingMode:(NSRoundingMode)roundingMode scale:(short)scale{
        
        return [[[NSDecimalNumber alloc] initWithFloat:value] y_decimalNumberHandlerWithRoundingMode:roundingMode scale:scale];
    }
    
    + (NSDecimalNumber *)y_decimalNumberWithDouble:(double)value{
        
        return [self y_decimalNumberWithDouble:value scale:2];
    }
    
    + (NSDecimalNumber *)y_decimalNumberWithDouble:(double)value scale:(short)scale{
        
        return [self y_decimalNumberWithDouble:value roundingMode:NSRoundBankers scale:scale];
    }
    
    + (NSDecimalNumber *)y_decimalNumberWithDouble:(double)value roundingMode:(NSRoundingMode)roundingMode scale:(short)scale{
        
        return [[[NSDecimalNumber alloc] initWithFloat:value] y_decimalNumberHandlerWithRoundingMode:roundingMode scale:scale];
    }
    
    
    
    
    /**
     *  <#Description#>
     *
     *  @return <#return value description#>
     */
    - (NSDecimalNumber *)y_decimalNumberHandler{
        
        return [self y_decimalNumberHandlerWithRoundingMode:NSRoundBankers scale:2];
    }
    
    - (NSDecimalNumber *)y_decimalNumberHandlerWithRoundingMode:(NSRoundingMode)roundingMode scale:(short)scale{
        
        NSDecimalNumberHandler *handler = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:roundingMode
                                                                                                 scale:scale
                                                                                      raiseOnExactness:NO
                                                                                       raiseOnOverflow:YES
                                                                                      raiseOnUnderflow:YES
                                                                                   raiseOnDivideByZero:YES];
        return [self decimalNumberByRoundingAccordingToBehavior:handler];
    }
    
    
    @end
    
    
    • 普通精度要求

    使用系统提供的数学运算进行计算,最后转换为字符串输出显示。保留小数点后N位的方法:

    /**
     *  formatterNumber .00 小数点后两位
     *
     *  @param number <#number description#>
     *
     *  @return <#return value description#>
     */
    + (NSString *)y_formatterNumber:(NSNumber *)number{
        
        return [self y_formatterNumber:number fractionDigits:2];
    }
    
    + (NSString *)y_formatterNumber:(NSNumber *)number fractionDigits:(NSUInteger)fractionDigits{
            
        NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
        [numberFormatter setMaximumFractionDigits:fractionDigits];
        [numberFormatter setMinimumFractionDigits:fractionDigits];
        
        return [numberFormatter stringFromNumber:number];
    }
    

    相关文章

      网友评论

          本文标题:iOS浮点数精度丢失问题及处理方案

          本文链接:https://www.haomeiwen.com/subject/bmpqvttx.html