53320


ビット演算なのですがビットを全てゼロにする処理を考えていたのですが<<20などをしてビットを  
あふれ消す？みたいなことができたんですけどこれは正しい処理の書き方なのでしょうか？  
１ビットずつ１になってるビットを消す処理が正しい処理なのですか？

[code]

    #include <stdio.h>
    
    typedef unsigned char uchar;
    
    void print_bit(unsigned char idx)
    {
        unsigned char bit = 1 << 7;
        int i = 0;
        while (bit != 0)
        {
            if (idx & bit)
            {
                printf("1");
            }
            else
            {
                printf("0");
            }
    
            i++;
            bit >>= 1;
            if (i == 4) {
                printf("_");
            }
        }
        printf("\n");
    }
    
    //左に何回シフトするか
    unsigned char flag_bit(unsigned char idx,unsigned char p)
    {
        unsigned char bit =  1 << 7;
        //unsigned char id = idx;
        if (p == 0)
        {
            p = 1;
        }
        p = 7 - p;
    
        idx <<= p;
        idx = idx  | bit;
        idx >>= p;
    
    
        return idx;
    
    }
    
    int main()
    {
        unsigned char x = 0;
        uchar t = 0;
        uchar bit = 1 << 7;
        t = flag_bit(t,2);
        t = flag_bit(t,4);
        print_bit(t);
    
        t <<= 20;
        print_bit(t);
    
    
        getchar();
    }
    
[/code]


CC BY-SA 4.0
2019-03-06T05:09:52.773
53232
2019-07-16T07:48:33.277
2019-04-05T13:18:52.240
4236
question
c
ビット演算でビットを全部ゼロするときのやり方でどっちが正しいのか知りたい。


> あふれ消す？みたいなことができたんですけどこれは正しい処理

目的次第です。

> １ビットずつ１になってるビットを消す処理

ビット演算では、普通、こっちの処理では無いかと思います。

それ以上は、何がしたいかによります。


CC BY-SA 4.0
2019-03-06T12:12:25.633
53243
2019-03-06T12:12:25.633
53232
answer


[INT34-C. 負のビット数のシフトやオペランドのビット数以上のシフトを行わない](https://www.jpcert.or.jp/sc-
rules/c-int34-c.html)で説明されていますが、

> 右オペランドの値が負または格上げされた左オペランドのビット幅以上である時、シフト動作は未定義となる
> (「[未定義の動作51](https://wiki.sei.cmu.edu/confluence/display/c/CC.+Undefined+Behavior#CC.UndefinedBehavior-
> ub_51)」を参照 )。

Undefined Behavior; 未定義の動作とは、Implementation-Defined Behavior;
処理系定義の動作とは異なり、どのような結果が引き起こされても文句は言えません。

具体的には、Intel
x86プロセッサ向けコンパイラーであれば、`SHL`；論理左シフトや`SAL`；算術左シフト命令が生成されることが想定されます。しかし、Intel
x86プロセッサの`SHL`命令・`SAL`命令は共に下位5bitしか参照せずにシフトを行います。例えば`x <<= 33`
と記述した場合、コンパイラーは`SHL EAX, 33`というコードを生成しますが、Intel x86プロセッサは`x <<=
1`相当の処理しか行わず全部ゼロにはならない、といったこともあり得ます。（実例としてはVisual StudioのDebugビルド）

左シフト演算で故意に溢れさせるのは避けるべきです。


CC BY-SA 4.0
2019-03-07T02:30:56.237
53256
2019-07-16T07:48:33.277
2019-07-16T07:48:33.277
4236
4236
53232
answer


ビットを消すってこういう事？

[code]

    #include <stdio.h>
    #include <limits.h>
    
    #define BITSIZ (sizeof(int) * CHAR_BIT)
    
    static int bitClear(int num, size_t pos)
    {
        if (pos >= BITSIZ) {
            return 0;
        }
        //
        int msk = ~(1 << pos);
        //
        return num & msk;
    }
    //
    int main(void)
    {
        printf("%d\n", bitClear(0xff, 4));
        //
        return 0;
    }
    
    
[/code]

usr ~/Project/test % ./a.out  
239  
usr ~/Project/test %


CC BY-SA 4.0
2019-03-09T11:50:28.473
53320
2019-03-09T11:50:28.473
25438
53232
answer