美文网首页程序员
OC中小数的精确计算

OC中小数的精确计算

作者: 忠橙_g | 来源:发表于2016-12-22 17:23 被阅读1836次

问题源于自己做的一个字符串单位换算的扩展方法,目的是把一大串数字转换成万、百万等为单位。
最开始的时候,思路很简单 直接把String转成float(float最高能表示到3.4*10^38,一般来说够用了),判断下要显示哪个单位,除一下就好了,然后就有了以下的代码:

+(NSString *)unitStringFromString:(NSString *)numberStr{
    NSString *resultStr = nil;
    CGFloat nfloat = [numberStr floatValue];
    CGFloat resultFloat = 0;
    NSString *resultUnit = @"";
    //0~5位数不变,6~8位数转换为**万,9-12位数转换为**亿,12位数以上转化为**万亿
    if (nfloat/100000<1) {
        return numberStr;
    }else if(nfloat/100000000<1){
        resultFloat = nfloat/10000.f;
        resultUnit = @"万";
    }else if(nfloat/1000000000000<1){
        resultFloat = nfloat/100000000.f;
        resultUnit = @"亿";
    }else{
        resultFloat = nfloat/1000000000000.f;
        resultUnit = @"万亿";
    }
    //这里直接保持小数点后所有位数,并去除多余的0
    resultStr = [NSString stringWithFormat:@"%@%@",@(resultFloat),resultUnit];
    //或者直接保留两位小数
    //resultStr = [NSString stringWithFormat:@"%.2f%@",resultFloat,resultUnit];
    return resultStr;
}

那么问题来了:当保留所有小数位数的时候,得出来的结果与预期的并不相同,例如:

numberStr = @"108649330";
全部的输出结果为=>
resultStr = @"1.08649328亿";
保留两位小数的结果为=>
resultStr = @"1.09亿";

我们发现保留两位小数时的数据没有问题,但是全部输出时,会有一定的误差。
我们想要的效果是,去除小数点后多余的0,并且最多保留两位小数,所以添加了一些代码:

    //这里保留两位小数,并去除多余的0
    NSString *tempStr = [NSString stringWithFormat:@"%.2f",resultFloat];
    resultStr = [NSString stringWithFormat:@"%@%@",@([tempStr floatValue]),resultUnit];

这样就能达到想要的效果了。
但是,有没有更精确的方法来计算两个浮点数的运算呢?
后来发现了这篇文章 关于OC中的小数精确计算---NSDecimalNumber
文中,提到了NSDecimalNumber是用于OC中精确计算的,所以我将上面的代码修改为:

+(NSString *)unitStringFromString:(NSString *)numberStr{
    NSString *resultStr = nil;
    NSDecimalNumber *decNumber = [NSDecimalNumber decimalNumberWithString:numberStr];
    NSString *devisor;
    NSString *resultUnit = @"";
    CGFloat nfloat = [numberStr floatValue];
    //0~5位数不变,6~8位数转换为**万,9-12位数转换为**亿,12位数以上转化为**万亿
    if (nfloat/100000<1) {
        devisor = @"1";
        resultUnit = @"";
    }else if(nfloat/100000000<1){
        devisor = @"10000";
        resultUnit = @"万";
    }else if(nfloat/1000000000000<1){
        devisor = @"100000000";
        resultUnit = @"亿";
    }else{
        devisor = @"1000000000000";
        resultUnit = @"万亿";
    }
    NSDecimalNumber *divisorNumber = [NSDecimalNumber decimalNumberWithString:devisor];
    NSDecimalNumber *resultDec = [decNumber decimalNumberByDividingBy:divisorNumber];
    //直接输出结果
    //resultStr = [resultDec stringValue];
    //resultStr = [NSString stringWithFormat:@"%@%@",resultStr,resultUnit];
    //这里保留两位小数,并去除多余的0
    NSString *tempStr = [NSString stringWithFormat:@"%.2f",[resultDec floatValue]];
    resultStr = [NSString stringWithFormat:@"%@%@",@([tempStr floatValue]),resultUnit];
    return resultStr;
}

以上,问题解决。

相关文章

网友评论

    本文标题:OC中小数的精确计算

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