‘NSDecimalNumber--十进制数’使用方法

本文详细介绍了NSDecimalNumber的创建方式及各种数学运算方法,并通过示例展示了如何进行数值比较。

NSDecimalNumber-十进制数,可以有小数点,可以是正负数。继承于NSNumber


  • + (NSDecimalNumber *)decimalNumberWithMantissa:(unsigned long long)mantissa exponent:(short)exponent isNegative:(BOOL)flag;
    mantissa:长整形;exponent:指数;flag:正负数。
    NSDecimalNumber *subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:1275 exponent:-2 isNegative:NO];   //12.75
      subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:1275 exponent:2 isNegative:YES];   //-127500
  • + (NSDecimalNumber *)decimalNumberWithDecimal:(NSDecimal)dcm;
    将C语言NSDecimal类型转成一个十进制数。
      NSDecimalNumber *subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:1275 exponent:-2 isNegative:NO];   //12.75
      NSDecimal decimalValue = [subtotalAmount decimalValue];
      /**
       *  数据结构:
       (NSDecimal) decimalValue = {
       _exponent = -2
       _length = 1
       _isNegative = 0
       _isCompact = 1
       _reserved = 0
       _mantissa = ([0] = 1275, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0, [6] = 0, [7] = 0)
       */
      subtotalAmount = [NSDecimalNumber decimalNumberWithDecimal:decimalValue];   //12.75
  • + (NSDecimalNumber *)decimalNumberWithString:(nullable NSString *)numberValue;
    将字符串转成一个十进制数。
    NSDecimalNumber *discountAmount = [NSDecimalNumber decimalNumberWithString:@"-12.74"];      //-12.74
      discountAmount = [NSDecimalNumber decimalNumberWithString:@"127.4"];      //127.4
  • + (NSDecimalNumber *)decimalNumberWithString:(nullable NSString *)numberValue locale:(nullable id)locale;
    这个有点复杂,locale代表一种格式,就像date的格式化一样。这里的locale可以传递两种格式
    NSDictionary类型:

    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 *)zero; //0
    +(NSDecimalNumber *)one; //1
    +(NSDecimalNumber *)minimumDecimalNumber;
    //-3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    +(NSDecimalNumber *)maximumDecimalNumber;
    //3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    +(NSDecimalNumber *)notANumber;
    //非数字,常用于对比,比如:
    [[NSDecimalNumber notANumber] isEqualToNumber:myNumber];
  • 加法运算

    -(NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber;
    -(NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • 减法运算

    -(NSDecimalNumber *)decimalNumberBySubtracting:(NSDecimalNumber *)decimalNumber;
    -(NSDecimalNumber *)decimalNumberBySubtracting:(NSDecimalNumber *)decimalNumber withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • 乘法运算
    -(NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber;-(NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;

  • 除法运算

    -(NSDecimalNumber *)decimalNumberByDividingBy:(NSDecimalNumber *)decimalNumber;
    -(NSDecimalNumber *)decimalNumberByDividingBy:(NSDecimalNumber *)decimalNumber withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • a的n次方

    -(NSDecimalNumber *)decimalNumberByRaisingToPower:(NSUInteger)power;
    -(NSDecimalNumber *)decimalNumberByRaisingToPower:(NSUInteger)power withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • 指数运算

    -(NSDecimalNumber *)decimalNumberByMultiplyingByPowerOf10:(short)power;
    -(NSDecimalNumber *)decimalNumberByMultiplyingByPowerOf10:(short)power 
    withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • 四舍五入运算

    -(NSDecimalNumber *)decimalNumberByRoundingAccordingToBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • 比较运算

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

    示例

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

在C语言中,`float`类型用于表示单精度浮点数,通常占用32位内存空间。根据IEEE 754标准,这32位被划分为三部分:1位符号位、8位指数位和23位尾数位(也称为有效数字或小数部分)。由于这种有限的位数分配,`float`只能提供大约7个十进制位的有效精度。 ### 浮点运算中的精度问题 当进行浮点数运算时,特别是涉及到非常大或者非常小的数值,或者是需要高精度计算的情况下,可能会遇到显著的舍入误差。这是因为不是所有的十进制分数都可以精确地用二进制浮点数来表示。例如,像0.1这样的简单十进制值,在二进制下是一个无限循环的小数,因此无法准确存储到任何固定长度的二进制格式中。 ```c #include <stdio.h> #include <math.h> int main() { float a = 0.1f; float b = 0.2f; float c = a + b; // 输出结果可能不会是精确的0.3 printf("c = %f\n", c); // 可能输出类似于0.3000001之类的数值 return 0; } ``` ### 避免或解决精度问题的方法 - **使用`double`代替`float`**:如果对精度有更高的需求,可以考虑使用双精度浮点数`double`,它提供了大约15个十进制位的有效精度,相比`float`来说更为精确。 - **避免直接比较浮点数是否相等**:由于可能存在微小的舍入误差,应该通过检查两个数之间的差值是否落在某个可接受的小范围内来进行近似比较。例如,利用`fabs()`函数与`DBL_EPSILON`或自定义的一个很小的阈值进行比较。 ```c #include <stdio.h> #include <math.h> int main() { double x = 0.1 * 9; double y = 0.9; if (fabs(x - y) < 1e-9) { // 使用一个足够小的正数作为容差 printf("x 和 y 被认为是相等的。\n"); } else { printf("x 和 y 不相等。\n"); } return 0; } ``` - **采用专门的库或数据类型处理货币等要求高精度的情况**:对于金融计算等领域,推荐使用特定的数据结构如`NSDecimalNumber`或其他第三方库提供的十进制算术支持以确保准确性。 - **注意编译器优化及平台差异**:某些情况下,不同平台上默认的浮点运算行为可能存在差异,包括但不限于如何处理非规范化数以及是否启用硬件加速等功能。开发者应当留意这些潜在因素,并采取适当措施保证程序的一致性和可移植性。
07-03
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值