ビット演算
-
朽木
Re:ビット演算
ビット列として表現する、ということは、10は 0000 0000 1010 、15 は 0000 0000 1111 、ということですか?(反転無視)
プログラミングの課題で 10 進数から 2進数 への変換という表現は少々罠な感じがしますが、
とりあえず、ビット演算子というものをGoogleなどで調べてみると良いでしょう。
http://www.google.co.jp/search?hl=ja&q=ビット演算子
表現については for文 と printf() で十分なはずです。 ってか、3ポイントってどういうこと… (・ω・`)
プログラミングの課題で 10 進数から 2進数 への変換という表現は少々罠な感じがしますが、
とりあえず、ビット演算子というものをGoogleなどで調べてみると良いでしょう。
http://www.google.co.jp/search?hl=ja&q=ビット演算子
表現については for文 と printf() で十分なはずです。 ってか、3ポイントってどういうこと… (・ω・`)
-
たかぎ
Re:ビット演算
何が分からないのか分かりませんが、C++なら、
#include <iostream>
#include <cstdlib>
#include <bitset>
#include <string>
std::string compl2(const std::string& decimal)
{
std::bitset<12> bs(std::strtoul(decimal.c_str(), 0, 10));
bs = ~bs;
bs = bs.to_ulong() + 1;
return bs.to_string<char, std::char_traits<char> >();
}
int main()
{
std::cout << compl2("123") << std::endl;
}
といったところです。-
朽木
Re:ビット演算
とりあえず、言語の指定が無い以上、ここで出されるべき言語はCですから、C++で出す意味は無いと思いますよ。
Cを習っている人から見れば、「え?こんなに難しいことをしなければいけないの?」という混乱をしてしまい、
無益な回答で、せっかく学習意欲のある質問者がかわいそうです。
アメリカで買った本とイギリスで買った本を持ち帰って二つとも同じにみて勉強してしまい、いざとなった時に
通じなかったり、まったく意味が異なっていて泣き寝入りしてしまうのと同じような結果に繋がります。
「C++も勉強する事になるかもしれないし?いいじゃん」ではなく、今勉強している事について、
手を差し出すべきではないでしょうか。
で、連投で申し訳ないんですが、
10進数から2進数に変換ですが、もしかして12( + 番兵)バイトの文字列に変えるということでしょうか。
もっと詳しい情報が欲しいです。プログラムは実行できない状態でも良いので載せて頂けますか。
Cを習っている人から見れば、「え?こんなに難しいことをしなければいけないの?」という混乱をしてしまい、
無益な回答で、せっかく学習意欲のある質問者がかわいそうです。
アメリカで買った本とイギリスで買った本を持ち帰って二つとも同じにみて勉強してしまい、いざとなった時に
通じなかったり、まったく意味が異なっていて泣き寝入りしてしまうのと同じような結果に繋がります。
「C++も勉強する事になるかもしれないし?いいじゃん」ではなく、今勉強している事について、
手を差し出すべきではないでしょうか。
で、連投で申し訳ないんですが、
10進数から2進数に変換ですが、もしかして12( + 番兵)バイトの文字列に変えるということでしょうか。
もっと詳しい情報が欲しいです。プログラムは実行できない状態でも良いので載せて頂けますか。
-
たかぎ
Re:ビット演算
一応Cでも書いてみました。
> 「え?こんなに難しいことをしなければいけないの?」という混乱をしてしまい、
どう考えてもC++の方が簡単です。
#include <stdio.h>
#include <stdlib.h>
#define DIGIT 12
void compl2(_Bool binary[DIGIT], const char *decimal)
{
unsigned long value = strtol(decimal, NULL, 10);
for (size_t i = 0; i < DIGIT; i++)
binary = value & (1ul << i);
for (size_t i = 0; i < DIGIT; i++)
binary = !binary;
_Bool carry = 1;
for (size_t i = 0; i < DIGIT; i++)
{
unsigned t = binary + carry;
binary = t & 1;
carry = t > 1;
}
}
int main(void)
{
_Bool binary[DIGIT];
compl2(binary, "123");
for (size_t i = 0; i < DIGIT; i++)
printf("%c", binary[DIGIT - 1 - i] ? '1' : '0');
}> 「え?こんなに難しいことをしなければいけないの?」という混乱をしてしまい、
どう考えてもC++の方が簡単です。
-
やそ
Re:ビット演算
まずは、掲示板の上にある、
必ずお読み下さい → 規約と注意事項
から規約を読んで、
”質問の仕方”
を手に入れましょう。
読めばお分かりになると思いますが、
必要な情報が足りません。
課題はC?C++?
課題として出された設問文?に制限項目などありますか?
使用できる命令とか使用してはいけないものとか(ビット演算子は使えるの??)
また、ご自分が作成されたプログラム(10進数から2進数への変換)
はここに載せられますか?
>10進数から、2進数の変換までは教科書をみながら出来たのですが、そのあとが;;
ということですが、
>その変換したものを反転させる。
>さらに、「1」を加え(2の補数とり)表示。
の部分だけアドバイスできれば良いのでしょうか?
必ずお読み下さい → 規約と注意事項
から規約を読んで、
”質問の仕方”
を手に入れましょう。
読めばお分かりになると思いますが、
必要な情報が足りません。
課題はC?C++?
課題として出された設問文?に制限項目などありますか?
使用できる命令とか使用してはいけないものとか(ビット演算子は使えるの??)
また、ご自分が作成されたプログラム(10進数から2進数への変換)
はここに載せられますか?
>10進数から、2進数の変換までは教科書をみながら出来たのですが、そのあとが;;
ということですが、
>その変換したものを反転させる。
>さらに、「1」を加え(2の補数とり)表示。
の部分だけアドバイスできれば良いのでしょうか?
-
conio
Re:ビット演算
①10進数から2進数に変換。
②その変換したものを反転させる。
③さらに、「1」を加え(2の補数とり)表示。
まず、①が良く分からないのです。
”10進数から2進数の変換するプログラム”を書いたという事ですか?
例えば、
int a = 10;
こうすれば、既に内部では2進数になっていますよ。
特にプログラムにする部分は無いと思います。
次に、②は補数演算子~ を使えばいいと思います。
③は、単純に1を足して、
表示する時は、
-------------------------------------------------------------
11ビット右へシフトしたものと、1の論理績& をとったものを表示
10ビット右へシフトしたものと、1の論理績& をとったものを表示
9ビット右へシフトしたものと、1の論理績& をとったものを表示
8ビット右へシフトしたものと、1の論理績& をとったものを表示
<以下略>
-------------------------------------------------------------
これをfor文か何かで実装すればいいと思います。
②その変換したものを反転させる。
③さらに、「1」を加え(2の補数とり)表示。
まず、①が良く分からないのです。
”10進数から2進数の変換するプログラム”を書いたという事ですか?
例えば、
int a = 10;
こうすれば、既に内部では2進数になっていますよ。
特にプログラムにする部分は無いと思います。
次に、②は補数演算子~ を使えばいいと思います。
③は、単純に1を足して、
表示する時は、
-------------------------------------------------------------
11ビット右へシフトしたものと、1の論理績& をとったものを表示
10ビット右へシフトしたものと、1の論理績& をとったものを表示
9ビット右へシフトしたものと、1の論理績& をとったものを表示
8ビット右へシフトしたものと、1の論理績& をとったものを表示
<以下略>
-------------------------------------------------------------
これをfor文か何かで実装すればいいと思います。
-
T.K.
Re:ビット演算
もうすでにたかぎさんが回答されているので恐縮ですが、
もう少し簡単そうに(ごつさをなくして)書きました。
たかぎさんの回答がベースです。
#include <iostream>
#include <bitset>
std::string
compl2(int decimal)
{
std::bitset<12> bs(~decimal + 1);
return bs.to_string();
}
int
main()
{
std::cout << compl2(123) << std::endl;
return 0;
}
VC++では通りますがBCCでは通りません。
書いておいてなんですが、conioさんの仰っている様な感じでシフト演算するのが
先生の期待している回答かもしれませんね。-
たかぎ
Re:ビット演算
> VC++では通りますがBCCでは通りません。
それは、
> return bs.to_string();
この部分に移植性がないからです。
移植性を持たせるには、
return bs.to_string<char, std::char_traits<char> >();
としなければなりません。
ところで、整数値のまま2の補数を求めてよいのであれば、
> シフト演算するのが
> 先生の期待している回答かもしれませんね。
それを質問内容から読み取るのは困難ですが、一般論で言えば、bitsetで済むものをわざわざスクラッチで実装する意味はありません。
自立処理系とかなら話は別ですが...。
それは、
> return bs.to_string();
この部分に移植性がないからです。
移植性を持たせるには、
return bs.to_string<char, std::char_traits<char> >();
としなければなりません。
ところで、整数値のまま2の補数を求めてよいのであれば、
#include <iostream>
#include <bitset>
int main()
{
unsigned value;
std::cin >> value;
std::cout << std::bitset<12>(~value + 1) << std::endl;
return 0;
}
↑で十分ですね。> シフト演算するのが
> 先生の期待している回答かもしれませんね。
それを質問内容から読み取るのは困難ですが、一般論で言えば、bitsetで済むものをわざわざスクラッチで実装する意味はありません。
自立処理系とかなら話は別ですが...。
-
T.K.
Re:ビット演算
>> たかぎさん 全て仰る通りだと思います。 移植性をなくしたのは故意です。テンプレート引数があるだけで読んで貰えなくなる と思ったので削除して、注意としてコンパイラ依存であることを記しました。 学校の問題は現実の問題とはかけ離れているので混乱しますね。 自分がシフト演算がなんたら~と書いたのは先生が10進数と2進数の変換を 手動(?)で体験させようとしているのではないかと推察したからです(体験に基づく)。 まあ結局のところ追加の情報が無いと意味のある議論はできませんね。 >> きいさん 学校のC(++)の授業で役立ちそうな参考書を紹介します。 ハッカーのたのしみ(エスアイビー・アクセス) BINARY HACKS(オライリー) きっと役に立つと思います。(2冊目は微妙かな?)
-
たかぎ
Re:ビット演算
> 移植性をなくしたのは故意です。テンプレート引数があるだけで読んで貰えなくなる
> と思ったので削除して、注意としてコンパイラ依存であることを記しました。
std::bitset::to_stringは設計ミスですよね。
C++0Xでは、明示的にテンプレート実引数を指定しなくても大丈夫になるようです。
> 自分がシフト演算がなんたら~と書いたのは先生が10進数と2進数の変換を
> 手動(?)で体験させようとしているのではないかと推察したからです(体験に基づく)。
まあ、そんな気はしますが...
それであれば、課題に明文化する必要がありますね。
あるいは、先生と学生・生徒との間に暗黙の了解があるのなら、きいさんが質問時にそれを補足する必要があります。
> と思ったので削除して、注意としてコンパイラ依存であることを記しました。
std::bitset::to_stringは設計ミスですよね。
C++0Xでは、明示的にテンプレート実引数を指定しなくても大丈夫になるようです。
> 自分がシフト演算がなんたら~と書いたのは先生が10進数と2進数の変換を
> 手動(?)で体験させようとしているのではないかと推察したからです(体験に基づく)。
まあ、そんな気はしますが...
それであれば、課題に明文化する必要がありますね。
あるいは、先生と学生・生徒との間に暗黙の了解があるのなら、きいさんが質問時にそれを補足する必要があります。