掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.27856

型変換 (No.27822の続きです)
投稿者---h3X(2006/08/04 21:01:08)


スレッドが長くなったため,新にスレッドを作らせて頂きます.

皆様のおかげで,型変換に関してほぼ理解できるようになりました.
しかし,完全に自分が理解できるためにも,考え方がまだあいまいな点を質問させて頂きます.


[[ 1 ]]

「汎整数拡張」に関してですが,No.27851にて,たかぎさんがおしゃられている,

> 念のため指摘しておくと、ここでいう「表現できなければ」というのは、例えばshortもintも16ビットの場合、
> unsigned shortの表現範囲はintではカバーできないのでunsigned intになるということです。
> 決して実際の値が表現できるかどうかではありません。

という内容に関してですが,「決して実際の値が表現できるかどうかではありません。」という言葉が
どういう意味なのか分らないので,もう少し詳しくご説明頂けないでしょうか.

[[ 2 ]]

char型の0x80という値が,int型に「汎整数拡張」すると(int型のサイズが4byteの環境の場合),0xffffff80となる.
これで間違ってないでしょうか?

[[ 3 ]]

「算術型変換」は「==」,「!=」においても起こる.
これで間違ってないでしょうか?

[[ 4 ]]

「算術型変換」においてシフト演算は,「例外的」に通常の算術型変換が行われないとのことですが,
他にも「算術型変換」において例外が起こる場合はあるのでしょうか?


質問内容にこれまでのやり取りと重複する内容があるかもしれませんが,
確かめの意味も含めてもう一度質問させて頂きます.
以上4つの質問について,ご教授よろしくお願い致します.


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:型変換 (No.27822の続きです) 27858 たかぎ 2006/08/04 21:56:34


No.27858

Re:型変換 (No.27822の続きです)
投稿者---たかぎ(2006/08/04 21:56:34)
http://takagi.in/


>> 念のため指摘しておくと、ここでいう「表現できなければ」というのは、例えばshortもintも16ビットの場合、
>> unsigned shortの表現範囲はintではカバーできないのでunsigned intになるということです。
>> 決して実際の値が表現できるかどうかではありません。
>
>という内容に関してですが,「決して実際の値が表現できるかどうかではありません。」という言葉が
>どういう意味なのか分らないので,もう少し詳しくご説明頂けないでしょうか.

例えば、shortもintも16ビットの環境で、

unsigned short x = 1;

とした場合、x の値は 1 でありintで表現できる範囲ですが、汎整数拡張の結果はunsigned intになるということです。

>char型の0x80という値が,int型に「汎整数拡張」すると(int型のサイズが4byteの環境の場合),0xffffff80となる.
>これで間違ってないでしょうか?

char型の0x80が汎整数拡張で0xffffff80になるためには、もっといろいろな条件が必要です。その条件とは、

1. char型が8ビットであること
2. int型が32ビットであること
3. char型が符号付きであること
4. 整数の負の値の内部表現が、1または2の補数であること
5. char型における0x80がトラップ表現ではないこと

です。

>「算術型変換」は「==」,「!=」においても起こる.
>これで間違ってないでしょうか?

正確には「通常の算術型変換(usual arithmetic conversions)」です。

>「算術型変換」においてシフト演算は,「例外的」に通常の算術型変換が行われないとのことですが,
>他にも「算術型変換」において例外が起こる場合はあるのでしょうか?

通常の算術型変換は二項演算子のオペランドに対して行われますが、中にはそうならないものがあります。
シフト演算子のほかには、(複合)代入演算子や配列の添え字演算子、論理演算子、コンマ演算子がそうです。



この投稿にコメントする

削除パスワード

No.27859

Re:型変換 (No.27822の続きです)
投稿者---たかぎ(2006/08/04 22:03:37)
http://takagi.in/


>char型の0x80が汎整数拡張で0xffffff80になるためには、もっといろいろな条件が必要です。その条件とは、
>
>1. char型が8ビットであること
>2. int型が32ビットであること
>3. char型が符号付きであること
>4. 整数の負の値の内部表現が、1または2の補数であること
>5. char型における0x80がトラップ表現ではないこと
>
>です。

まだありました。
その型で表現できない値を符号付き整数型に変換する場合(今回のように0x80をchar型に変換するなど)には、処理系定義の値になるか、処理系定義のシグナルが生成されるので、「処理系定義の値」というのが、0x80がそのままcharのビット表現になる必要がありますね。



この投稿にコメントする

削除パスワード

No.27860

Re:型変換 (No.27822の続きです)
投稿者---h3X(2006/08/04 22:40:42)


[[ 1 ]] [[ 3 ]]は解決しました.

[[ 2 ]] ですが,

>char型の0x80が汎整数拡張で0xffffff80になるためには、もっといろいろな条件が必要です。その条件とは、
>
>3. char型が符号付きであること
>4. 整数の負の値の内部表現が、1または2の補数であること
>5. char型における0x80がトラップ表現ではないこと

・ 3の条件はなぜ必要なのですか?
・ 1の補数,2の補数については知っていますが,4の条件はなぜ必要なのですか?
・ 5の条件中に出てくる「トラップ表現」というのは初耳なので,ネットで調べてみたのですが,分らなかったので教えて頂けると助かります.
またこの5の条件はなぜ必要なのですか?


[[ 4 ]] ですが,
>シフト演算子のほかには、(複合)代入演算子や配列の添え字演算子、論理演算子、コンマ演算子がそうです。

複合代入演算や,配列の添字演算子の場合は「汎整数拡張」は行なわれるが,通常の算術型変換は行なわれないということでしょうか?
シフト演算の時のように例外的な算術型変換が行なわれるのでしたら,その内容をご教授して頂ければ助かります.

今日は1日中,私の質問にお付き合い頂き,心から感謝しております.

上記の点について,よろしくお願い致します.


この投稿にコメントする

削除パスワード

No.27861

Re:型変換 (No.27822の続きです)
投稿者---たかぎ(2006/08/04 23:20:36)
http://takagi.in/


>>3. char型が符号付きであること
>>4. 整数の負の値の内部表現が、1または2の補数であること
>>5. char型における0x80がトラップ表現ではないこと
>
>・ 3の条件はなぜ必要なのですか?

char型が符号付きか符号無しかは処理系定義だからです。
char型が符号無しであれば、汎整数拡張しても(符号拡張されないので)0x80のままです。

>・ 1の補数,2の補数については知っていますが,4の条件はなぜ必要なのですか?

整数の内部表現には、符号および絶対値という形式を取ることも許されるからです。

>・ 5の条件中に出てくる「トラップ表現」というのは初耳なので,ネットで調べてみたのですが,分らなかったので教えて頂けると助かります.
>またこの5の条件はなぜ必要なのですか?

負の値の内部表現が2の補数の場合、または符号および絶対値の場合には、最上位ビットが1で他のビットが0となるビット表現を、処理系は「トラップ表現」とみなすことができます。
「トラップ表現」は早い話が「値ではない表現」のことで、浮動小数点数の非数と少し似ています。

>複合代入演算や,配列の添字演算子の場合は「汎整数拡張」は行なわれるが,通常の算術型変換は行なわれないということでしょうか?
>シフト演算の時のように例外的な算術型変換が行なわれるのでしたら,その内容をご教授して頂ければ助かります.

代入演算子ですが、

unsigned char a;
a = -1L;

といったコードがあった場合、通常の算術型変換を両オペランドに行うのであれば、a をlong型に変換して、そこに -1L を格納することになるのでしょうが、左辺値にそんなことをすると意味不明になってしまいます。

複合代入演算子はちょっと微妙ですが、E1 op= E2 は E1 = E1 op (E2) になるので、E1 op (E2) の段階では通常の算術型変換が行われるものもあるわけです。これは言い方の問題だけかもしれませんね。

配列の添え字演算子は、一方のオペランドはポインタなので、通常の算術型変換を行うことはできません。

論理演算子は、各オペランドは 0 と比較した結果になるので、やはり通常の算術型変換は行われません。

コンマ演算子は、左辺の結果は捨てられるので、通常の算術型変換は行われません。



この投稿にコメントする

削除パスワード

No.27862

Re:解決致しました
投稿者---h3X(2006/08/04 23:36:47)


皆様のご教授のおかげで,大変勉強になりました.

特に,たかぎさん,rubyさんに到りましては,何度も私の質問に丁寧にご回答
頂き本当にありがとうございました.


この投稿にコメントする

削除パスワード

No.27869

トラップ表現 <was: Re:型変換 (No.27822の続きです)>
投稿者---RiSK(2006/08/05 08:10:26)


トラップ表現について補足。
# 本題からは外れます。

>負の値の内部表現が2の補数の場合、または符号および絶対値の場合には、
>最上位ビットが1で他のビットが0となるビット表現を、処理系は「トラップ表現」とみなすことができます。

負の値の内部表現が1の補数の場合で,
全ビットが立っている場合もトラップ表現になることがあります。

ちなみに -0 をトラップ表現にするか 0 にするかは未規定。

int が 32bit で 1 の補数表現の場合に
0xFFFFFFFF が処理系により勝手に 0x00000000 にされたり,
int が 32bit で 符号及び絶対値表現の場合に
0x80000000 が処理系により勝手に 0x00000000 にされたりするかもしれないって事。

まぁ,滅多なことでは -0 は作り出せないのだけどね。


この投稿にコメントする

削除パスワード

No.27871

Re:トラップ表現 <was: Re:型変換 (No.27822の続きです)>
投稿者---たかぎ(2006/08/05 08:43:27)
http://takagi.in/


>ちなみに -0 をトラップ表現にするか 0 にするかは未規定。

正確にいうと、通常の値になるかトラップ表現になるかは処理系定義です。そして、(符号および絶対、または1の補数において)通常の値の場合は負の0(-0)になります。
そして、処理系が負の0をサポートする場合、-0を生成したり-0を格納する操作を行った際に、-0になるか0になるかが未規定(不定)になります。

トラップ表現を読み取ったり、生成したりすると、文字型でない整数型では動作が未定義になるのですが、今回は文字型(char型)の話をしているので、結局どんな値になるのか規格を見てもよくわかりませんでした。



この投稿にコメントする

削除パスワード

No.27872

Re:トラップ表現 <was: Re:型変換 (No.27822の続きです)>
投稿者---RiSK(2006/08/05 08:54:35)


>正確にいうと、

補足に感謝します。


実は

>-0

って書いたり,

>まぁ,滅多なことでは -0 は作り出せないのだけどね。

って書いたのは,

>通常の値になるかトラップ表現になるかは処理系定義
>処理系が負の0をサポートする場合

を理解していたからです。
曖昧な書き方でしたね。すみません。


>トラップ表現を読み取ったり、生成したりすると、文字型でない整数型では動作が未定義になるのですが、今回は文字型(char型)の話をしているので、結局どんな値になるのか規格を見てもよくわかりませんでした。

うーむ。おもしろそうだけど別スレにした方が良さそうな話題ですね。
# しかも,今日はもう時間をとれないや。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧