• ベストアンサー

C言語で確保できるビットの桁数

C言語でビット単位でデータ操作する際に、確保できるビットの桁数はたとえば以下のような例の場合 unsigned char bit; 1バイト(=8ビット)なので8桁ということは勉強しました。 ここで、たとえば計算でビットの桁数を100桁用意したい場合 以下のように32*4桁という風に分ける方法しかないのでしょうか? unsigned int bit[4]; できれば一つの変数で済ませたいのですが、何か良い方法をご存知の方いらっしゃいましたらよろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • lesskey
  • ベストアンサー率33% (66/200)
回答No.4

根本的な解決ではないですが・・・次の式で出来るかも? ------------------------------------------------ unsigned int math[4]; unsigned int shift; // シフト用 ~ 中略 ~ for (i=0 ; i < 100 ; i++){ shift = i & 0x1F; // 0~31までがシフト範囲 if(math[i >> 5] >> shift == 1) printf("%d", i) } ※int型は4バイト、1バイト=8ビットとする。 ------------------------------------------------ 出席番号は以下の通りになります。 math[0] ... 0~31番 math[1] ... 32~63番 math[2] ... 64~95番 math[3] ... 96~99(MAX127)番 ・・・最近はVB4の保守ばっかやってるので もしかしたら構文がおかしいかもしれません。(^-^;) 以上、頑張ってください。

その他の回答 (7)

回答No.8

単純に 100bit 準備したいのであれば、ビットフィールドという手もあることはあります。 strcut member_list_type { unsigned int no1 : 1; unsigned int no2 : 1; unsigned int no3 : 1; …… unsigned int no99: 1; unsigned int no100: 1; }; strcut member_list_type members; とすれば、 member.no1 = 0; 等とできます。それぞれは、1bit の領域を持ちます。 でも、これでは配列として扱うこともできませんし多分不便でしょう。 unsigned int bit[4]; でまかなう場合には、配列風に扱えるような関数を一式定義するのが常套手段です。 set_bit(unsigned int bit[], int n); // bit[] の先頭から数えて、n bit めをセットする clr_bit(unsigned int bit[], int n); // bit[] の先頭から数えて、n bit めをクリアする unsinged int test_bit(unsigned int bit[], int n); // bit[] の先頭から数えて、n bit めの値を返す これで、 if(test_bit(bit, 3) == 0) set_bit(bit, 3); のようなことはできます。 さらに、No.7 で提示されているような方法だと struct kamoku_list_type { unsingned int kamoku1: 1; unsingned int kamoku2: 1; unsingned int kamoku3: 1; }; strcut kamoku_list kamoku[100]; で、n番目の人の科目は、 kamoku[n].kamoku1 などで参照できます。 さらに、現在では多くの場合、「データをビットで扱う」必要はほぼないと思います。 int kamoku[100] で普通に、1 や 0 を代入/テストする方が動作としても速くなることが多いですし。

accum
質問者

お礼

とりあえずビットを複数用意する方法と、配列で確保する方法を比べながら、自分に会った方を選んでいきたいと思います。 みなさまありがとうございました。大変勉強になりました。

  • yukigle
  • ベストアンサー率14% (9/63)
回答No.7

そもそもイメージが逆と思いますが。 出席番号分100ビット化するのではなく、履修科目分、数ビット化すればよいのかと。この場合だと、配列が100となりますが、お気に召されませんでしょうか。 出席番号をnとし、bit(n)のビット0、1で履修なら1の各科目フラグとすると、bit(n)が3なら両方、0でないなら1科目以上となります。 これなら、何教科も追加できますよ。何ビットも余ってますから。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.6

>配列(例:bit[4])でもできますが、出席番号を求めるときなどは、場合分けが必要になるため、なるべく1つの変数で行いたいのですが、難しいようですね…。 なるほど、そういうことですか。1つの変数で、最大のビットをもつものは、long long int型で64ビットがありますので、64人分までなら可能ですが、64人以内に限定することは、あまりよくないですね。 ここで、考え方をもっとシンプルにして、char型でデータをもち、1バイトで、1人分のデータにしては、どうでしょうか。 例えば、char math[100];とjapanese[100];を定義し、履修あり=1、履修無し=0とします。 数学を履修している人の出席番号(0~99)は for (i=0 ; i < 100 ; i++){ if (math[i] == 1) printf("%d,",i); } で簡単にあらわすことができます。 この場合は、無理に1ビットで1人の状態を表す必要はないかと思います。 ビットにした方がよい場合は、非常に多くの出席番号(例えば1万以上)があて、データのサイズを節約したい場合などがありますが。 ビットにした場合は、#5の方のようになるかと思います。

  • lesskey
  • ベストアンサー率33% (66/200)
回答No.5

普通に原文ソースを写し間違えそのまま編集してました。(^-^;) 以下、ANo.4の修正箇所となります。 誤) if(math[i >> 5] >> shift == 1) printf("%d", i) 正) if ( (math[i >> 5] >> shift)%2 == 1) printf("%d,",i);

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

> unsigned char bit; > 1バイト(=8ビット)なので8桁ということは勉強しました。 char型(unsigned charでも同じ)のビット数は、<limits.h>で定義されるCHAR_BITマクロで表されます。CHAR_BITマクロの値は8以上であり、これが1バイトのビット数になります。したがって、1バイトが9ビットであったり、16ビットや64ビットの環境も存在します。 > 以下のように32*4桁という風に分ける方法しかないのでしょうか? > unsigned int bit[4]; これも、unsigned int型のビット数は少なくとも16ビット以上ですので環境に依存します。確実に100ビット以上を確保するには、 unsigned char bit[(100+CHAR_BIT-1)/CHAR_BIT]; とする必要があります。 また、基本型で100ビット以上を確保するための一般的な方法はありませんが、処理系によっては__int128_tといった型が存在する場合がありますし、unsigned long long型が100ビット以上ある可能性もなくはないので、一通り調べてみてください。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.2

>unsigned char bit; >1バイト(=8ビット)なので8桁ということは勉強しました。 はい、それであってますよ。 >ここで、たとえば計算でビットの桁数を100桁用意したい場合 >以下のように32*4桁という風に分ける方法しかないのでしょうか? >unsigned int bit[4]; はい、そのようにするのが普通です。 >できれば一つの変数で済ませたいのですが どうして、そのような質問をされたのかを書かれると、よい回答が得られやすくなります。 かってな推測ですが、非常に大きな数値を扱いたいのでしょうか。 もし、そうであれば、それは、小数点以下の値を含む実数でしょうか、それとも整数でしょうか。

accum
質問者

お礼

質問内容がわかり難くて申し訳ございません。 問題の例として たとえば生徒が100人(出席番号0~99)いたとして、選択科目の国語と数学を履修しているとします。 これをそれぞれの科目を履修しているかしていないかをビットで表すとして、履修している人を1、していない人を0とすると 変数japanese(国語)とmath(数学) japanese = 10000001000…0001; math = 11100110011…0101; とデータ化しておき 両方履修している人 = japanese & math; 1科目以上履修している人 = japanese | math; 数学を履修している人の出席番号 for (i=0 ; i < 100 ; i++){ if ( (math >> i)%2 == 1) printf("%d,",i); } という風に利用したいと考えています。 配列(例:bit[4])でもできますが、出席番号を求めるときなどは、場合分けが必要になるため、なるべく1つの変数で行いたいのですが、難しいようですね…。

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.1

> 1バイト(=8ビット)なので8桁 1バイトが8ビットでない環境もあるように聞いています。 _lim.h かどこかで定義している CHAR_BIT の値(8かもしれないし、 8以外かもしれない)を確認する方がよいのではないかと思います。 > unsigned int bit[4]; > できれば一つの変数で済ませたいのですが bitという、一つの変数ですんでいますけれど…。 添字を使いたくない、ということでしょうか?むずかしいのではないかな…。