アカウント名:
パスワード:
十数年仕事で(アマ時代を入れると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;}
えー常識だと思っていたけどな計算機イプシロンとかその辺で出てくる話題だと思た
計算機的な講義(世代により中学なり大学なり新人研修だったりするだろうけど)でイの一番に習いそうだけど。
浮動小数のバックグランドを知らない人間に浮動小数を扱わせてはいけない、の実例。
Z80用の単精度浮動小数点ライブラリを自分で書いてみたクチだから、どれくらい浮動小数点での加減算が信用できない(精度が足りなくなる)か身に染みて分かる。今は浮動小数点形式の構造ばかりか、スタックの構造やらポインタ、果てはデータのメモリ内での記憶方法なんぞを知らなくても良い時代になったと思えばいいのかなあ。
今はNCデータが割と身近にある仕事してるんだけど、それに慣れてると、小数はぜんぶ1000倍して常に整数で持たせたくなる。モノはでかくても4mくらいだし。
なぜ1024倍でないのか?
0.001mm を 1024倍して何が嬉しい?
二進数の整数で扱うなら、1000倍より1024倍の方が計算が簡単なんだけど、知らない?
二進化十進数なら話は別だと思うけど。
いまどきこんなこと言ってる人いるんだなあw $ cat test.cint hoge(int n){ return 1024 * n;}
int piyo(int n){ return 1000 * n;}
$ gcc -O2 -S test.c -o - .text .globl hogehoge: movl %ecx, %eax sall $10,
これて浮動小数点で得られるものを、固定小数点で表したい、ってはなしだよね。なら、
int hoge(double n){ return 1024 * (int)n;} int piyo(double n){ return 1000 * (int)n;}
とかにしないと。
掛け算しようとすると、固定小数点なので、
int hogemul(int n, int m){ return ((long)n * (long)m)/1024;} int piyomul(int n, int m){ return ((long)n * (long)m)/1000;}
> return 1024 * (int)n;ではなくて、
return (int)(1024.0 * n);
ではないの?だとしたら1024でも1000でも計算コストは変わらないよね。
> 掛け算しようとすると、固定小数点なので、> return ((long)n * (long)m)/1024;
これも、掛け算したらもはや単位は長さではなく面積なので、長さ 1unit=1/1,000 mm面積 1unit=1/1,000,000 mm2と仕様書に書いておけばすむ話。
いずれにしても、僅かな計算機リソースの節減より、十進にしたときの見やすさを優先するなあ。私だったら。
1024 * (int)nだろうと、(int)(1024.0 * n)だろうと、1024倍と1000倍でコストは変わらないね。実際、どちらの場合も、コンパイラが吐くニーモニックのステップ数は同じになる。
ただし、掛算とビットシフトが同じコストと考えるならば、だけどね。実際には同じではないので、コンパイラも1024倍の時は、掛算命令でなくビットシフト命令を吐くわけだけど。
そんなことで済むなら、そもそも#3069125 [srad.jp]は何だったのか、って話になっちゃうね。
それにもし、そうしたいのであれば、普通
> コンパイラも1024倍の時は、掛算命令でなくビットシフト命令を吐く
(int)(1024.0 * n)って、ビットシフトで計算するんですか?自分のところのVisualStudioではどちらもfmul命令に変換されたんですが。
> マイクロメートル、学校で習ったよね?
業界によりますが、長さをmmで扱うのが当然のところでは、1000mmを単純に1mと略さないのと同じ程度には、0.001mmを単純に1μmと書かないところがあります。
> そもそも、機械に食わせるデータに、見やすさなんか関係あるの?
思った結果にならなかったときに、生データをその場で当たらなければならないことは往々にしてるんですよ。
(int)(1024.0 * n)って、ビットシフトで計算するんですか?
当然しませんが、そーゆー意味じゃないです。 #3069313 [srad.jp]を受けた発言です。
そーゆー業界に身を置くなら、慣れるのが吉。業界を変えるのは超困難だけど、自分を変えることはできるので。0が二つ三つ程度の話ならなおさら。
でも、「1unit=1/1,000mm」と書くのはokって話なんだよね?キミに文句を言ってもしかたないけど、ミョーな業界ルールだねぇ。
ところで、私は機械可読なデータの話のつもりだったんだけど、設計図とかの話にズレてる気がする。気のせい
この人はどーして恥の上塗りを繰り返すのだろう?
なんでこの匿名の臆病者は、無根拠な一口中傷を繰り返すのだろう。→何度もRyo.Fにコテンパンにノされて悔しいのう悔しいのう、だけど、まともに議論するとまたノされちゃうから(笑)。
ということにしないと精神の安定が保てない人かな? 傍から見て哀れな人だなとしか。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
日々是ハック也 -- あるハードコアバイナリアン
floatで整数を数えあげちゃいけない@C言語 (スコア:1)
十数年仕事で(アマ時代を入れると20年以上)使っていたのに知らなかったので数日はまった。
バグったコードからエラー原因を簡素化したテストコードは以下。
float型(i)とint型(k)で1ずつ加算していって異なったら
標準エラーに出力。
Re: (スコア:0)
えー常識だと思っていたけどな
計算機イプシロンとかその辺で出てくる話題だと思た
Re: (スコア:0)
計算機的な講義(世代により中学なり大学なり新人研修だったりするだろうけど)でイの一番に習いそうだけど。
Re: (スコア:0)
浮動小数のバックグランドを知らない人間に浮動小数を扱わせてはいけない、の実例。
Re: (スコア:2)
Z80用の単精度浮動小数点ライブラリを自分で書いてみたクチだから、どれくらい浮動小数点での加減算が信用できない(精度が足りなくなる)か身に染みて分かる。
今は浮動小数点形式の構造ばかりか、スタックの構造やらポインタ、果てはデータのメモリ内での記憶方法なんぞを知らなくても良い時代になったと思えばいいのかなあ。
Re: (スコア:0)
今はNCデータが割と身近にある仕事してるんだけど、それに慣れてると、小数はぜんぶ1000倍して常に整数で持たせたくなる。モノはでかくても4mくらいだし。
Re: (スコア:1)
なぜ1024倍でないのか?
Re: (スコア:0)
0.001mm を 1024倍して何が嬉しい?
Re: (スコア:1)
二進数の整数で扱うなら、1000倍より1024倍の方が計算が簡単なんだけど、知らない?
二進化十進数なら話は別だと思うけど。
Re: (スコア:0)
二進数の整数で扱うなら、1000倍より1024倍の方が計算が簡単なんだけど、知らない?
いまどきこんなこと言ってる人いるんだなあw
$ cat test.c
int hoge(int n)
{
return 1024 * n;
}
int piyo(int n)
{
return 1000 * n;
}
$ gcc -O2 -S test.c -o -
.text
.globl hoge
hoge:
movl %ecx, %eax
sall $10,
Re: (スコア:1)
これて浮動小数点で得られるものを、固定小数点で表したい、ってはなしだよね。
なら、
とかにしないと。
掛け算しようとすると、固定小数点なので、
Re: (スコア:0)
> return 1024 * (int)n;
ではなくて、
return (int)(1024.0 * n);
ではないの?だとしたら1024でも1000でも計算コストは変わらないよね。
> 掛け算しようとすると、固定小数点なので、
> return ((long)n * (long)m)/1024;
これも、掛け算したらもはや単位は長さではなく面積なので、
長さ 1unit=1/1,000 mm
面積 1unit=1/1,000,000 mm2
と仕様書に書いておけばすむ話。
いずれにしても、僅かな計算機リソースの節減より、
十進にしたときの見やすさを優先するなあ。私だったら。
Re: (スコア:1)
ではないの?だとしたら1024でも1000でも計算コストは変わらないよね。
1024 * (int)nだろうと、(int)(1024.0 * n)だろうと、1024倍と1000倍でコストは変わらないね。
実際、どちらの場合も、コンパイラが吐くニーモニックのステップ数は同じになる。
ただし、掛算とビットシフトが同じコストと考えるならば、だけどね。
実際には同じではないので、コンパイラも1024倍の時は、掛算命令でなくビットシフト命令を吐くわけだけど。
これも、掛け算したらもはや単位は長さではなく面積なので、
長さ 1unit=1/1,000 mm
面積 1unit=1/1,000,000 mm2
と仕様書に書いておけばすむ話。
そんなことで済むなら、そもそも#3069125 [srad.jp]は何だったのか、って話になっちゃうね。
それにもし、そうしたいのであれば、普通
Re: (スコア:0)
> コンパイラも1024倍の時は、掛算命令でなくビットシフト命令を吐く
(int)(1024.0 * n)って、ビットシフトで計算するんですか?自分のところのVisualStudioではどちらもfmul命令に変換されたんですが。
> マイクロメートル、学校で習ったよね?
業界によりますが、長さをmmで扱うのが当然のところでは、1000mmを単純に1mと略さないのと同じ程度には、0.001mmを単純に1μmと書かないところがあります。
> そもそも、機械に食わせるデータに、見やすさなんか関係あるの?
思った結果にならなかったときに、生データをその場で当たらなければならないことは往々にしてるんですよ。
Re: (スコア:1)
(int)(1024.0 * n)って、ビットシフトで計算するんですか?
当然しませんが、そーゆー意味じゃないです。
#3069313 [srad.jp]を受けた発言です。
業界によりますが、長さをmmで扱うのが当然のところでは、1000mmを単純に1mと略さないのと同じ程度には、0.001mmを単純に1μmと書かないところがあります。
そーゆー業界に身を置くなら、慣れるのが吉。
業界を変えるのは超困難だけど、自分を変えることはできるので。
0が二つ三つ程度の話ならなおさら。
でも、「1unit=1/1,000mm」と書くのはokって話なんだよね?
キミに文句を言ってもしかたないけど、ミョーな業界ルールだねぇ。
ところで、私は機械可読なデータの話のつもりだったんだけど、設計図とかの話にズレてる気がする。
気のせい
Re:floatで整数を数えあげちゃいけない@C言語 (スコア:0)
この人はどーして恥の上塗りを繰り返すのだろう?
Re: (スコア:0)
なんでこの匿名の臆病者は、無根拠な一口中傷を繰り返すのだろう。
→何度もRyo.Fにコテンパンにノされて悔しいのう悔しいのう、だけど、まともに議論するとまたノされちゃうから(笑)。
Re: (スコア:0)
なんでこの匿名の臆病者は、無根拠な一口中傷を繰り返すのだろう。
→何度もRyo.Fにコテンパンにノされて悔しいのう悔しいのう、だけど、まともに議論するとまたノされちゃうから(笑)。
ということにしないと精神の安定が保てない人かな? 傍から見て哀れな人だなとしか。