Objective-C 精确计算

在iOS中需要精确计算时,double, float类型往往会出现不可预料的问题:

  在调试过程中可以看到 doule 类型 d3 在计算过程中值不是预计的9999.99。

  如果在要用中计算涉及到金额等重要数据,不建议使用这种不可控结果的方式,可以采用iOS提供的另外一种支持准确精度计算的数据类型 NSDecimalNumber.

  NSDecimalNumber是NSNumber的子类,比NSNumber的功能更为强大,可以指定一个数的幂,四舍五入等操作。由于NSDecimalNumber精度较高,所以会比基本数据类型费时,所以需要权衡考虑,苹果官方建议在货币以及要求精度很高的场景下使用。

  所有NSDecimalNumber对象是不可变的,这意味着已经被创建后不能改变它们的值。

- (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;

NSDecimalNumberBehaviors对象可以通过下述方法创建

NSDecimalNumberHandler *roundUp = [NSDecimalNumberHandler
                                       decimalNumberHandlerWithRoundingMode:NSRoundBankers
                                       scale:2
                                       raiseOnExactness:NO
                                       raiseOnOverflow:NO
                                       raiseOnUnderflow:NO
                                       raiseOnDivideByZero:YES];

  scale代表保留小数点后几位

  枚举,

    NSRoundPlain,   // Round up on a tie //貌似取整
    NSRoundDown,    // Always down == truncate  //只舍不入
    NSRoundUp,      // Always up    // 只入不舍
    NSRoundBankers  // on a tie round so last digit is even  貌似四舍五入

  

 

时间: 2024-11-05 09:39:25

Objective-C 精确计算的相关文章

第二章 Java浮点数精确计算

1.实际意义 在实际开发中,如果需要进行float或double的精确计算(尤其是财务计算),直接使用float或double是不行的(具体的例子看下边的代码的main方法的测试结果),需要使用BigDecimal. 2.代码 package com.xxx.util; import java.math.BigDecimal; /** * 浮点数精准算法 */ public class BigDecimalArithUtil { private static final int DIV_SCAL

Java中浮点型数据Float和Double进行精确计算的问题

一.浮点计算中发生精度丢失  大概很多有编程经验的朋友都对这个问题不陌生了:无论你使用的是什么编程语言,在使用浮点型数据进行精确计算时,你都有可能遇到计算结果出错的情况.来看下面的例子. // 这是一个利用浮点型数据进行精确计算时结果出错的例子,使用Java编写,有所省略. double a = (1.2 - 0.4) / 0.1;System.out.println(a); 如果你认为这个程序的输出结果是“8”的话,那你就错了.实际上,程序的输出结果是“7.999999999999999”.好

Java使用BigDecimal解决精确计算的问题

最近有人在微信上给我发了一个数学题目,如下图: 我看了之后感觉很是简单,但是却想了半天才解出来.解出来后我想到了用程序再解一遍,然而精确计算的问题却让人头疼不已. 解题思路: 思路其实很简单,暴力求解就可以,但是当你写了一个四重for循环后你会发现解不出来.由此考虑到结果可能是小数,便把增量改成了float类型,每次自增0.1. 当你写完满心欢喜地运行的时候会发现还是出不来结果.再改成double类型也同样是不行. 这是因为java中float类型相加是把十进制转化为二进制后相加然后把二进制结果

java精确计算之BigDecimal

Java中的计算主要有double,float,int,long,BigDecimal 1.float和double主要用户科学计算和工程计算,它们执行二进制浮点运算,这是为了在广泛的数值范围上提供较为精确的快速近似计算而设计的.然而它们并没有提供完全精确的结果,所以不应该被用于需要精确计算的场合. eg: double double_price1 = 1.03;  double double_price2 = 0.42;  System.out.println("double的计算值:&quo

Java浮点数float和double精确计算的精度误差问题总结

1.float整数计算误差 案例:会员积分字段采用float类型,导致计算会员积分时,7位整数的数据计算结果出现误差. 原因:超出float精度范围,无法精确计算. float和double的精度是由尾数的位数来决定的.浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的“1”,由于它是不变的,故不能对精度造成影响. float:2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为6~7位有效数字: double:2^5

精确计算工具类,提供加减乘除的计算

package com.ljq.util; import java.math.BigDecimal; /** * 精确计算工具类,提供加减乘除的计算 * * @author jqlin */ public class CompuUtils { /**小数点后保留的位数*/ public final static int SCALE = 5; /** 0 */ public final static int ZERO = 0; /** * BigDecimal大小比较 * * @param a *

Java精确计算

Java精确计算 如果我们编译运行下面这个程序会看到什么? public class Test{ public static void main(String args[]){ System.out.println(0.05+0.01); System.out.println(1.0-0.42); System.out.println(4.015*100); System.out.println(123.3/100); } } 你没有看错!结果确实是 0.060000000000000005 0

精确计算java中float和double的精度

[本文相关的代码放在github上,地址为:https://github.com/VigourJiang/StructuredFloat] Java中double类型的格式是遵循IEEE 754标准的.尽管数学意义上的小数是连续的,但double仅仅能表示其中的一些离散点,把这些离散点组成的集合记为S,S的大小还是有限的.如果要保存的小数P刚好在集合S内,那么double类型就能精确的表示P:否则double类型只能从集合S中找一个与P最近的离散点P'代替P. 以上表述对于float也成立.IE

BigDecimal精确计算及陷阱

BigDecimal通常在涉及到精确计算的时候会用到,下面是自己多次错误使用BigDecimal的总结. 结论: BigDecimal初始化小数时,尽量用字符串形式,例如new BigDecimal("0.1"); BigDecimal类型变量比较大小时用compareTo方法,判断变量值是否为0,与BigDecimal.ZERO比较大小. BigDecimal作除法时,除了要考虑除数是否为0,更要考虑是否能除尽的问题,直接调用BigDecimal divide(BigDecimal