“/2”和”>>1”的区别
 写优先级队列的时候发现,-1/2的值为0,当时是在一个循环中将一个值/2再-1,然后循环执行,结果进入死循环了。
 改成>>1后,不再死循环,原因是-1 >> 1 = -1。
 于是百度了一下两者的区别,找到了这个:
 编译器不会将“/2”优化为“>>1”,因为当被除数为负数时,/2会向上取整,>>1会向下取整。
 即:“/2“为“向零取整”,“>>1”永远向下取整。
 由于两个操作效果有差异,当被除数为变量时编译器不知道它是不是负数,无法将两个操作等效,不敢优化。
 要是被除数是常量的话,编译器可以直接在编译期算完结果,不在运行期算,这时候效率是一样的,因为都不用计算(也许,万一编译器不优化咱也没处说理啊)。
 于是简单研究了一下二者的原理:
int a = -5;
Console.WriteLine(a / 2);
Console.WriteLine(a >> 1);
得到的结果是-2和-3
 除法不知道具体是怎么实现的,但是右移这个操作还是可以合理推断一下的。
 已知在计算机中,数字由补码的形式存储,那么-5这个数在存储时就应该是1011(简便起见使用4位二进制来表示数字,其中第一位是符号位)
 而将-5右移一位后,最低位数字被舍弃,最高位补上符号位,其结果为1101,转化为十进制就是-3。
 /2这个操作只能靠猜了。从前面百度的结果来看,一个数/2后总会向0取整,那么/2可能是先做一次右移操作(通过计组的学习可以知道计算机中的乘除法都是通过移位操作来实现的,这样可以加快运行速度),当结果为负数且小数部分不为0时,舍弃小数部分后+1以实现向0取整。
希望我提供的帮助能够补偿你在这里花费的时间。
- 本文链接:https://shinya754.github.io/2021/04/07/%E9%99%A4%E4%BB%A52%E5%92%8C%E5%8F%B3%E7%A7%BB1%E4%BD%8D%E7%9A%84%E5%8C%BA%E5%88%AB/
- 版权声明:本博客所有文章除特别声明外,均默认采用 许可协议。