アカウント名:
パスワード:
十数年仕事で(アマ時代を入れると20年以上)使っていたのに知らなかったので数日はまった。
バグったコードからエラー原因を簡素化したテストコードは以下。float型(i)とint型(k)で1ずつ加算していって異なったら標準エラーに出力。
#include <stdio.h>int main(){ float i; int k; i=0; for(k=0;k<=16777217;k++){ if(k != (int)i) fprintf(stderr,"%i %i\n",k,(int)i); i += 1; } return 0;}
floatと整数と言えば。
int*をfloat*にキャストして、それをデリファレンスすること(intをfloatとしてアクセスすること)は未定義である。
を見て、もすぬごい衝撃がががが。
Fast inverse square root [wikipedia.org]とか、Cで書きたくなくなる。
共用体の存在を、こってり忘れていた。
逆に定義されていたら困りそう。intのビット数なんて定義されていないわけだし。
>int*をfloat*にキャストして、それをデリファレンス
そりゃ、任意のびっちパターンが許されるintと浮動小数点形式が定まってるfloatをビットレベルで混ぜたら危険にもほどがあるでしょうに・・・。素直に*つけてからキャストしてくださいな。
そのページにも書いてあるけど、それは(エンディアン、メモリ保護機構などにも依存するが)「IEEE 754-1985 32-bit floating point」であることに依存したアルゴリズム。言い換えるとそのアルゴリズムが使用可能になる前提として、C自体では未定義だった動作が目的の処理系でいい具合に定義済みの場合に使えるアルゴリズム。
浮動小数点数として無効なビットパターンとかもあるから未定義になるのはしゃあない。そもそも浮動小数点数の表現だってIEEE 754のbinary32等であるとは規定されてない。…というか、某ポケコンのCのfloatはBCD系の実装だったりする。あれは結構衝撃だった…
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
物事のやり方は一つではない -- Perlな人
floatで整数を数えあげちゃいけない@C言語 (スコア:1)
十数年仕事で(アマ時代を入れると20年以上)使っていたのに知らなかったので数日はまった。
バグったコードからエラー原因を簡素化したテストコードは以下。
float型(i)とint型(k)で1ずつ加算していって異なったら
標準エラーに出力。
Re:floatで整数を数えあげちゃいけない@C言語 (スコア:2)
floatと整数と言えば。
を見て、もすぬごい衝撃がががが。
Fast inverse square root [wikipedia.org]とか、Cで書きたくなくなる。
Re:floatで整数を数えあげちゃいけない@C言語 (スコア:2)
共用体の存在を、こってり忘れていた。
Re: (スコア:0)
逆に定義されていたら困りそう。intのビット数なんて定義されていないわけだし。
Re: (スコア:0)
>int*をfloat*にキャストして、それをデリファレンス
そりゃ、任意のびっちパターンが許されるintと浮動小数点形式が定まってるfloatをビットレベルで混ぜたら危険にもほどがあるでしょうに・・・。素直に*つけてからキャストしてくださいな。
Re: (スコア:0)
そのページにも書いてあるけど、それは(エンディアン、メモリ保護機構などにも依存するが)「IEEE 754-1985 32-bit floating point」であることに依存したアルゴリズム。
言い換えるとそのアルゴリズムが使用可能になる前提として、C自体では未定義だった動作が目的の処理系でいい具合に定義済みの場合に使えるアルゴリズム。
浮動小数点数として無効なビットパターンとかもあるから未定義になるのはしゃあない。
そもそも浮動小数点数の表現だってIEEE 754のbinary32等であるとは規定されてない。
…というか、某ポケコンのCのfloatはBCD系の実装だったりする。あれは結構衝撃だった…