美文网首页
初级_NSDecimalNumber 十进制数计算

初级_NSDecimalNumber 十进制数计算

作者: 求长生 | 来源:发表于2016-11-11 11:09 被阅读55次

    由于使用Double计算经常会在小数点后精度问题和上取整、下取整、四舍五入方面出现问题,所以决定使用十进制数做金额、利率的计算。 NSDecimalNumber是NSNumber的子类。

    一、初始化

    //实例方法

    -(instancetype)initWithMantissa:(unsignedlonglong)mantissa exponent:(short)exponent isNegative:(BOOL)flag;
    -(instancetype)initWithDecimal:(NSDecimal)dcm;
    -(instancetype)initWithString:(nullableNSString *)numberValue;
    -(instancetype)initWithString:(nullableNSString *)numberValue locale:(nullableid)locale;
    

    //类方法

    +(NSDecimalNumber *)decimalNumberWithMantissa:(unsignedlonglong)mantissa exponent:(short)exponent isNegative:(BOOL)flag;
    +(NSDecimalNumber *)decimalNumberWithDecimal:(NSDecimal)dcm;+ (NSDecimalNumber *)decimalNumberWithString:(nullableNSString *)numberValue;
    +(NSDecimalNumber *)decimalNumberWithString:(nullableNSString *)numberValue locale:(nullableid)locale;
    

    **e.g. **

    NSDecimalNumber *subtotalAmount = [[NSDecimalNumber alloc]initWithString: @"12.34"]; //12.34
    subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:1234 exponent:-2 isNegative:NO];   //12.34 (
    mantissa:长整形;exponent:指数;flag:正负数)
    subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:1234 exponent:2 isNegative:YES];   //-123400
    discountAmount = [NSDecimalNumber decimalNumberWithString:@"123.4"];      //123.4
    

    //NSDecimal类型
    C语言NSDecimal类型和十进制数转换

    NSDecimalNumber *subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:1234 exponent:-2 isNegative:NO];   //12.34
    NSDecimal decimalValue = [subtotalAmount decimalValue];
    subtotalAmount = [NSDecimalNumber decimalNumberWithDecimal:decimalValue];   //12.34
    

    ☐//字符串转换十进制数格式 : locale
    locale代表一种格式,就像date的格式化一样。这里的locale可以传递两种格式

    NSDictionary *locale = [NSDictionary dictionaryWithObject:@"," forKey:NSLocaleDecimalSeparator];    //以","当做小数点格式
    
    NSDecimalNumber *discountAmount = [NSDecimalNumber decimalNumberWithString:@"123,40" locale:locale];    //123.4
    NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"fr_FR"];    //法国数据格式,法国的小数点是','逗号
    
    NSDecimalNumber *discountAmount = [NSDecimalNumber decimalNumberWithString:@"123,40" locale:locale];    //123.4
    

    二、加减乘除

    加法运算

    - (NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber;
    - (NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber withBehavior:(nullableid <NSDecimalNumberBehaviors>)behavior;
    

    减法运算

    - (NSDecimalNumber *)decimalNumberBySubtracting:(NSDecimalNumber *)decimalNumber;
    - (NSDecimalNumber *)decimalNumberBySubtracting:(NSDecimalNumber *)decimalNumber withBehavior:(nullableid <NSDecimalNumberBehaviors>)behavior;
    

    乘法运算

    - (NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber;
    - (NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber withBehavior:(nullableid <NSDecimalNumberBehaviors>)behavior;
    

    除法运算

    - (NSDecimalNumber *)decimalNumberByDividingBy:(NSDecimalNumber *)decimalNumber;
    - (NSDecimalNumber *)decimalNumberByDividingBy:(NSDecimalNumber *)decimalNumber withBehavior:(nullableid <NSDecimalNumberBehaviors>)behavior;
    

    a的n次方

    - (NSDecimalNumber *)decimalNumberByRaisingToPower:(NSUInteger)power;
    - (NSDecimalNumber *)decimalNumberByRaisingToPower:(NSUInteger)power withBehavior:(nullableid <NSDecimalNumberBehaviors>)behavior;
    

    指数运算

    - (NSDecimalNumber *)decimalNumberByMultiplyingByPowerOf10:(short)power;
    - (NSDecimalNumber *)decimalNumberByMultiplyingByPowerOf10:(short)power withBehavior:(nullableid <NSDecimalNumberBehaviors>)behavior;
    

    四舍五入运算

    - (NSDecimalNumber *)decimalNumberByRoundingAccordingToBehavior:(nullableid <NSDecimalNumberBehaviors>)behavior;
    

    比较运算

    - (NSComparisonResult)compare:(NSNumber *)decimalNumber;
    

    e.g.

    NSDecimalNumber *discount1 = [NSDecimalNumber decimalNumberWithString:@"1.2"];  
    NSDecimalNumber *discount2 = [NSDecimalNumber decimalNumberWithString:@"1.3"];  
    NSComparisonResult result = [discount1 compare:discount2];  
    if (result == NSOrderedAscending) {
          NSLog(@"discount1 < discount2");
      } else if (result == NSOrderedSame) {
          NSLog(@"discount1 == discount2");
      } else if (result == NSOrderedDescending) {
          NSLog(@"discount1 > discount2");
      }
    

    ☐三、格式化处理
    NSDecimalNumberHandler

    -  (instancetype)initWithRoundingMode(NSRoundingMode)roundingMode 
    scale:(short)scale 
    raiseOnExactness:(BOOL)exact 
    raiseOnOverflow:(BOOL)overflow 
    raiseOnUnderflow:(BOOL)underflow 
    raiseOnDivideByZero:(BOOL)divideByZero;
    
    + (NSDecimalNumberHandler *)defaultDecimalNumberHandler;
    + (instancetype)decimalNumberHandlerWithRoundingMode:(NSRoundingMode)roundingMode scale:(short)scale raiseOnExactness:(BOOL)exact raiseOnOverflow:(BOOL)overflow raiseOnUnderflow:(BOOL)underflow raiseOnDivideByZero:(BOOL)divideByZero;
    

    e.g.

    NSDecimalNumberHandler *roundUp = [NSDecimalNumberHandler   decimalNumberHandlerWithRoundingMode:NSRoundBankers
                                           scale:2
                                           raiseOnExactness:NO
                                           raiseOnOverflow:NO
                                           raiseOnUnderflow:NO
                                           raiseOnDivideByZero:YES];
    NSDecimalNumber *subtotal = [NSDecimalNumberdecimalNumberWithString:@"11.4035"];
    NSDecimalNumber *discount = [NSDecimalNumberdecimalNumberWithString:@"3.22"];
    NSDecimalNumber *total = [subtotal decimalNumberByAdding:discount withBehavior:roundUp];//14.62  两个数相加然后舍去小数点后两位以后的部分
    

    枚举

    NSRoundPlain,   // Round up on a tie // 貌似是四舍五入
    NSRoundDown,    // Always down == truncate  // 只舍不入
    NSRoundUp,      // Always up   //  只入不舍
    NSRoundBankers  // on a tie round so last digit is even  // 貌似是: if(四舍五入位 == 5)(四舍五入位(5)+  保留位 )%2 == 0 ? 入 : 舍;  if(四舍五入位 != 5) 遵从四舍五入
    

    End、未补充
    ☐NSDecimalNumberBehaviors
    ☐ NSDecimalNumberHandler
    ☐ NSRoundingMode

    End、未验证
    所有NSDecimalNumber是不可变的,这意味着已经被创建后不能改变它们的值。

    (本页属于摘抄备记笔记,集合网络提供所需方法并加以补充验证,由于来源过多并不一一列举转载地点,希望网络可以流传更精准更全面的技术笔记)

    相关文章

      网友评论

          本文标题:初级_NSDecimalNumber 十进制数计算

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