Math.abs一定是正数吗?

当使用Math.abs计算绝对值时,我们会认为结果总是正数。然而,通过深入探讨源码和计算机原理,发现对于某些特定情况,如byte类型的最小值,Math.abs的行为可能不按常理出牌。这源于计算机中补码的表示方式和类型提升的规则。文章通过实例解释了Math.abs在处理byte类型最小值时为什么会返回原值,并探讨了类型转换在其中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      如题,一起来看个例子:

 public static void main(String[] args) {
        System.out.println("The result of Integer type is:" + Math.abs(Integer.MIN_VALUE));
        System.out.println("The result of Long type is:" + Math.abs(Long.MIN_VALUE));
        System.out.println("The result of Byte type is:" + Math.abs(Byte.MIN_VALUE));
    }

       看下结果喽:

The result of Integer type is:-2147483648
The result of Long type is:-9223372036854775808
The result of Byte type is:128

       咦?第三个看似是正确的,但是前两个究竟是怎么一回事?明明是绝对值,怎么可能是负数呢?让我们一起来看下abs的方法源码:

public static long abs(long a) {
        return (a < 0) ? -a : a;
    }

       so easy的代码,如果是是负数,直接求相反数,如果是非负数,直接取原值。那么问题就转换为了求相反数的问题了。

   我们知道,计算机只存储补码,因为计算机只会做加法,而原码和反码的加法运算都会有问题的(具体可参考计算机原理相关知识)。求一个数的相反数就是对其补码连同符号位求反然后加1。好,了解这些基础知识,我们一起来看下为何最小值的相反数是其自身。如果一个数占8位,则其最小值的补码为10000000,老实说,这个数其实就是-0,但0只有一个就够了,索性定规矩的人就把这个值作为最小值-128了。试着按照求相反数的公式,将这个值按位求反,然后加一,发现还是原值。所以前两个类型就很好解释了。

      but,第三种是个什么情况,为什么不是自身呢?这个要看Math.abs了,其入参为byte时,实际调用时传入的形参为int,因为byte类型可以自动转换为int类型的,具体原因我还没找到,不信看下面这个代码。

 public static void main(String[] args) {
        byte value = 8;
        test(value);
    }

    private static void test(int param) {
        System.out.println("调用成功:" + param);
    }

如果你运行一下,会发现这个代码是可以运行的,所以,即使我们将byte类型传给Math.abs,他还是拿int类型来处理的。int位数比这个多。

     而且,Byte.MIN_VALUE默认就是int类型的,只不过其将值赋给了byte类型的,如果我们真的用byte类型来操作。会发现结果跟预期的是一样的,不信的话请看:

class Scratch {
    public static void main(String[] args) {
        System.out.println("The result of Byte type is:" + (-(ByteTest.MIN_VALUE)));
    }

}
class ByteTest {
    public static final byte MIN_VALUE = 0b1000000;
}

看结果:

The result of Byte type is:-64

可知,真实的byte类型的操作是符合求反的原理的。

此外,如果在byte类型中,将byte类型的位数设为8,则其自动会转化为Int类型,不信的话,你试试,看看idea会不会报错呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值