• C Traps:运算


    位移

    如果sizeof(int) = 4,那么下面的代码的结果是什么?

    int x=255; printf("%d", x>>34);
    

    实际输出:63

    在编译这个代码时,编译器会给出警告

    [Warning] right shift count >= width of type [enabled by default]

    (这时假设位移运算位移步数只能在[0, type_bit_width)范围内)位移操作会对其位移步数对数值位宽(这里int类型为32位)做一次求余操作即上述代码等同于

    x >> (34 % 32)
    

    实际上上述的等同不完全正确,当位移步数是负数时

    x >> -1 // 0
    

    这时通过%操作不能把位移步数转化到[0, type_bit_width)范围内(-1 % 32 = -1)

    更为正确的我们可以用以下代码来等效(商向负无穷取整的一种取余方式,正数:n % m,负数:n % m + m,详见“取余”一节)

    int shift = -1
    int q = floor(shift / 32.0);
    double r = i -  q * 32.0;
    x >> (int)(r)
    

    可以写一段代码进行测试

    #include <stdio.h>
    #include <math.h>
    int main() {
        for (int i=-1; i>-65; i--) {
            int sh = i;
            int q = (int)floor(sh / 32.0);
            double r = sh -  q * 32;
            printf("custommod: q = % d, r = % g
    ", q, r);
            int xn = 255;
            printf("%d>>%d = %d
    ", xn, sh, xn>>(sh));
        }
        return 0;
    }
    

    输出见:http://codepad.org/RzYr6fkI

    取余

    取余围绕一下公式进行

    q * b + r = a
    

    其中q = [a / b],r为余数。

    但当a / b为一个浮点数时,它向那个方向取整决定了余数r的取值

    • %:朝0取整(a/b为正时向负方向取整,为负时向正方向取整)

    下面给出一个比较代码(c中的%操作和上一节中自定义的取余方式)

    1     for (int i=-15; i<16; i++) {
    2         if (i == 0) continue;
    3         printf("(%2d, %d)
    ", i, 3);
    4         printf("%%        : q = % d, r = % d 
    ", i / 3, i % 3);
    5         int q = floor(i / 3.0);
    6         double r = i -  q * 3;
    7         printf("custommod: q = % d, r = % g
    ", q, r);
    8     }

    运行结果见:http://codepad.org/jSmd5Jnq

    另外c语言math库中另有一些取余函数:

    • remainder:商向最接近的整数取整
    • remquo:商向最接近的整数取整
    • fmod:商直接截断小数部分(即向0取整),与%运算符一致

    另外在python中%的行为模式与上文自定义的那个取余方式一致见代码:http://codepad.org/XFangjmO

    参考:

      http://www.cplusplus.com/reference/cmath/remainder/

      C traps & pitfalls

      http://blog.csdn.net/huasion/article/details/6855900

  • 相关阅读:
    POJ1741 Tree
    BZOJ3674 可持久化并查集加强版
    BZOJ3673 可持久化并查集 by zky
    BZOJ3174 [Tjoi2013]拯救小矮人
    BZOJ2733 永无乡【splay启发式合并】
    AtCoder Grand Contest 007 E:Shik and Travel
    BZOJ2599:[IOI2011]Race
    AtCoder Regular Contest 063 E:Integers on a Tree
    SPOJ1825:Free Tour II
    AtCoder Grand Contest 012 C:Tautonym Puzzle
  • 原文地址:https://www.cnblogs.com/lailailai/p/3661981.html
Copyright © 2020-2023  润新知