BigInteger 的一些基本知识

首先我们知道基本类型只能表示一定范围内的数值。

byte   (-128-127);

long (-9223372036854774808~9223372036854774807)

如果超出范围了该怎么办呢?  比如如何来表示 123123456789123456789。

1489942a3a70c9f02e62dd47f008de04900.jpg

更正一下 ,signum 有三个取值 1,0,-1 .

mag 数组的定义是什么?

首先大数 123123456789123456789 对应的二进制为  1101010110010101110011000111001110100011001110111000101111100010101 ,  共67位,  从后往前每32个bit位可以当作一个int进行存储 。 这应该是最节约内存的表示方式了 ,表示这个大数占用了16个字节 。 

char[] arr = {'1','2','3','1','2','3','4','5','6','7','8','9','1','2','3','4','5','6','7','8','9'};   占用42个字节,所以不大会直接用一个char数组来表示大数

eceba41904e1f53c6c841efd559bcd4b1c2.jpg

 

以下是计算出mag数组的算法,这是一个非常有意思的处理过程。 

相信大家对如何将字符串“123” 转化为int 123 已经很熟悉了

   int sum = 0 ;

    for(int i = 0 ; i<3;i++){

        sum = sum * 10 + ch[i] - '0'

}

以下转换思路类似,只是稍微麻烦了一些些 。 

 

1: 将123123456789123456789 分为三组  group0 = 123 , group1 = 123456789, group2 = 123456789 ;  

       其中group0 的长度为大数的length % 9, 其余 group的长度均为9 , 这个和 java int 的表示范围有关 。Integer.MAX_VALUE = 2147483647 恰好为10位, 因此每组取9个字符,在parse时不会存在溢出问题 。

       int[] num = new int[3] ;

 2: 

     2.1       num[2] = group0的int值 ;   num[1] = 0 ;  num[0]  = 0 ;

     2.2.1      long x = num[2] * 10 ^ 9 ;       123000000000 ;   一个long刚好8个字节 ,分为两个int存储   , (int) x 为x的后四个字节, x>>>32 为x的前四个字节。

                num[2]  = (int) x ; 

                long x = num[1] +  x >>> 32 ;

                num[1]  = (int) x ;

                long x = num[0] +  x >>> 32 ; 

                num[0] = (int) x ;

       2.2.2     long sum = num[2] + group1的int值

                       num[2] = (int) sum ;

                 sum = num[1] + sum >>> 32 ;     有可能有进位 

                 num[1] = (int) sum ;

                 sum = num[0] + sum >>> 32 ;     有可能有进位 

                 num[0] = (int) sum ;

            重复2.2 的两个过程, 即可将一个字符串(大数)表示为整形数组 。

 

还有一些很细节的问题, 比如mag数组的大小,如果小了,肯定表示不了大数, 但是如果大了,对上面的算法毫无影响,最后只需去掉数组前面值为0的item即可 。

(2^n > 123123456789123456789   先求出最小的n 然后 【n/32 】  理论上是这样的,但是这个是无法实现的,因为此时 123123456789123456789是根本不存在的,如果存在也就不需要再表示了)。

 

118fe72a139f4d2bdacf73dc032b6fc5e38.jpg

 

((length * 3402 >>> 10 )  +1  + 31 )  >>> 5 ,     为啥这个可以用来估算mag的长度,而且一定比需要的长度大或者等于。 我现在也没有弄明白,充满神秘感的东西才是这个世界上最好的东西 。 

 

88d4a7fa63dd1c79014fe25ed93ee90eb84.jpg

850aa419c2e06ad6451b92d1b0ae95bdb0e.jpg

这两个过程我是看了n多遍才慢慢看懂的 。

 

接下来的问题:

1:如何将mag数组还原成一个字符串?如果不可逆那么这种表示方式没有任何意义。

2:如何实现加减乘除等运算 。 

 

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/qidis/blog/3098902

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BigInteger和BigDecimal是Java中的两个类,用于处理大数和精确的小数计算。 BigInteger是一个用于表示大整数的类。它可以处理任意大小的整数,并提供了基本的加减乘除等操作方法。可以使用BigInteger类的构造方法实例化一个BigInteger对象,并使用add、subtract、multiply和divide等方法执行相应的加减乘除操作。 BigDecimal是一个用于表示高精度小数的类。它可以处理任意精度的小数,并提供了准确的四舍五入计算。BigDecimal类的基本操作与BigInteger类相似,可以进行加减乘除等运算。与BigInteger不同的是,BigDecimal还提供了setScale方法用于设置小数的精度。 可以使用BigDecimal类的构造方法实例化一个BigDecimal对象,并使用add、subtract、multiply、divide和setScale等方法执行相应的操作。 因此,BigInteger适用于处理大整数运算,而BigDecimal适用于处理高精度小数运算。都提供了丰富的方法来进行相应的运算。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [BigInteger和BigDecimal知识点](https://blog.csdn.net/Guqiancheng/article/details/82263455)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Java核心技术知识点笔记—大数值BigInteger和BigDecimal](https://blog.csdn.net/lyklykkk/article/details/79190150)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值