80578
<https://kikakurui.com/x3/X3010-2003-01.html>  
によると幅指定整数型と右シフト演算は以下のように規定されていました。

> 6.5.7 ビット単位のシフト演算子  
>  E1>>E2の結果は，E1をE2ビット分右にシフトした値とする。  
>  E1が符号無し整数型をもつ場合，又はE1が符号付き整数型と非負の値をもつ場合，結果の値は，E1/2E2の商の整数部分とする。  
>  E1が符号付き整数型と負の値をもつ場合，結果の値は処理系定義とする。
>
> 7.18.1.1 幅指定整数型  
>  型定義名intN̲tは，Nビットの幅をもち，詰め物ビットがなく，2の補数で表現される，符号付き整数型を示す。  
>  したがって，int8̲tは，厳密に8ビットの幅をもつ符号付き整数型を表す。

そこで符号bitの取り出しに下記のようなコードを作成しましたが、幅指定整数型が定義される処理系に限定して、このコードの移植性に問題はあるでしょうか？

```

    #include <stdio.h>
    #include <stdint.h>
    
    int main()
    {
        int32_t i = -10;
    
        if (i >> 31)
            puts("OK");
    }
    
```

仮に、右シフトの実装が算術シフト、または論理シフトに限られ、純粋2進表現における2の補数が必ず最上位bitを符号bitとして扱うのであれば問題なく動くような気がしています。

<https://www.jpcert.or.jp/sc-rules/c-int13-c.html>  
によると、

> 右シフト演算は算術(signed)シフトあるいは論理(unsigned)シフトのいずれかで実装される。

となっていますが・・・  
符号bitが変なところにあったり算術シフト、論理シフト以外が使われる可能性はあるでしょうか？  
その他問題点があればご指摘いただきたいです。
CC BY-SA 4.0
2021-08-03T20:58:45.420
80573
2021-08-04T03:55:33.043
2021-08-04T00:10:12.873
3060
44647
question
c
幅指定整数型における符号bitの取り出しについて
移植性を考慮するのであれば、ひねくれたことをせず、素直に

```

     if (i < 0)
            puts("OK");
    
```

とすれば、言語仕様に即した上で、各実装のコンパイラーが適切なコードを生成してくれます。

例えばIntel系プロセッサには SF; 符号フラグ
というものがあり、最後に操作した結果の符号は別に保持しているため、右シフトよりも効率的なコード生成が可能になります。
CC BY-SA 4.0
2021-08-03T23:20:29.117
80574
2021-08-03T23:20:29.117
4236
80573
answer
ごく普通に `if (i<0)`
でダメな理由が知りたいです。妙なテクニックに走られても後から読む人（には数か月後の自分が含まれます）が困惑するだけです。バレルシフタが無い CPU
では真に３１回シフトを行うコードが生成されてしまう可能性があり、単純比較と比して３１倍遅い機械語が生成される可能性があります。ましてや 64bit
型など使ったらどうなるか。

この辺、言語規格書の版によって異なる可能性があります。 [c++](/questions/tagged/c%2b%2b "'c++'
のタグが付いた質問を表示") では [C++20
では２の補数のみ規定](https://cpprefjp.github.io/lang/cpp20/signed_integers_are_twos_complement.html)
なる改版が行われており、提示の命題は C++20 では真です。それより古い C++03 や C++11 等では下記
[c](/questions/tagged/c "'c' のタグが付いた質問を表示") と同様。  
# 文言「２の補数」は暗黙のうちに詰め物なし符号ビットは最上位を含意するため

[c](/questions/tagged/c "'c' のタグが付いた質問を表示") においてはいまだに [１の補数系で -0 と +0
は等しいか](https://ja.stackoverflow.com/questions/27105/)
１の補数であるとかげたばき記法とかを拒絶していなかったはず。その意味で提示の命題は偽です。

とはいえ
[コンピュータ内では2の補数が使われていますか1の補数が使われていますか](https://ja.stackoverflow.com/questions/12855/)
でも書きましたが、現代に生き残っている CPU は２の補数を採用しているものばかりです。情報工学科の課題とかで１の補数な CPU
を設計・作成してオレオレコンパイラを実装する・・・みたいな例でもない限りは提示の命題が偽になることはないと思われます。
CC BY-SA 4.0
2021-08-03T23:54:10.487
80578
2021-08-04T03:55:33.043
2021-08-04T03:55:33.043
8589
8589
80573
answer