C言語関係掲示板

過去ログ

No.531.ローテート(intのビット数)

[戻る] [ホームページ]
No.4274

ローテートについて
投稿者---cross-over(2003/01/09 18:35:47)


またローテートについてなんですが、前回と同様に呼び出されるたびに1つずつ左にローテートする関数int lrotate(int)と右に1つずつローテートする関数int rrotate(int)を作成したいんですが、まだC言語を独学でやり始めたばかりなのでよく分かりません。できたらプログラムを完成させてくれませんか。ぜんぜん勉強が進まなくて困っているんです。よろしく御願いします。

No.4277

Re:ローテートについて
投稿者---aki(2003/01/09 20:44:53)


#define MSB (~(~0U >> 1))

int lrotate(int x)
{
    return (x << 1) | !!(x & MSB);
}

int rrotate(int x)
{
    return ((unsigned)x >> 1) | ((x & 01) ? MSB : 0);
}

これは別の方法です。

int int_bits(void)
{
    int i = 0, x = ~0;
    while (x)
        i++, x <<= 1;
    return i;
}

int lrotate(int x)
{
    return (x << 1) | ((unsigned)x >> (int_bits() - 1));
}

int rrotate(int x)
{
    return ((unsigned)x >> 1) | (x << (int_bits() - 1));
}


No.4278

Re:ローテートについて
投稿者---cross-over(2003/01/09 21:12:20)



ありがとうございました。よく復習したいと思います

No.4302

Re:ローテートについて
投稿者---かずま(2003/01/11 20:07:43)


> これは別の方法です。
> 
> int int_bits(void)
> {
>     int i = 0, x = ~0;
>     while (x)
>         i++, x <<= 1;
>     return i;
> }
int のビット数はヘッダファイル <limits.h> に書かれている
CHAR_BIT と sizeof(int) の積で、コンパイル時に分かるのに、
実行時に毎回計算し直しているのはなぜですか。また、x = 1;
でいいはずなのに、わざわざ x = ~0; としているのはなぜですか。
初心者の勉強のためでしょうか。

もう一度、私のコードを示します。
#include <limits.h>

#define N  (sizeof(int) * CHAR_BIT - 1)

int lrotate(int x) { return (unsigned)x>>N | x<<1; }

int rrotate(int x) { return (unsigned)x>>1 | x<<N; }


No.4304

Re:ローテートについて
投稿者---aki(2003/01/11 21:56:36)


>int のビット数はヘッダファイル <limits.h> に書かれている
>CHAR_BIT と sizeof(int) の積で、コンパイル時に分かるのに、
>実行時に毎回計算し直しているのはなぜですか。

以前別の掲示板で教えていただいたのですが、int のビット数は char の
ビット数の整数倍とは限らないらしいのです。このページを教えてもらい
ました。(int が16ビット未満という点はおかしいんですけど。)

    http://www.bohyoh.com/CandCPP/FAQ/FAQ00018.html

このようなやり方で int のビット数をわざわざ計算しているのを、本など
でもたまに見かけます。

>また、x = 1;でいいはずなのに、わざわざ x = ~0; としているのはなぜですか。
>初心者の勉強のためでしょうか。

x = 1 でも良いということには気が付いていませんでしたが、x = ~0 よりも
x = 1 の方が良いと考える理由は何でしょう。

>int i = 0, x = ~0;
>while (x)
>    i++, x <<= 1;

私はこんなふうに考えています。
「x = ~0 で int 型オブジェクトのビットを全部セットし、x <<= 1 で一つ消
すと同時に i++ でその消した分をカウントする。全部消えたらループを出る。」


No.4305

Re:ローテートについて
投稿者---aki(2003/01/11 22:03:37)


>私はこんなふうに考えています。
>「x = ~0 で int 型オブジェクトのビットを全部セットし、x <<= 1 で一つ消
>すと同時に i++ でその消した分をカウントする。全部消えたらループを出る。」

いや、正確に言うとこれを書いたときは、この通りには考えていなかったと思い
ます。本当にこう考えていたなら、i++, x <<= 1; ではなく、x <<= 1, i++ と
書いていたと思います。どうでもいいと言われそうですが。


No.4342

Re:ローテートについて
投稿者---かずま(2003/01/13 15:25:16)


> 以前別の掲示板で教えていただいたのですが、int のビット数は char の
> ビット数の整数倍とは限らないらしいのです。このページを教えてもらい
> ました。(int が16ビット未満という点はおかしいんですけど。)
>
> http://www.bohyoh.com/CandCPP/FAQ/FAQ00018.html

それは、規格に従っていない C のことでしょう。

規格に従えば、int のビット数は char のビット数の整数倍です。
ANSI の 1.6 Definitions of Terms (JIS なら 3.用語の定義及び規約) の
ところに、ビット、バイト、オブジェクトの定義があり、ビットフィールド
以外のオブジェクトは、1バイト以上が連続するものとなっています。


> x = 1 でも良いということには気が付いていませんでしたが、x = ~0 よりも
> x = 1 の方が良いと考える理由は何でしょう。

左シフトで、最初の x の LSB 以外のビットが捨てられ、最後に LSB が
消えたことを判定して、ビット数を数えるのだから、捨てられるビットを
わざわざ 1 にする必要はありませんね。 x = 1; で 十分であり、
x = ~0; はちょっとひっかかるという程度のことです。

unsigned int の右シフトで MSB が消えることにより、ビット数を数えるの
だったら、x = ~0; でよいでしょう。x = ~(~0u >> 1); は複雑ですから。

No.4361

Re:ローテートについて
投稿者---aki(2003/01/14 17:33:54)


>> 以前別の掲示板で教えていただいたのですが、int のビット数は char の
>> ビット数の整数倍とは限らないらしいのです。このページを教えてもらい
>> ました。(int が16ビット未満という点はおかしいんですけど。)
>> 
>> http://www.bohyoh.com/CandCPP/FAQ/FAQ00018.html
>
>それは、規格に従っていない C のことでしょう。
>
>規格に従えば、int のビット数は char のビット数の整数倍です。
>ANSI の 1.6 Definitions of Terms (JIS なら 3.用語の定義及び規約) の
>ところに、ビット、バイト、オブジェクトの定義があり、ビットフィールド
>以外のオブジェクトは、1バイト以上が連続するものとなっています。

いいえ。オブジェクトの最小単位はバイトですが、オブジェクトを構成する
すべてのビットが値を表現するために使われているとは限らないようです。
つまり、オブジェクトはその中に padding bits をもっても良いということ
です。こちらを読んでみてください。

    http://dbforums.com/t583479.html

>> x = 1 でも良いということには気が付いていませんでしたが、x = ~0 よりも
>> x = 1 の方が良いと考える理由は何でしょう。
>
>左シフトで、最初の x の LSB 以外のビットが捨てられ、最後に LSB が
>消えたことを判定して、ビット数を数えるのだから、

私はそのようには考えていません。立てたビットを集合の要素(~0は空集合の
補集合)と考え、右端の要素を消しながら 1、2、3... と要素数を数えている
つもりです。

>捨てられるビットをわざわざ 1 にする必要はありませんね。 x = 1; で 十分であり、
>x = ~0; はちょっとひっかかるという程度のことです。

x = ~0 でも x = 1 でも効率は同じですよね。すべてのビットをセットするのに
手間はかからないので、「わざわざ」といわれると考え込んでしまいます。プロ
グラムの見方(どのような方法で数えていると見るか)によってそう感じるのでし
ょうか。かずまさんはビットが置かれるべき「場所」を数えていると考えている
(?)のに対し私は「ビットそのもの」を数えていると考えている、と。私の考え
は不自然でしょうか。


No.4433

Re:ローテートについて
投稿者---かずま(2003/01/17 20:43:38)


> いいえ。オブジェクトの最小単位はバイトですが、オブジェクトを構成する
> すべてのビットが値を表現するために使われているとは限らないようです。
> つまり、オブジェクトはその中に padding bits をもっても良いということ
> です。こちらを読んでみてください。
>
> http://dbforums.com/t583479.html

面白いページを紹介していただき、ありがとうございました。

しかし、ここでの議論は、型の持つビット数と、値の表現に必要なビット数を
混同しているように、私には読めました。

long型が 32 ビットでも、1ビットは符号ビットだから、31ビットが値を表現する
もので、sizeof(long) * CHAR_BIT では、その 31 が求められないと言っている
ようです。

aki さんの int_bits() でも、値の表現に必要なビット数は求められないのでは
ないでしょうか。

私は、型の持つビット数という意味で、sizeof(int) * CHAR_BIT は、規格に準拠
した C では、問題ないと考えています。


> x = ~0 でも x = 1 でも効率は同じですよね。すべてのビットをセットするのに
> 手間はかからないので、「わざわざ」といわれると考え込んでしまいます。プロ
> グラムの見方(どのような方法で数えていると見るか)によってそう感じるのでし
> ょうか。

プログラムの実行時間という意味での効率ではなく、プログラムを読む人間にとっ
て、 x = ~0; の意味を解釈するのに、ひと呼吸余分に時間が掛かるということです。

x = 1; なら、単純に x に 1 をセットする。

x = ~0; は、0 のビットパターンの反転し、すべてのビットを立ててから、x に
それをセットする。


> かずまさんはビットが置かれるべき「場所」を数えていると考えている
> (?)のに対し私は「ビットそのもの」を数えていると考えている、と。私の考え
> は不自然でしょうか。

左シフトだと一番右端の 1 が消えるまで、何回シフトするかを数えているとし
か、私には見えません。一番右端以外は、数えずに捨てているのですから。
int int_bits(void)
{
    int i = 0, x = ~0;

    while (x) {
        if (x & 0x80000000) i++;
        x <<= 1;
    }
    return i;
}
int_bits() がこのように書かれていれば、ビットそのものを数えているように
見えます。もちろん、このコードはだめですよ。ビット数を数えるのに、int の
ビット数を 32ビットだと仮定しているのですからね。

また、今、最初の私のコメントを読み直してみると、~0 と 1 の違いというより
も、1ビットのローテートに、毎回毎回 int_bits() を呼び出して、多数のシフト
を繰り返してビット数を求めることにあきれて、その思いが「わざわざ」という
言葉になったようです。入れる場所を間違えたのかも。

No.4443

Re:ローテートについて
投稿者---aki(2003/01/18 00:37:42)


>面白いページを紹介していただき、ありがとうございました。
>
>しかし、ここでの議論は、型の持つビット数と、値の表現に必要なビット数を
>混同しているように、私には読めました。
>
>long型が 32 ビットでも、1ビットは符号ビットだから、31ビットが値を表現する
>もので、sizeof(long) * CHAR_BIT では、その 31 が求められないと言っている
>ようです。

明らかに読み間違いをされていると思います。下に訳してみました。

------- John ------------------------------------------------------------

int bits = sizeof(long) * CHAR_BIT; /* 32 on my system */
Is this a portable way to find out how many bits are in a given type?

これは与えられた型の中にいくつのビットがあるかを調べる可搬性のある方法
でしょうか?

------- Kevin Easton ----------------------------------------------------
John wrote:
  > int bits = sizeof(long) * CHAR_BIT; /* 32 on my system */
  > 
  > Is this a portable way to find out how many bits are in a given type?

Yes. However, this number is almost useless, because it may include
padding bits, so you can't necessarily extrapolate from the number of
bits to the range of the type.

はい、そうです。でもこの数字はたいてい役に立ちません。なぜなら、パディン
グビットを含んでいるかもしれないからです。だからあなたは必ずしもその数字
からその型(で表現できる値)の範囲を外挿(既知の数字などから未知の数字を推定
すること)する事は出来ません。

------- Emmanuel Delahaye -----------------------------------------------
In 'comp.lang.c', "John" wrote:

  > int bits = sizeof(long) * CHAR_BIT; /* 32 on my system */
  > 
  > Is this a portable way to find out how many bits are in a given type?

No. Only a char is both defined in number of bits and by a range. All the 
other types are only defined by a range in for integer and in 
for floating points.

いいえ、ちがいます。char型だけがビット数と範囲の両方で定義されています。
その他のすべての型は範囲でのみ定義されています。(in for の訳し方がわから
ないので in for 以降を無視した。)

------- Rjh -------------------------------------------------------------

John wrote:

  > int bits = sizeof(long) * CHAR_BIT; /* 32 on my system */
  > 
  > Is this a portable way to find out how many bits are in a given type?

Not quite. :-(

size_t bits = sizeof(long) * CHAR_BIT is better, *but* it doesn't mean quite 
what you might think. It will give you the right number of bits, but this 
will include not only the value bits, but also the sign bit (in the case of 
types where this is meaningful) and any padding bits that the 
implementation might choose to incorporate into the type.

完全に可搬性があるわけではありません。

size_t bits = sizeof(long) * CHAR_BITとした方がもっと良いですが、でもこれは
必ずしもあなたが期待しているものを意味しません。この式はビットの正しい個数を
与えますが、それは値の表現に使われるビットだけでなく、符号ビット(符号が意味
をもつ型の場合)や処理系がその型に組み入れたパディングビットを含むかもしれま
せん。

------- Christian Bau ----------------------------------------------------
In article ,
"John" wrote:

  > int bits = sizeof(long) * CHAR_BIT; /* 32 on my system */
  > 
  > Is this a portable way to find out how many bits are in a given type?

There are degrees of portability. It will give the correct answer on 
many C implementations, but not on all. 

可搬性には程度があります。その方法は多くのCの処理系で正しい答えを与える
でしょう。でもすべての処理系ではありません。

There is for example one DSP processor that has 40 bit long which is 
stored in 64 bits. Variable "bits" will be 64, but only 40 bits can be 
used. 

例えば64ビットの中に収納された40ビットのlong型をもつDSPプロセッサがあり
ます。変数のビット数は64なのでしょう、でも40ビットだけが使用可能です。

And very hypothetically, you could have a C implementation with 16 bit 
int and 32768 bit long :-)

また、非常に仮定的な話ですが、16ビットのintと32768ビットのlongをもつCの
処理系もありえます。:-)

--- 続きがあります ---


No.4444

Re:ローテートについて
投稿者---aki(2003/01/18 00:41:12)


続きです

------- Dan Pop↓ -------------------------------------------------------
In Emmanuel Delahaye writes:

  >In 'comp.lang.c', "John" wrote:
     >> int bits = sizeof(long) * CHAR_BIT; /* 32 on my system */
     >> 
     >> Is this a portable way to find out how many bits are in a given type?
  >No. Only a char is both defined in number of bits and by a range.

Nope, it is unsigned char that has this property. Plain char may have
padding bits, like any other type.

うんにゃ。この属性をもつのは unsigned char です。'単なるchar'は他のすべての型
と同じく、パディングビットをもつかもしれません。

------- Dan Pop↓ ------------------------------------------------------------
In rjh writes:

  >John wrote:
     >> int bits = sizeof(long) * CHAR_BIT; /* 32 on my system */
     >> 
     >> Is this a portable way to find out how many bits are in a given type?
  >Not quite. :-(
  >size_t bits = sizeof(long) * CHAR_BIT is better,

Or worse, depending on the relationship between INT_MAX and (size_t)-1 :-)
In practice, neither is better or worse than the other.

より悪いともいえます。INT_MAX と (size_t)-1 の関係次第では。:-)
実際には、どちらがどちらより良くも悪くもありません。

-------  Dan Pop↓ ----------------------------------------------------------
In "John" writes:

  >int bits = sizeof(long) * CHAR_BIT; /* 32 on my system */
  >Is this a portable way to find out how many bits are in a given type?

It is a portable method of obtaining the size in bits of a type.

その方法は型のビット単位のサイズを得るための可搬性のある方法です。

However, this value is not particularly useful, because you have no
guarantee that all the bits contribute to the actual value (well, in
your particular example you have, because a long can't have less than
31 value bits and one sign bit).

しかし、その値は特に役に立つ値ではありません。なぜなら、そのすべての
ビットが本当の値に対して貢献しているという保証はないからです(ところで、
あなたが示した特別な例ではこの保証があります。なぜならlong型は31ビット
と符号の1ビットより少ないビット数を持つことはありえないからです)。

Besides value bits and sign bit, you can also have padding bits, which 
you can count, but you cannot directly access (you must alias your long
with an array of unsigned char to get at them). You can figure out the
number of padding bits by computing the number of value bits (from
LONG_MAX, defined in ). Just subtract this number and one
for the sign bit from sizeof(long) * CHAR_BIT.

値のビットと符号ビットに加えて、パディングビットがあるかもしれません。そ
のパディングビットの数を数えることはできますが、それに直接アクセスするこ
とは出来ません(アクセスする為には long を unsigned char の配列でaliasしな
ければならない)。あなたは値のビット数を(LONG_MAXを使って)計算することによ
ってパディングビットの数を求めることが出来ます。値のビット数と符号ビット
分の1を sizeof(long) * CHAR_BIT から引くだけです。

Note that, in practice, hosted implementations using padding bits
are few and far between.

実際のところ、パディングビットを使っているホスト処理系はわずだという
ことに注意してください。


No.4452

Re:ローテートについて
投稿者---かずま(2003/01/18 14:17:03)


> 明らかに読み間違いをされていると思います。下に訳してみました。

その訳のどの部分をどう読み違いしているのかを、指摘していただきたいの
ですが、その前にもう一度問題を整理してみます。

まず、発端はローテートですが、これについては置いておいて、
int 型のビット数をどうやって知るかという問題に焦点を当てます。
配列や構造体を含む一般の型についてではありません。int型についてです。

(1) #include <limits.h> で、sizeof(int) * CHAR_BIT
(2) int_bits() という関数を用意する。

aki さんが、(1)はだめで (2)のほうがよい、とする理由は、
int のビット数が char のビット数の整数倍とは限らないから、ということ
ですね。しかし、その根拠として挙げた
http://www.bohyoh.com/CandCPP/FAQ/FAQ00018.html では、int が 12ビット
の処理系という規格はずれのものに対応しようとしています。

次に、http://dbforums.com/t583479.html ですが、最初の質問、
------- John ------------------------------------------------------------
int bits = sizeof(long) * CHAR_BIT; /* 32 on my system */
Is this a portable way to find out how many bits are in a given type?

ここで、John は、long を例に挙げ、a given type という一般の型のサイズに
ついて、そのビット数の数え方がこれでいいのか尋ねています。

この時点で、int 型のビット数を数えることから離れているので、その後の議論は
(1)か (2)かという問題には関係ありません。

(1)はだめで (2)のほうがよい、とする理由を、規格はずれの処理系にも対応する
ためとするのなら、私は何も言いません。

No.4454

Re:ローテートについて
投稿者---カンナ(2003/01/18 14:59:55)
http://hana.sakura.ne.jp/~elfin/k/


>(1) #include <limits.h> で、sizeof(int) * CHAR_BIT
>(2) int_bits() という関数を用意する。

 CHAR_BITが8でintが20bitの場合には規格準拠ですが(1)ではintの
ビット数を求められません。従って私は「(1)はだめで (2)のほうがよい」と
判断します。

No.4456

Re:ローテートについて
投稿者---かずま(2003/01/18 16:31:37)


>  CHAR_BITが8でintが20bitの場合には規格準拠ですが(1)ではintの
> ビット数を求められません。従って私は「(1)はだめで (2)のほうがよい」と
> 判断します。

CHAR_BITが 8で intが 20bitの場合には規格準拠ではありません。

ANSI の規格書には Rationale が付属していて、これには、なぜ
規格がそのように決められたかという根拠が書かれています。

例えば、http://www.lysator.liu.se/c/rat/a.html#1-6 を見ると、

1.6 Definitions of terms

The definitions of object, bit, byte, and alignment reflect a strong
consensus, reached after considerable discussion, about the fundamental
nature of the memory organization of a C environment:

All objects in C must be representable as a contiguous sequence of bytes,
each of which is at least 8 bits wide.

A char (or signed char or unsigned char) occupies exactly one byte.
(Thus, for instance, on a machine with 36-bit words, a byte can be
defined to consist of 9, 12, 18, or 36 bits, these numbers being all the
exact divisors of 36 which are not less than 8.) These strictures codify
the widespread presumption that any object can be treated as an array
of characters, the size of which is given by the sizeof operator with that
object's type as its operand.

したがって、int が 20ビットの場合には、CHAR_BIT は 10 か 20 にならないと
規格準拠ではありません。

No.4458

Re:ローテートについて
投稿者---カンナ(2003/01/18 18:19:01)
http://hana.sakura.ne.jp/~elfin/k/


 CHAR_BITが8でintが20bitの場合でも:

>All objects in C must be representable as a contiguous sequence of bytes,
>each of which is at least 8 bits wide.

…を満たすことは可能です。例えば4bitをpadding bitとすればintは24bitで
representできます。representに使用する全てのbitを値そのものの表現に
使用する必要はありませんよね? 例えばこの4bitを5bitごとのパリティに
用いてもやはり規格準拠だと思います。

No.4476

Re:ローテートについて
投稿者---かずま(2003/01/19 17:43:28)


> …を満たすことは可能です。例えば4bitをpadding bitとすればintは24bitで
> representできます。representに使用する全てのbitを値そのものの表現に
> 使用する必要はありませんよね? 例えばこの4bitを5bitごとのパリティに
> 用いてもやはり規格準拠だと思います。

わかりました。そういうハードウェアを作れば、規格準拠だといえるでしょう。
いや、実際にそういうものが既にあるのかもしれませんが、私は知りません。
オブジェクトが自分の型を知るために、タグを持つアーキテクチャがあることは
聞いたことがあるんですが、.....

納得のいく説明をいただき、ありがとうございました。

No.4467

Re:ローテートについて
投稿者---aki(2003/01/19 03:43:28)


comp.lang.c の問題のスレッドの記事を読んで考えてみると、int のビット
数は sizeof(int) * CHAR_BIT の値と等しく、次の式で表せるということに
なると思います。[]は無いかもしれないという事を表しています。

intのビット数 = [パディングビット] + 1ビットの符号ビット + 値のビット

私は「int のビット数は char のビット数の整数倍とは限らない」と書きま
したが、この部分は正確にいうと間違っているので訂正させてください。
「int型がもっているビット数のうち実際に使用されるビット数は CHAR_BIT
 の整数倍であるとは限らない」とすべきでした。

>その前にもう一度問題を整理してみます。
>まず、発端はローテートですが、これについては置いておいて、
>int 型のビット数をどうやって知るかという問題に焦点を当てます。
>配列や構造体を含む一般の型についてではありません。int型についてです。

>(1) #include <limits.h> で、sizeof(int) * CHAR_BIT
>(2) int_bits() という関数を用意する。

この問題の整理の仕方には不満があります。int 型のビット数をどうやって知
るかということなら、(1)で良いのでしょう。でも問題は int 型の「正味の」
ビット数のはずです。ローテート関数が正しく動作するためには正味のビット
数が必要なのですから。私は下のかずまさんのローテート関数が、どの規格準
拠の処理系においてでも、期待する結果を返すかどうかが問題だと考えていま
す。

>#include <limits.h>
>#define N  (sizeof(int) * CHAR_BIT - 1)
>int lrotate(int x) { return (unsigned)x>>N | x<<1; }
>int rrotate(int x) { return (unsigned)x>>1 | x<<N; }

言い換えるとこうです。

すべての規格準拠の処理系について sizeof(int) * CHAR_BIT の値は、私の
int_bits 関数が返す値と等しいか?

私は「等しいとは限らない」、かずまさんは「等しい」、ですね?

>しかし、その根拠として挙げた
>http://www.bohyoh.com/CandCPP/FAQ/FAQ00018.html では、int が 12ビット
>の処理系という規格はずれのものに対応しようとしています。

例として12という数字を使っている点は明らかにまずいですね。また、「int型
が12ビットである処理系」という所も「int型が実際に使用するビットが12ビッ
トである処理系」としないと正確ではないのでしょう。でも規格はずれのものに
対応しようとしている、という見方以外に単に例として使う数字や表現を間違え
ただけという見方もできます。

>次に、http://dbforums.com/t583479.html ですが、最初の質問、
------- John ------------------------------------------------------------
>int bits = sizeof(long) * CHAR_BIT; /* 32 on my system */
>Is this a portable way to find out how many bits are in a given type?

>ここで、John は、long を例に挙げ、a given type という一般の型のサイズに
>ついて、そのビット数の数え方がこれでいいのか尋ねています。

>この時点で、int 型のビット数を数えることから離れているので、その後の議論は
>(1)か (2)かという問題には関係ありません。

意味がわかりません。このスレッドの中で頻繁に出てくる 「padding bits」の意味
を説明して下さい。まさかこの言葉が構造体のパディングのことのみを指していると
でもお考えですか?


No.4477

Re:ローテートについて
投稿者---かずま(2003/01/19 18:10:58)


> すべての規格準拠の処理系について sizeof(int) * CHAR_BIT の値は、私の
> int_bits 関数が返す値と等しいか?
>
> 私は「等しいとは限らない」、かずまさんは「等しい」、ですね?

カンナさんの説明をうかがうまでは、int にはパディングビットがないから、
「等しい」と考えていました。


>> 次に、http://dbforums.com/t583479.html ですが、最初の質問、
> ------- John ------------------------------------------------------------
>> int bits = sizeof(long) * CHAR_BIT; /* 32 on my system */
>> Is this a portable way to find out how many bits are in a given type?
>
>> ここで、John は、long を例に挙げ、a given type という一般の型のサイズに
>> ついて、そのビット数の数え方がこれでいいのか尋ねています。
>
>> この時点で、int 型のビット数を数えることから離れているので、その後の議論は
>> (1)か (2)かという問題には関係ありません。
>
> 意味がわかりません。このスレッドの中で頻繁に出てくる 「padding bits」の意味
> を説明して下さい。まさかこの言葉が構造体のパディングのことのみを指していると
> でもお考えですか?

では、私がどう解釈したのか、順に説明します。

John は、long を例に挙げ、「一般の型」のサイズについて、そのビット数の
数え方を尋ねました。

Kelvin は、型がパディングビットを含む場合があって、その型が表現できる
値は、型全体のビット数からは類推できない、と言いました。
私はこの時点では、構造体のパディングだけを考えていました。

Emmanuel が言っていることは、具体的には、<limits.h> に、
char については、CHAR_BIT と CHAR_MIN と CHAR_MAX があるが、
int については、INT_MIN と INT_MAX はあっても、INT_BIT がない、
<float.h> で、double について、DBL_MAX、DBL_MIN はあっても、ビット数を
表すものはない、ということでしょう。

Rjh は、結果を int で受けずに size_t で受けたほうがよい、と言っていますが、
これは議論には関係ありません。次に、符号ビットとパディングビットの存在を
言っていますが、私はこの時点で、
・int や long には符号ビットがあるから、型が表現できる値は、その分小さい。
・構造体にはパディングがあるから、型が表現できる値は、その分小さい。
と言っているのだと解釈しまた。そして、符号ビットがあってもそれはシフトの
対象になりますから関係ないと考えました。

Christian が、64ビットの long を持つが 40ビットしか意味のない DSP が存在す
ると言いました。私はこれを、DSP のデータバスが 40ビットしかなく、上位のビ
ットは DSP につながる DAC や ADC との外部入出力には使われないという意味に
解釈しました。内部的には 64ビット持っているのだから、プログラムでその全ビ
ットにアクセスすることは可能だと思っていました。
int が 16ビットで、long が 32768ビットというのは、Rjh の size_t に対しての
発言で、議論には関係ありませんね。

Dan が Emmanuel に対して、unsigned char と違って char はパディングビットを
持つと言っているのは、符号ビットをパディングビットと考えているからでしょう。

Dan が Rjh に対して言っているのは、size_t が int より小さければだめだという
だけのことです。

最後に Dan が、最初の John に対して、パディングビットの存在を言っていますが、
私は、Christian の DSP のことが頭にあったので、入出力でアクセスできないだけ
で、メモリ上ではアクセスできることから、シフト演算の対象からはずされるとは
思っていませんでした。

ここにいたるまでの議論で、常に符号ビットを値の対象からはずそうとしています。
しかし、符号ビットもシフトの対象になります。パディングビットも(もしあったと
してですが)シフトの対象になる、と私が考えても不思議はないでしょう。

以上です。

また、この議論から、特殊な long があるもんだ。sizeof(long double) が 10 の
処理系もあるから、そんなものもあるかもしれない。でも int は、計算機が演算
を行うのに最も基本的な型だから、パディングビットなんかない、と考えていて、

>> この時点で、int 型のビット数を数えることから離れているので、その後の議論は
>> (1)か (2)かという問題には関係ありません。

という発言になりました。

カンナさんの説明により、パディングビットを持つ int があり得ないわけでは
ないと納得しました。

でも、Dan が最後に言った
 Note that, in practice, hosted implementations using padding bits
 are few and far between.
にあるように、「実際には、きわめてまれな」ですね。
実際にあったら教えて欲しいよ、といいたくなるぐらいです。


ところで、aki さんの int_bits() ですが、x = 1 でも、x = 3 でも、x = 255
でも 32 を返すので、やはり「ビットそのもの」を数えていません。
x = 8 だと、29 を返すので、一番右端の 1 が左から何ビット目にあるかを
返しているとしか、私には見えません。
「ビットそのもの」を数えていると考えている、という akiさんの考えは
不自然に思います。


しかし、aki さんのおかげで、とても勉強になりました。
長い英文の翻訳までしていただいて、その熱意にはとても感謝しています。
ありがとうございました。