« 新鯖 | メイン | GeForce6600 »
■printf
投稿者 bois : 2004年10月12日 | [EDIT]
ゆうひさんが悩んでいるようなので・・
コンピュータ上での小数値の扱いは、普通の数値と同じように2進数で扱うわけだから、
10進数で0.5を二進数で0.1
10進数で0.25を二進数で0.01
みたいに考えて、次々に2で割りまくって細かい計算をしていると理解する。
詳しい解説は、IEEE 浮動小数点 などのキーワードでぐぐってください
そうすると、1.15ってのは二進数にとっては無限小数(循環小数)で、具体的には単精度の浮動小数点で「1.149991577748622946875」くらいなので、第1桁で四捨五入してしまうと1.1。
1.25は、二進数にとってきっかり表現できる数値なので、誤差がなく表示される。
そんな感じで、結果が変わって見えてしまうのだと思う。
これを回避するのであれば、自前でなんとかしなければならないので、printfで細工。
awkはよくわからないけれど、Cでやるならこうするかなぁ
float num = 1.15f;
printf("%d.%d", (int)num, (int)(num*10) % 10);
・1個目の%dは、整数部分。intにキャストして少数以下を切り捨て。
・2個目の%dは、小数1桁目。10倍したものをintにキャストして、10で割ったあまり(0〜9にするため)。
awkだとここまで型を意識したコーディングはできないのかな・・
トラックバック
このエントリーのトラックバックURL:
http://www.boiscreative.com/blog/mt-tb.cgi/45
コメント
誤差というより、ただ四捨五入されてるだけっぽいけど…。
{ print int($1 * 10) / 10; }
こんな感じでできるのでは。
投稿者 m-akita : 2004年10月12日 20:40
あ゛、もう一度確認したら四捨五入じゃないっぽい(汗
という訳で上のコメントは、なかった事にしてください
投稿者 m-akita : 2004年10月12日 21:19
実際floatとかdoubleでプログラム組んでても、まさかこんなところに落とし穴があるなんて気づかないんで、いろいろ勉強になりますね。1.15を実は表現できていなかったという事実も、実はこの検証で初めて知りました(*´−`)・・・
投稿者 BOIS : 2004年10月15日 13:32