最多保留n位小数-满足支付类应用金额的显示

382 阅读1分钟

需求

网上也搜到了不少关于相关的解决办法,但是都不符合我这边的需求:

  • 可以根据传入参数设置保留多少位。
  • 末尾多余的0要去掉,比如保留两位,但是 9.101 要截成 9.1。
  • 可以还原数字字符串中的分节号,比如:10,988.088这种字符串的处理。
  • 直接截取,末位不能四舍五入。

自己封装了一个NSString的扩展,满足我自己的需求:

  • 可以根据传入的参数来设置保留多少位小数。
  • 支持带分节号的数字字符串,截取之后返回的字符串仍然又分节号。
  • 去除末尾多余的0。
  • 直接截取,末位不四舍五入。

测试

截取效果如下:

// 保留两位小数
98.1 -> 98.1
98.01999 -> 98.01
98.90999 -> 98.9
10,789.01999 -> 10,789.01
10,789.90999 -> 10,789.9

// 保留三位小数
98.1 -> 98.1
98.012999 -> 98.012
98.990999 -> 98.99
10,789.012999 -> 10,789.012
10,789.990999 -> 10,789.99

源码

- (NSString *)jkr_filter_subNumberStringWithDecimals:(NSInteger)decimals {
    if (!self || ![self containsString:@"."] || decimals < 0 || decimals > 10) return self;
    BOOL hasComma = [self containsString:@","];
    NSString *subCommaString;
    if (hasComma) {
        hasComma = YES;
        subCommaString = [self stringByReplacingOccurrencesOfString:@"," withString:@""];
    } else {
        subCommaString = self;
    }
    NSString *formatString = [NSString stringWithFormat:@"%%.%zdf", decimals];
    NSInteger formatMultiplier = pow(10, decimals);
    NSString *subfloatString = [NSString stringWithFormat:formatString, floor((subCommaString.doubleValue) * formatMultiplier) / formatMultiplier];
    NSString *ms = [NSString stringWithString:subfloatString];
    subNumberString(&ms);
    if (hasComma) {
        if ([ms containsString:@"."]) {
            NSRange dRange = [ms rangeOfString:@"."];
            NSString *fString = [ms substringWithRange:NSMakeRange(0, dRange.location)];
            NSString *bString = [ms substringWithRange:NSMakeRange(dRange.location + 1, ms.length - dRange.location - 1)];
            NSString *rString;
            NSMutableString *mFString = [NSMutableString stringWithString:fString];
            for (NSInteger i = 0; (i + 1) * 3 + i < mFString.length; i++) {
                [mFString insertString:@"," atIndex:mFString.length - ((i + 1) * 3 + i)];
            }
            rString = [NSString stringWithFormat:@"%@.%@", mFString, bString];
            return rString;
        } else {
            NSString *fString = ms;
            NSString *rString;
            NSMutableString *mFString = [NSMutableString stringWithString:fString];
            for (NSInteger i = 0; (i + 1) * 3 + i < mFString.length; i++) {
                [mFString insertString:@"," atIndex:mFString.length - ((i + 1) * 3 + i)];
            }
            rString = [NSString stringWithFormat:@"%@", mFString];
            return rString;
        }
    }
    return ms;
}

static inline void subNumberString(NSString **string) {
    NSString *ms = *string;
    while ([ms hasSuffix:@"0"] && ms.length > 0) {
        ms = [ms substringToIndex:ms.length - 1];
    }
    if ([ms hasSuffix:@"."]) {
        ms = [ms substringToIndex:ms.length - 1];
    }
    *string = ms;
}