草庐IT

财务精度:BigInteger 与 BigDecimal

TheMagicalRainbowSea 2023-04-16 原文

财务精度:BigInteger 与 BigDecimal


每博一文案

师父说: 人这一辈子,真地好难。
有些人,好着好着,忽然就变陌生了,有些手,牵着牵着,瞬间就放开了,有些路,走着走着,就失去了方向了。
懵懵懂懂,一眨眼,我们就长大了,爱过的人,一转身,,青春就溜走了。以为有来日方长的,最后只剩人走茶凉。
以为能护你周全的,把你留给大风大浪。时光会老,爱会退潮,猜不透的,是人心,回不去,是从前。
从早晨到天黑,忙忙碌碌就是一天,从年初道年尾,辛辛苦苦就是一年。
为了家人,再苦也要咬牙奋斗,为了生活,再累也要微笑面对。
道不尽的,是付出,丢不掉的,是责任。人累了就休息,没有铁打的身体,心累了就放下,不是你的留不住。
一生很短,不要追得太多,心也有限,不必装太满。家不求奢华,只愿温馨和睦,
爱不求浪漫,只愿一生相伴。凡事看开了,烦恼就少了,人心看淡了,受伤就少了,
感情,大不了就是一聚一散,生活,大不了就是一起一落,相爱,有苦有甜才叫日子,心情,有起有落才叫人生。
愿你想开了就不必困惑,参透了就不用执着。
                                            ——————   一禅心灵庙语


1. BigInteger

Integer 类作为 int 的包装类,能存储的最大整型值为 2^31-1,Long 类也是有限的,最大为 2^63-1。如果要表示再大的整数,不管是基本数据类型还是他们的包装类都无能为力,更不用说进行运算了。

java.math 包的 BigInteger 可以表示不可变的任意精度的整数。BigInteger 提供所有 java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。另外,BigInteger 还提供以下运算:模算术,GCD 计算,质数测试,素数生成,位操作以及一些其他操作。


一般使用 public BigInteger(String val) 构造器创建 Bigteger 对象


import java.math.BigInteger;

public class BigIntegerTest {
    public static void main(String[] args) {
        BigInteger bigInteger = new BigInteger("9999999999");
        System.out.println(bigInteger);

    }
}


1.2 BigInteger 常用的方法

1.2.1  BigInteger 的 ”+“ add(), "-"subtract,"*" multiply,"/" divide

BigInteger  是引用数据类型,不是基本数据类型,是不可以直接使用 "+.-.*./" 这些算术运算符的,而是通过调用其对应的对象方法才行。

  • +   加 public BigInteger add(BigInteger val)
  • - 减 public BigInteger subtract(BigInteger val)
  • * 乘 public BigInteger multiply(BigInteger val)
  • / 除public BigInteger divide(BigInteger val)
  • 注意所传的参数 BigInteger 类型的才行的,以及是加减乘除后,返回一个新的 BigInteger 对象不是,在原本的基础上修改的
  • BigInteger 继承了 Number 类,其 Integer 也是继承了该 Number 类。

举例:

import java.math.BigInteger;

public class BigIntegerTest {
    public static void main(String[] args) {
        BigInteger bigInteger = new BigInteger("9999999999");
        BigInteger bigInteger2 = new BigInteger("1");

        BigInteger add = bigInteger.add(bigInteger2);              // +
        System.out.println(add);

        BigInteger subtract = bigInteger.subtract(bigInteger2);    // -
        System.out.println(subtract);

        BigInteger multiply = bigInteger.multiply(bigInteger2);    // *
        System.out.println(multiply);

        BigInteger divide = bigInteger.divide(bigInteger2);        // /
        System.out.println(divide);

    }
}

1.2.2 绝对值:abs()  ,取模:remainder() ,次方:pow()

public BigInteger abs(); // 返回其绝对值。
public BigInteger remainder(BigInteger val); // 返回其值为 (this % val) 的 BigInteger。 
public BigInteger pow(int exponent);  // 返回其值为 (thisexponent) 的 BigInteger。注意,exponent 是一个整数而不是 BigInteger。

同样的是运算后返回一个新的 BigInteger对象,不是在原来的基础上修改的

举例

import java.math.BigInteger;

public class BigIntegerTest {
    public static void main(String[] args) {
        BigInteger bigInteger = new BigInteger("-3");
        BigInteger abs = bigInteger.abs();          // 绝对值
        System.out.println(abs);

        BigInteger bigInteger2 = new BigInteger("2");

        BigInteger remainder = bigInteger.remainder(bigInteger2);   // 取模 %
        System.out.println(remainder);

        BigInteger pow = bigInteger.pow(2);    // 次方
        System.out.println(pow);
    }
}


2. BigDecimal

一般的 Float 类 和 Double 类可以用来左科学计算或工程计算,但在商业,财务,金融 计算中,要求的数字精度比较高,故用

java.math.BigDecimal 类。

因为 无论是 Float 类 还是 Dobule 类都存在精度问题。具体原因大家可以移步至: 浮点数的精确度的探究_ChinaRainbowSea的博客-CSDN博客

你真的了解C语言 if - else 、bool(布尔值)、浮点数损失吗 ?_c11中有bool_ChinaRainbowSea的博客-CSDN博客

如下:

public class BigDoubleTest {
    public static void main(String[] args) {
        double num = 2.9999999999999999999998;
        System.out.println(num);
    }
}

BigDecimal类解决了这个,精度上的问题,并支持不可变的、任意精度的有符号十进制定点数。

常用的构造器两个

public BigDecimal(double val);  // 将 double 转换为 BigDecimal,后者是 double 的二进制浮点值准确的十进制表示形式。
public BigDecimal(String val);  // 将 BigDecimal 的字符串表示形式转换为 BigDecimal

举例:

import java.math.BigDecimal;

public class BigDoubleTest {
    public static void main(String[] args) {
        double num = 2.9999999999999999999998;
        System.out.println(num);   // 精度问题;

        BigDecimal bigDecimal2 = new BigDecimal("2.9999999999999999999998");
        System.out.println(bigDecimal2);
        
    }
}


2. 1 BigDecimal 常用的方法

2.1.1  BigDecimal 的 ”+“ add(), "-"subtract,"*" multiply,"/" divide

public BigDecimal add(BigDecimal augend);  // 返回一个 BigDecimal,其值为 (this + augend),其标度为 max(this.scale(), augend.scale())。 
public BigDecimal divide(BigDecimal divisor,int scale,RoundingMode roundingMode) // 返回一个 BigDecimal,其值为 (this / divisor),其标度为指定标度。如果必须执行舍入,以生成具有指定标度的结果,则应用指定的舍入模式。 
参数:
divisor - 此 BigDecimal 要除以的值。
scale - 要返回的 BigDecimal 商的标度。
roundingMode - 要应用的舍入模式。 
    
public BigDecimal multiply(BigDecimal multiplicand);  // 返回一个 BigDecimal,其值为 (this × multiplicand),其标度为 (this.scale() + multiplicand.scale())。 

public BigDecimal subtract(BigDecimal subtrahend);  // 返回一个 BigDecimal,其值为 (this - subtrahend),其标度为 max(this.scale(), subtrahend.scale())。

注意:  是不可变的,都是计算后返回一个新的BigDecimal 对象,不是在原来的基础上修改的。

举例;

import java.math.BigDecimal;

public class BigDoubleTest {
    public static void main(String[] args) {
        BigDecimal bigDecimal = new BigDecimal("2.9999999999999999999998");
        BigDecimal add = bigDecimal.add(new BigDecimal("1"));   // 加
        System.out.println(add);

        BigDecimal subtract = bigDecimal.subtract(new BigDecimal(1));  // 减
        System.out.println(subtract);

        BigDecimal multiply = bigDecimal.multiply(new BigDecimal(2));   // 乘
        System.out.println(multiply);

        BigDecimal divide = bigDecimal.divide(new BigDecimal(2));   // 除
        System.out.println(divide);

    }
}

这里特别说明一下 BigDecimal 的**除法**** 会 如果除不尽话,可以设置保留精度**

如果除数是 0 ,同样是会报算术异常的。

public BigDecimal divide(BigDecimal divisor,int scale, int roundingMode)

如下是: roundingMode 舍入的模式:说白了就是:四舍五入时的取舍规则,什么情况取,什么情况舍

举例:

import java.math.BigDecimal;

public class BigDoubleTest {
    public static void main(String[] args) {
        BigDecimal bigDecimal = new BigDecimal("2.9999999999999999999998");
        BigDecimal bigDecimal2 = new BigDecimal(2);

        BigDecimal divide = bigDecimal.divide(bigDecimal2,6,BigDecimal.ROUND_FLOOR);   // 除
        System.out.println(divide);
    }
}


3. 总结:

  1. BigDecimal 属于大数据,精度很高,不属于基本数据类型,属于java对象(引用数据类型)这是sun提供的一个类,专门用在财务软件当中。
  2. 注意: 财务软件中的double 是不够的,当处理财务数据时,用那一种类型 ?  千万不能用 double 要用 java.math.BigDecimal 中的类的这个对象
  3. 以及处理 Double 精度上的问题,使用 ``java.math.BigDecimal` 处理。
  4. 对于存储大的 Int 数值 使用 ``java.Math.BigInteger` 类 存储范围更大。
  5. 无论是 : BigDecimal  还是 BigInteger 都是引用类型,不是基本数据类型,对于 ”加减乘除“ 运算符,都不可以直接运算,而是通过 对于的方法进行了。”+“ add(), "-"subtract,"*" multiply,"/" divide。
  6. 无论是 : BigDecimal  还是 BigInteger 都是不可变的,其计算的结果都是,返回一个新的对象,不是在原来的基础上修改的。

4. 最后:

限于自身水平,其中存在的错误,希望大家给予指教,韩信点兵——多多益善,谢谢大家,江湖再见,后会有期 !!!


有关财务精度:BigInteger 与 BigDecimal的更多相关文章

  1. [工业相机] 分辨率、精度和公差之间的关系 - 2

    📢博客主页:https://blog.csdn.net/weixin_43197380📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由Loewen丶原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.分辨率(Resolution)1、工业相机的分辨率是如何定义的?2、工业相机的分辨率是如何选择的?二.精度(Accuracy)1、像素精度(PixelAccuracy)2、定位精度和重复定位精度(RepeatPrecision)三.公差(Tolerance)四.课后作业(Post-ClassExercises)视觉行业的初学者,甚至是做了1~2年

  2. ruby-on-rails - ruby on rails 模型验证中的浮点精度 - 2

    我正在尝试使用正则表达式验证美元金额:^[0-9]+\.[0-9]{2}$这工作正常,但每当用户提交表单并且美元金额以0(零)结尾时,ruby(或rails?)将0砍掉。所以500.00变成500.0,因此正则表达式验证失败。有没有办法让ruby​​/rails保持用户输入的格式,而不管尾随零? 最佳答案 我假设您的美元金额是小数类型。因此,用户在字段中输入的任何值在保存到数据库之前都会从字符串转换为适当的类型。验证适用于已转换为数字类型的值,因此在您的情况下,正则表达式并不是真正合适的验证过滤器。不过,您有几种可能性可以解决这个问

  3. ruby - 1.8 与 1.9 中的 BigDecimal - 2

    当升级到ruby​​1.9时,我在比较BigDecimal的预期值与实际值时测试失败,这是除float的结果。expected:'0.495E0',9(18)got:'0.49500000000000005E0',18(27)googlingforthingslike"bigdecimalrubyprecision"and"bigdecimalchangesruby1.9"isn'tgettingmeanywhere.HowdidBigDecimal'sbehaviorchangeinruby1.9?update1>RUBY_VERSION=>"1.8.7">1.23.to_d=>#>

  4. ruby - Ruby 的任意精度算术 - 2

    Ruby到底是怎么做到的?Jörg或其他人是否知道幕后发生的事情?不幸的是,我不太了解C,所以bignum.c对我帮助不大。我只是有点好奇有人可以解释(用简单的英语)它使用的任何神奇算法背后的理论。irb(main):001:0>999**99936806348825922326789470084006052186583833823203735320465595962143702560930047223153010387361450517521869134525758989639113039318944796977164583238219236607653663113200177617

  5. ruby - 无法将 BigDecimal 强制转换为 BigDecimal - 2

    这应该很简单,但它正在爆炸。有什么想法吗?d=BigDecimal.new("2.0")YAML::load({:a=>d}.to_yaml)TypeError:BigDecimalcan'tbecoercedintoBigDecimalfrom/Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb/inspector.rb:86:in`inspect'from/Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb/inspector.rb

  6. ruby-on-rails - Rails 2.3.11 DateTime BigDecimal 精度 - 2

    我目前有一个运行Ruby1.8.7和Rails2.3.2的RubyonRails项目我有一些从数据库中读取数据的单元测试,特别是两个连续项目的日期时间列,这两个项目应该相隔24小时。在一项测试中,我将项目2的日期时间设置为与项目1的日期时间相同。当我执行断言以确保两个值相等时,测试在rails2.3.2下工作正常。当我升级到rails2.3.11时,测试失败显示两次之间的差异将关闭并出现以下错误:expectedbutwas.这两个版本的rails中似乎存在浮点转换问题。如何解决float问题? 最佳答案 这也发生在我身上,我最终这

  7. ruby-on-rails - Ruby float 学 - Sum Calc 中的精度问题 - 2

    大家早上好我在float学方面遇到了一些问题,完全迷失在“.to_f”、“*100”和“.0”中!我希望有人能帮助我解决我的具体问题,并准确解释他们的解决方案为何有效,以便我下次理解这一点。我的程序需要做两件事:对一组小数求和,确定它们的和是否正好为1.0确定1.0与数字总和之间的差值-将变量的值设置为使总和等于1.0的精确差值。例如:[0.28,0.55,0.17]->总和应为1.0,但我一直得到1.xxxxxx。我正在以下列方式实现总和:sum=array.inject(0.0){|sum,x|sum+(x*100)}/100我需要此功能的原因是我正在读取一组来自excel的小数。

  8. ruby - 在不使用 BigDecimal 的情况下将美分转换为 Ruby 中的美元字符串 - 2

    我想在Ruby中正确地将美分转换为美元。我将永远不必使用几分之一美分。是否可以在不使用BigDecimal的情况下正确执行此操作(没有浮点错误)?例如,美分兑美元"99"=>"0.99""324"=>"3.24"以下似乎有效,但它是否正确?(cents.to_i/100.0).to_s更新:我注意到如果cents="10287349283923497624861294712974892742837833",上面的行不起作用。 最佳答案 作为MichealKohlalreadyanswered:看看金钱gem。例子:require'm

  9. ruby - 我怎么知道 BigDecimal 是否解析失败? - 2

    我正在从csv导入数据,我需要将一些值转换为BigDecimal,如果无法解析则引发错误。根据测试,BigDecimal("invalidnumber")返回0的BigDecimal。这没问题,但有点乱,除了有效值为0...Float("invalidnumber")的行为不同并抛出异常...我目前的解决方案是:classStringdefto_bdbeginFloat(self)rescueraise"Unabletoparse:#{self}"endBigDecimal(self)endend我是否完全遗漏了什么? 最佳答案 在

  10. ruby - 在 Ruby 的 BigDecimal 中是否使用 String 或 Integer - 2

    引用BigDecimal类的文档,n,m=a.precsprecreturnsnumberofsignificantdigits(n)andmaximumnumberofsignificantdigits(m)ofa.我对以下与BigDecimal相关的输出感到困惑。require'bigdecimal'BigDecimal.new('1').precs#=>[9,18]BigDecimal.new(1).precs#=>[9,27]我不明白为什么当传递String时,有效数字的最大数目比传递Fixnum时少。它还会导致任何精度问题吗? 最佳答案

随机推荐