今天碰到了负数除法与右移的替代问题,借机研究一下C语言中负数除法的问题。此处只讨论整数除2的幂次方的情况,并取-7~-5除以4为例,不讨论一般除法的移位优化。
-
负数右移
对于有符号整数,右移时按高位补符号位的原则,则结果会向小于它的整数取整。如
-5 >> 2 = -2;
-6 >> 2 = -2;
-7 >> 2 = -2;
-
负数除法(截断)
博文《议“右移一位 等同于 除以二”》http://blog.chinaunix.net/uid-406135-id-3421605.html中有这样一段描述:“C99和C++0x规定,商向零靠近取整,在 C99 和 C++0x 之前,只保证商*除数+余数==被除数,如果希望商向零靠近取整,应当使用div函数。”
那上述算式就会有结果:
-5 / 4 = -1;
-6 / 4 = -1;
-7 / 4 = -1;
-
负数除法(四舍五入)
四舍五入的意义就在于向临近的整数取整,但问题就在于对.5这个临界点如何进行处理。这里有一种说法,即是说对于负数相除四舍五入的情况,可以先将符号拿掉,按正整数做除法,最后再把符号位加到结果上即可。那上述算式的结果应该为:
-5 / 4 = -1;
-6 / 4 = -2;
-7 / 4 = -2;
即
sign(val) * (abs(val) +(1<< (n-1) )>> n)。
Microsoft Excel的取整就是采用这种方法。
但是,在ARM的NEON运算里的rounding,以及java的Math.round()函数的返回值来看(参考http://www.cnblogs.com/jiutianhe/archive/2012/10/07/2755655.html):
在.5这个临界点上,对于正负值都是向上取整。即是说按公式(val+ (1 << (n-1))) >> n进行计算。即:
-5 / 4 = -1;
-6 / 4 = -1;
-7 / 4 = -2;
C语言如何进行取整
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/114935.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...