質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

4回答

2208閲覧

ビット演算における符号なしと符号ありの違い

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/09/12 06:52

提示コードですが符号なしと符号ありのビット演算における処理の違いが知りたいです。無論マイナスの値が使えるかどうかの違いですがビット演算になるとなぜunsignedを使うのでしょうか?

cpp

1unsigned int a; 2int b;

参考サイト:http://wisdom.sakura.ne.jp/programming/c/c53.html
参考サイト: https://www.cc.kyoto-su.ac.jp/~yamada/programming/bit.html

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ビット演算になるとなぜunsignedを使うのでしょうか?

処理系依存のコードにしないためでしょう。
C 規格も C++ 規格もシフト演算については、論理シフトか算術シフトか規定していません。
処理系が任意に選択できます。
そのため signed のオブジェクトを右シフトするコードを書くと処理系依存のコードになってしまいます。

投稿2021/09/12 08:19

lehshell

総合スコア1156

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

a= ~0;
a>>=1;

という演算をした場合、aが符号付きだと結果が変わる場合があります
まあ、こういうややこしいことを考慮しないで済むように、符号なしにするってことで。

投稿2021/09/12 07:11

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/09/12 07:20

なんかの拍子の一つ左にシフトしたときにそれが符号ビットとして扱われて値が変わるからですか?
y_waiwai

2021/09/12 07:25 編集

aが符号付きの場合、 aが0xffffffff になるか、0x7fffffff になるか、処理系によってどっちでもありえますね
退会済みユーザー

退会済みユーザー

2021/09/12 07:29

質問ですが処理系とはパソコンによって変わるということでしょうか?
y_waiwai

2021/09/12 07:31

コンパイラにより変わります
退会済みユーザー

退会済みユーザー

2021/09/12 07:34

コンパイラとはg++ clnag で変わるということでしょうか?
y_waiwai

2021/09/12 07:38

そこらへんはGCCから続くシリーズなんで、おそらく同じ動作をするでしょうね 組み込み系とかそこらへんになるといろいろです
SaitoAtsushi

2021/09/12 08:40

言語仕様におけるシフト演算子についての規定はここにあります。 https://timsong-cpp.github.io/cppwp/n3337/expr.shift 言語仕様における処理系定義 (implementation-defined) という用語は処理系としてその挙動を決めて文書化しておくべき項目ということを意味します。 https://timsong-cpp.github.io/cppwp/n3337/defns.impl.defined GCC では最大値ビットのひとつ上位のビットが符号ビットであると見做した動作をすると規定されています。 https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html ちなみに左シフトには結果が「未定義」となる状況がありますが、 C++ の言語仕様における未定義動作 (undefined behavior) とは言語仕様で一切の要件を課さないことを意味し、処理系がエラーとして検出してもかまいませんし、なんらかの意味のある結果を処理系独自に規定しても構いませんし、状況を完全に無視した動作も許容されます。 要するにその場でいきなり終了したり暴走したりしても言語仕様通りであるということです。 https://timsong-cpp.github.io/cppwp/n3337/defns.undefined 常識的には未定義動作は事実上禁止されている (引き起こしてはならない) 動作と考えるべきですし、処理系を変更したときに挙動が変わってしまうかもしれない処理系定義の挙動をあてにするのは出来れば避けるに越したことは有りません。
guest

0

あ。算術シフトを避ける為ですね……

~~
ビット演算は符号の有無は無視して、そのまま桁ごとに演算がされます。~~
~~
たとえば、
int x = 0; //00000000
をnotで反転
~xの値は11111111 = -1
になります。
同様に、1を反転すると-2になります。
~~
~~
符号があるのに無視されることでおかしな事になるので、unsignedで初めから符号はなかったものとして扱います。
~~
~~
unsigned int x=0;
をnotで反転
~xの値は11111111 = 255
になります。
同様に、1を反転すると254になります。
~~

投稿2021/09/12 07:05

編集2021/09/12 07:12
amiya

総合スコア1218

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

AND/OR/NOTの世界では符号の有無は関係ないのですが、
ビット演算には左右シフトが現れます。
シフトは最上位を符号ビットとして扱うか否かで演算(処理)が変わります。

ビット演算になるとなぜunsignedを使うのでしょうか?

符号ビットを持たない(どのビットも同じ意味として)演算を行いたいからでしょうね。
前述のとおり、AND/OR/NOTおよびそれらの組み合わせのみで演算が構成されているのであれば
signed/unsigned のどちらも同じ結果となります。

投稿2021/09/12 07:01

編集2021/09/12 16:54
episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問