
3進数や5進数のように2の階乗ではない任意の進数の文字列を、C言語のビットシフトを使って10進数に変換するプログラムについて、質問させていただきます。
ビットシフトを使わないで、任意の進数の文字列を10進数に変換する方法は分かっていますが、ビットシフトを使った方が非常に計算が高速で出来るので、ビットシフトを使いたいと思っています。
下記のプログラムは4進文字列を10進整数に変換するものです。2進、8進文字列の場合は、シフトするビット数を1ビット、3ビット(つまり、ans <<= 1、ans <<= 3)にすれば計算することが可能です。しかし、3進数や5進数の場合、いろいろと考えたのですが、どのようにすれば良いのか分かりません。
下記のプログラムのようにビットシフトを使って3進数や5進数の文字列を10進数に変換するには、どのように工夫すれば良いでしょうか? どなたかご教授をお願いいたします。
#define STRING_NUM 2/*文字列の長さ*/
int main(void)
{
int i;
int ans = 0;/*10進数の整数*/
char buf[STRING_NUM];/*4進数の文字列*/
buf[0] = '3';
buf[1] = '1';
for ( i = 0 ; i < STRING_NUM; i++ ){
printf(" %c", buf[i]);
}
printf("\n");
for ( i = 0 ; i < STRING_NUM; i++ ){
if ( buf[i] == '0' ){
ans <<= 2;/*シフトするビット数*/
ans |= 0;
}
if ( buf[i] == '1' ){
ans <<= 2;
ans |= 1;
}
if ( buf[i] == '2' ){
ans <<= 2;
ans |= 2;
}
if ( buf[i] == '3' ){
ans <<= 2;
ans |= 3;
}
}
printf( "ans = %d\n", ans );
return 0;
}
No.6ベストアンサー
- 回答日時:
この実行環境はなんでしょう?
コンパイラはなんでしょう?
・例えば、a*3は、内部では
(a << 1) + (a << 0)
a*5は
(a << 2) + (a << 0)
と計算されている可能性が高いです。
・CPU等の回路構成では、上のような乗算を回路で高速に演算できるようになっています。
ビットシフトを自分で書くより高速でしょう。
・コンパイラの種類や設定によってできるオブジェクトは変わりますが
乗算はCPUに専用命令があるなら、それを積極的に使おうとするでしょう。
プログラム中でシフト+加算で書いてあったら、乗算に置き換えてくれることはまず無いでしょう。
これが、8bitマイコン用、とかなら、自分でシフト使った方が早いかもしれませんが、PCに入っているようなものだったら、素直に乗算使った方が速いのではないでしょうか
引き続きの回答有り難うございます。
以前、ビットシフトの方が単なる掛け算をするより早いという話を聞いたことがあったので、ずっと今もそういういものだと信じ込んでいました。調べてみると、昔は確かにそうだったようですが、今はKmeeさんがご指摘の通り、大きな差はないようです。
ご指摘ありがとうございました。
No.5
- 回答日時:
話の途中で送ってしまいましたが、
言いたい事は、ビットシフトしているから早いのではなく
指定した桁を指定した位置に置いてるだけ
指定した位置にを実現するのにビットシフトを使っているだけです
なので、3ビットやら5ビットやらはそもそも
指定した位置に置くだけではそもそも違う値なので
ビットシフトでどうにかなるものではないです
まぁ2つ一致しない2進数をさらなるビットシフトでどうにか
できるのなら話は別ですが、その法則を導き出す
なら、演算したほうが早いです。
No.4
- 回答日時:
4進数=2進数=10進数
000 = 00-00-00 = 0
001 = 00-00-01 = 1
002 = 00-00-10 = 2
003 = 00-00-11 = 3
010 = 00-01-00 = 4
011 = 00-01-01 = 5
012 = 00-01-10 = 6
013 = 00-01-11 = 7
020 = 00-10-00 = 8
021 = 00-10-01 = 9
022 = 00-10-10 = 10
023 = 00-10-11 = 11
030 = 00-11-00 = 12
031 = 00-11-01 = 13
032 = 00-11-10 = 14
033 = 00-11-11 = 15
100 = 01-00-00 = 16
101 = 01-00-01 = 17
4進数 = 2進数 =10進数
2進数は判りやすいように2桁毎にハイフンで区切って表示してます。
8進数の場合は、3桁区毎にハイフンで区切れば同じような表が出来ます
これと同じ表を、3進数で作るとどうなるか
000 = 00-00-00 = 00-00-00 = 0
001 = 00-00-01 = 00-00-01 = 1
002 = 00-00-10 = 00-00-10 = 2
010 = 00-01-00 ≠ 00-00-11 = 3
011 = 00-01-01 ≠ 00-01-00 = 4
012 = 00-01-10 ≠ 00-01-01 = 5
020 = 00-10-00 ≠ 00-01-10 = 6
021 = 00-10-01 ≠ 00-01-11 = 7
022 = 00-10-10 ≠ 00-10-00 = 8
100 = 01-00-00 ≠ 00-10-01 = 9
101 = 01-00-01 ≠ 00-10-10 = 10
102 = 01-00-10 ≠ 00-10-11 = 11
110 = 01-01-00 ≠ 00-11-00 = 12
111 = 01-01-01 ≠ 00-11-01 = 13
112 = 01-01-10 ≠ 00-11-10 = 14
210 = 10-01-00 ≠ 00-11-11 = 15
211 = 10-01-01 ≠ 01-00-00 = 16
212 = 10-01-10 ≠ 01-00-01 = 17
こうなります
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
0xffffとは?
-
8ビットのデータの、先頭ビット...
-
CASL2(減算命令と比較命令の...
-
エクセルVBAのIf,Then 構...
-
整数除算の意味とは?
-
文字参照は10進数と16進数では...
-
2の補数
-
一般のソフトで画像を扱う場合...
-
ビットシフトってどんな時使うの?
-
シーケンサのデータレジスタD...
-
実行ファイルからソースはみれる?
-
レジストってなんですか?
-
Delphiでの関数の戻り値を別の...
-
SRAMとレジスタの違いは何でし...
-
アセンブラ言語がわかりません。
-
void __cdeclなど_
-
マシン語で再起動を書くには?
-
GCCの.cfi_系について
-
アセンブラのLA
-
CPUは何故、16bit→32bit→64bit...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
0xffffとは?
-
8ビットのデータの、先頭ビット...
-
C言語で128bitの2進数のビット...
-
ビットシフトってどんな時使うの?
-
「ひまわり」と「なでしこ」の違い
-
[VBS] 素早くローテート演算したい
-
一般のソフトで画像を扱う場合...
-
文字参照は10進数と16進数では...
-
アセンブラプログラムの「数値...
-
x86のJP命令について。
-
命令について
-
VB.net
-
03分22秒36のような時間の単位...
-
verilog 符号付加減算(最上位...
-
e(自然対数の底)を100桁以上出...
-
代入の書き方で質問です。
-
マイクロコンピューター制御の...
-
光コンピュータについて
-
アセンブリの論理演算命令のCPL...
-
符号無し整数xを右にnビット回転
おすすめ情報