斜渐近线b为0为什么不存在_技 术 | 你不知道的Java——01.数据类型溢出

bf919a7a94ff1a8ba2f98e80eb4682d7.gif

学习JAVA的同学都知道,JAVA有8个基本数据类型。其中除char是无符号数据类型,其余数据类型均为有符号。在这些有符号的数据类型中,均存在数据类型溢出的问题。这个问题的危害其实非常的大,如果它应用于某些计算中,又没有对数据进行有效验证,那么有极大可能让攻击者利用并通过这个漏洞做出意想不到的结果。以下将详细讲解这个漏洞的成因和解决方案

所谓有无符号是指首高位占位是否表示为正负号,在有符号的数据类型中,首高位为0时表示负数,首高位为1时表示正数。以byte型为例,byte占2字节,共16位。当byte的值为1时,其2进制表示为

28ce79387919612f08fd58c27a6585f1.png

当byte值为-1时,其正码表示为

34d47a4b706b8566e71470372dc56dd6.png

但由于计算规则要求,需要进行反码运算

所谓反码运算是指除首高位(即最左边第一位)符号位的值不变,其它各位原值为0的表为1原值为1的表为0。因此反码运算后结果为

d5bf9cc7129677b2225547ad7ceddb1e.png

同时为了让计算机能够正确识别和计算,规定在反码的基础上进行补码。因此,-1的最终结果为

cc43cf743f29e97bb06852a3f19391b5.png

为避免出现-0这样的无效且冗余的表示,如:

21a4c54f93f5299fdc620e0d54c1ea89.png

则规定,上述表示为负数最大值+1,即-128。我们不再深入讨论为什么要进行反码和补码运算,这将会在另外的篇章中进行,这里我们只需要记住负数需要反码和补码运算就好。接下来我们来看看数据是怎么溢出的

2fe5c500fe0e961b5ae606dce144ba04.png

上述代码初看并没有任何问题,我们申明了一个byte型的变量,其值为127,给它的值加上1后输出,但输出结果我们会发现是-128而非128。为什么会这样?我们先看看它原值127的2进制表示为

540f2b01f75b9f418a43b6cf182c4839.png

那么,当我们给这个值+1后的结果又会是什么?在最右边的尾数上+1,我们发现它会不断进位,最终形成这样的结果

b9b10f9c6a75ee0634e8cb5bf97ce9ec.png

前面我们讲过,在byte的2进制表示中,首高位为1则表示负数。因此,当这个变量+1后正好是我们前面讲到的-128

当上述代码改成b+2时,为什么又成了-127呢?同样,我们从127的原码中开始增加,127的2进制+2会形成如下结果

0c86ad4791282155c605b3d7cea591bd.png

但是注意,此时的计算机会认为,这个结果已经是反码和补码后的结果。在写出计算时修正结果,进行同样的反码补码运算。注意:这里在“最后一位减掉再反码”和“全部反码后再补码“的数学计算上都是一样的

cfe8ad7ac10d7c36a50afe9292b3efce.png

因此,最后写出时计算机会认为它的真值表示为

2de7fe7d4b0a80961d063e9f9dd085fb.png

即为-127

我们知道,在JAVA中任何数字默认都表示为int型。如果b+1的结果不强制转为byte这个结果也会默认为int,那么它并不会出现类型溢出的问题。事实也正是如此,在JAVA中我们很少发现其它类型的溢出,而int的溢出漏洞却经常发现。

Int型溢出过程与byte溢出过程原因一致。为了避免这个漏洞的产生,通常我们采用以下几种方法验证参与运算的因子大小,并用更大的数据类型来保存结果。

例如:用户输入a和b两个数,验证a、b两数的范围不可大于int型最大值,但用长整形来接收

a05e227da94f010dffaed1dabe68db05.png

这种方式并不能从根本上解决问题,所以更好的建议是使用 java.util.BigInteger类 来解决。

37b55051811bac9b4b3e69311b713768.png 84e8be464c6a8acf44d9458ce0ce7612.png

采编排:左 左

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值