Math.abs 竟然返回了负数???

简介: Math.abs 竟然返回了负数???

「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!

事情是这样的。

某一天扯扯群里发来一段代码:


image.png


读者提问道,为啥这个 pos 还要判断一下?

这代码一看我就熟悉,RocketMQ 的源码,如果你看过源码你会发现到处都有这样的判断。

想着已经取绝对值了,然后再取余,肯定是正数啊,这 if(pos<0) 不就是多余的判断吗?


image.png

滴。

再解释一下为什么 int 最小值取绝对值还是等于它本身。

int 是 32 位,为了便于演示,我就拿 8 位来举例子,反正道理是一样的。

在 Java 中的数字的实现都是有符号位的,不像 C 有个 unsigned 来表示无符号,有符号的数字实现是用最高位来表示符号位,1表示负数,0表示正数。


image.png


图中就是向上溢出得到了最小值,所以最小值取绝对值得到的值比最大值大一,导致向上溢出,又变成了最小值。

因此 Math.abs(Integer.MIN_VALUE) = Integer.MIN_VALUE

那为什么 8 位表示的是-128到127而不是-127到128?

8位二进制,一共有2^8=256个坑位,所以能表示 256 个数字,理论上随便怎么表示都ok,你表示-254~1都行。

但是我们规定无符号数是 0~255,有符号数规定是-128 ~ 127。

如果有符号数要规定成-127到128并不是不行,但是这样就比较麻烦。

按照-128 ~ 127这样的实现,我们只要通过最高位就可以判断一个数的正负,而-127~128就需要排除128这个特例,也就是之前只需要判断最高位,现在变成需要判断最高位为 1 且其它位不全是 0 才是负数。

这样电路设计也要变复杂了,所以我们规定是 -128到127,32位也同理。

Math.absExact

这种出错了但是没有提示的 Math.abs 肯定是不好的,所以在 JDK 15 出了个  Math.absExact


image.png


也就是会抛错,而不是返回个错误的结果。


最后


有位群友还说面百度的时候被问过。

image.png

面试题是真的多,防不胜防。

好了,今天的分享到此结束

更多面试题可以看我汇总的仓库,每个面试题都是含答案的,Java基础已经更新完毕~

面试仓库(含答案)


image.png


相关文章
|
5月前
Math.atan2求角度解析
`Math.tan(x/y)` 求得是与y轴的夹角,而 `Math.atan2(y, x)` 求得是与x轴的夹角(范围:\(-\pi\) 到 \(\pi\)),顺时针为负,逆时针为正。`Math.atan2` 函数注意点:y在前,x在后。它能正确处理各象限的角度,例如 `Math.atan2(1, 1)` 返回 \(\frac{\pi}{4}\),而 `Math.atan2(-1, -1)` 返回 \(-\frac{3\pi}{4}\)。
53 0
Math.atan2求角度解析
|
6月前
Math常用方法,什么是math?
Math常用方法,什么是math?
89 0
|
6月前
总结一些Math的常规用法,什么是math?
总结一些Math的常规用法,什么是math?
118 1
|
6月前
|
Java API
Java的Math.random获取区间随机数
Java的Math.random获取区间随机数
|
6月前
ES6的Array.from({length:N})方法创建长度为N的undefined数组,等价于 [...Array(N)]
ES6的Array.from({length:N})方法创建长度为N的undefined数组,等价于 [...Array(N)]
java 中的 Math.round(-1.5) 等于多少
java 中的 Math.round(-1.5) 等于多少
|
Python
Python浮点数转整数int、round、ceil、floor
Python浮点数转整数int、round、ceil、floor
251 0
Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?
Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加0.5然后进行下取整。
1775 0