美文网首页
项目中支付时遇到的精度问题(NSDecimalNumber)

项目中支付时遇到的精度问题(NSDecimalNumber)

作者: 温柔vs先生 | 来源:发表于2017-11-02 11:35 被阅读0次

支付中最怕遇到精度有关的问题,导致金额计算不准确,我们手机端从后台接口获取数据的时候,有时候就会出现这样的问题,所以需要我们手机端对返回的数值进行精度上的转换.这里iOS给我们提供了NSDecimalNumber这个计算类,继承与NSNumber.


这里是我封装的一个方法
/**
 *  @brief  截取指定小数位的值
 *
 *  @param  price   目标数据
 *  @param  position    有效小数位(一般都是两位小数)
 *
 *  @return 截取后数据
 */
+ (NSString *)notRounding:(double)price afterPoint:(NSInteger)position
{
    NSDecimalNumberHandler* roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:position raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO];
    NSDecimalNumber *ouncesDecimal;
    NSDecimalNumber *roundedOunces;
    
    ouncesDecimal = [[NSDecimalNumber alloc] initWithDouble:price];
    roundedOunces = [ouncesDecimal decimalNumberByRoundingAccordingToBehavior:roundingBehavior];
    
    NSString *temStr = [NSString stringWithFormat:@"%.2f", roundedOunces.doubleValue];
    // NSLog(@"NSDecimalNumber----%@",temStr);
    return temStr;
}

这里NSDecimalNumber 的这个初始化方法介绍一下

// Rounding policies :
// Original
//    value 1.2  1.21  1.25  1.35  1.27
// 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  (特殊的四舍五入,碰到保留位数后一位的数字为5时,根据前一位的奇偶性决定。为偶时向下取正,为奇数时向上取正。如:1.25保留1为小数。5之前是2偶数向下取正1.2;1.35保留1位小数时。5之前为3奇数,向上取正1.4)


typedef NS_ENUM(NSUInteger, NSRoundingMode) {
    NSRoundPlain,   // Round up on a tie
    NSRoundDown,    // Always down == truncate
    NSRoundUp,      // Always up
    NSRoundBankers  // on a tie round so last digit is even
};
//scale:保留有效小数的个数(为0的无效小数后自动过滤).
//Exactness:进度异常、Overflow:向上溢出、Underflow:向下溢出、DivideByZero:除数为0。当参数为YES出错会抛出异常,为NO时忽略异常。返回nil.
NSDecimalNumberHandler *roundUp = [NSDecimalNumberHandler
                                   decimalNumberHandlerWithRoundingMode:NSRoundUp
                                   scale:2
                                   raiseOnExactness:NO
                                   raiseOnOverflow:NO
                                   raiseOnUnderflow:NO
                                   raiseOnDivideByZero:YES];

其中的一些基本方法(+-*/):

NSDecimalNumber *price1 = [NSDecimalNumber decimalNumberWithString:@"15.99"];
NSDecimalNumber *price2 = [NSDecimalNumber decimalNumberWithString:@"29.99"];
NSDecimalNumber *coupon = [NSDecimalNumber decimalNumberWithString:@"5.00"];
NSDecimalNumber *discount = [NSDecimalNumber decimalNumberWithString:@".90"];
NSDecimalNumber *numProducts = [NSDecimalNumber decimalNumberWithString:@"2.0"];

NSDecimalNumber *subtotal = [price1 decimalNumberByAdding:price2];
NSDecimalNumber *afterCoupon = [subtotal decimalNumberBySubtracting:coupon];
NSDecimalNumber *afterDiscount = [afterCoupon decimalNumberByMultiplyingBy:discount];
NSDecimalNumber *average = [afterDiscount decimalNumberByDividingBy:numProducts];
NSDecimalNumber *averageSquared = [average decimalNumberByRaisingToPower:2];

NSLog(@"Subtotal: %@", subtotal);                    // 45.98
NSLog(@"After coupon: %@", afterCoupon);           // 40.98
NSLog((@"After discount: %@"), afterDiscount);       // 36.882
NSLog(@"Average price per product: %@", average);    // 18.441
NSLog(@"Average price squared: %@", averageSquared); // 340.070481

相关文章

  • 项目中支付时遇到的精度问题(NSDecimalNumber)

    支付中最怕遇到精度有关的问题,导致金额计算不准确,我们手机端从后台接口获取数据的时候,有时候就会出现这样的问题,所...

  • 关于精度处理

    有时会遇到价格类似精度的问题,尤其是float相减时遇到的差距,处理方案:转为NSDecimalNumber类型 ...

  • 链式编程之科学计算

    前段时间因为经常遇到数值的计算,本来用➕➖✖️➗。但是遇到精度问题,所以必须得用NSDecimalNumber类,...

  • iOS中需要谨慎对待8.2这个数字

    咱们在开发中为了防止浮点数有精度问题,特意有NSDecimalNumber进行计算,来解决精度问题。 但是在开发中...

  • 关于OC中的精度计算NSDecimalNumber

    //NSDecimalNumber是NSNumber的子类,是苹果针对浮点型计算时存在精度计算误差的问题而提供的一...

  • NSDecimalNumber修复精度问题

    json 解析double类型多出几位小数,利用NSDecimalNumber修复 后台返回float类型数据8....

  • NSDecimalNumber 介绍

    NSDecimalNumber是NSNumber的不可变子类。苹果针对浮点型计算时存在精度计算误差的问题而提供的一...

  • 2019-08-14

    NSDecimalNumber是NSNumber的不可变子类。苹果针对浮点型计算时存在精度计算误差的问题而提供的一...

  • NSDecimalNumber

    涉及到金额时的计算往往要求保留很高的精度,NSDecimalNumber很好的解决了这个问题,而你不需要再没次都想...

  • 解决货币精度问题(NSDecimalNumber)

    在项目中经常使用到货币的结算问题,但是货币的精度问题真的很让人头疼~~不论你是用float类型还是double类型...

网友评论

      本文标题:项目中支付时遇到的精度问题(NSDecimalNumber)

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