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

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

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

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

Q&A

解決済

2回答

833閲覧

シフト演算について、

cgen

総合スコア17

C++

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

0グッド

1クリップ

投稿2021/09/07 16:33

前提・実現したいこと

シフト演算のコードがよくわかりません。下のコードの7行目

unsigned __int64 mask = (__int64)1<<63;

(__int64)1<<63はどういう意味でしょうか。
(__int64)1
というのは10進数で1という意味??それを63ビット左シフト??
シフト演算についてのいいサイトがあれば教えてくれると嬉しいです。

該当のソースコード

class Bitmap { static const int WD = 8; static const int HT = 8; public: Bitmap(__int64 bits) { unsigned __int64 mask = (__int64)1<<63; for(int y = 0; y < HT; ++y) { for(int x = 0; x < WD; ++x) { if( (bits & mask) == 0 ) { m_pixel[x][y] = 0; } else { m_pixel[x][y] = 1; } mask >>= 1; // マスクを右に1ビットシフト } } } ..... };

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

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

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

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

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

guest

回答2

0

左シフトってわかりますか
1<<1 ってのは2になります(00000010)し、1<<2 ってのは4となります(00000100)
これが63ビット分シフトしているってことですね

投稿2021/09/07 17:23

y_waiwai

総合スコア88042

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

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

cgen

2021/09/07 18:01

では、1を63ビット左シフトしたら2の63乗ってことですよね。2の63乗という数値はこの問題にどのように関わってくるのですか? すみません、、
cgen

2021/09/07 18:03

あ!わかったかもしれないです。64個の0か1の数値に対して、0なのか1なのか見るということですかね
cgen

2021/09/07 18:04

でもmaskは1を63ビット左シフトしたら10000...となるわけで、その数値がどう活かされるのでしょう、、
cgen

2021/09/07 18:11

maskが1ずつ右シフトしていくから対象の桁(ビット?)を調べられる、というのはわかりました!
y_waiwai

2021/09/07 22:19

数値、と考えるとかえってややこしくなるので、ビットパターンと考えるとよろしいかと。 提示のコードは、 64個のビットを、それぞれ配列に分解して配置してる、と考えるとよろしいかと
cgen

2021/09/08 15:49

了解です!ビットについての理解が深まりましたありがとうございます。
guest

0

ベストアンサー

C++

1unsigned __int64 mask = (__int64)1<<63;

(__int64)1
というのは10進数で1という意味??それを63ビット左シフト??

はい。1は10進数の1です。

(余談になりますが、もし01と書いたなら8進数で1、0x1と書いたなら16進数で1を表すことになります。が、まあ、何進数で表そうと、1は1です。そしてビット演算を考えるときには数値を2進表記に変えて考えたほうがイメージしやすいと思います。)

(__int64)1は、それを__int64という型にキャスト(型変換)しています。
はい。そしてそれを63ビット左シフトしていますね。

なぜ型変換が必要かというと、1はそのままではint型となります。
処理系にもよりますが、通常int型は32ビットですので、そのまま63ビット左シフトしてしまうと桁があふれて0になってしまいます。
そのため64ビットの型に変換してからシフトしているのですね。

「キャスト」や「ビットシフト」で検索すると良いと思います。

(追記)
上記で使われているのはCから引き継がれた旧式のキャストですので、「C キャスト」で。

投稿2021/09/07 16:40

編集2021/09/07 16:56
itagagaki

総合スコア8402

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

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

cgen

2021/09/07 17:00

問題文 Bitmap(const char *ptr) を追加しなさい。 指定文字列中の 空白、'0', '.' は値0として、それ以外は値1と解釈しなさい。 文字列は各ピクセルの値を左上から右方向、その次の行... という順序で指定するものとする。 上記 Bitmap クラスに、64ビット整数値で画像を指定できるコンストラクタ Bitmap(__int64 bits) を追加しなさい。 という問題に対する回答が上のコードなのですが、なぜ63ビット左シフトする必要があったのかとかわかりますか、、
itagagaki

2021/09/07 17:18 編集

縦8×横8=64個のピクセルからなる画像データがある。 各ピクセルの値は1ビットで表される。('0'が黒で'1'が白とか) したがってこの画像データは64ビットに収まっている。 ということは、64ビットの変数(データ)1つに、この画像データを収納することができる。 それが bits ですね。 この bits で表されている画像を、2次元配列 m_pixel[x][y] で表すように組み直したい。 そのために、bitsのビット(=ピクセル)を、最初から最後まで1ビットずつ、それが'0'か'1'かを調べたい。 データの、あるビットが'0'か'1'かを調べるには、対応するビットだけが’1’でその他のビットが'0'であるデータ(mask)との論理積(&ですね)を取って、調べる対象のビット以外をすべて'0'にした結果が0(オールゼロ)かどうかを判定すればよい。 そのために、まず最初に mask は64ビットデータの最上位のビットだけが'1'のデータにしたい。 だから 1<<63 です。 そして、mask を1ビットずつ右シフトしていって(mask >>= 1)、調べたいビットの場所を変えていますね。
cgen

2021/09/07 18:21

丁寧にありがとうございます!! 32ビット左シフトされる意味、maskが1ずつ右シフトされていって対応するビットだけが1となっている数だということがよくわかりました。
cgen

2021/09/07 18:28

すみません、if( (bits & mask) == 0 ) の部分の意味がまだよくわかりません。おそらく、(bits & mask)の意味がよくわからなくて、、。bits&maskは調べる対象のビット以外がオールゼロになるというのがわかりません。 例えば、1110&0100=0100、1110&0001=0000という意味なのですか。
itagagaki

2021/09/08 00:47

その例のとおりですよ
fana

2021/09/08 02:24 編集

すっごいどうでもいい話ですが,個人的に > Bitmap(__int64 bits) これの引数が unsigned じゃないのが気持ち悪い… (ビットパターン を意図するときに signed にするのが何か嫌) > unsigned __int64 mask = (__int64)1<<63; よく見たらこれも嫌だ. (unsigned __int64)1 << 63 としたい.
cgen

2021/09/08 15:48

itagagakiさんありがとうございます!拝見させていただきました。ビットについての理解が深まりました。 fanaさんありがとうございます!修正します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問