
WinXP,SDKです。
小数点以下第2位までに切り上げをしようと思ったのですが、
以下のような式の場合に0.55が0.56と求められてしまいます。
double num = 0.55;
num = num * 100; <- この時点で55.0
double tmp = ceil(num); <- この時点で56.0 ※
num = tmp / 100; <- この時点で0.56
※の所でなぜ55.0と戻ってこないのでしょうか。
これはなぜか0.55の時だけ現象が出てしまいます。
ほかの数値の場合はほぼ上手く行きます。(ダメな数値は見つけられていません)
上の式をたとえば
num = 55.0;
double tmp = ceil(num);
とした場合、正しく55.0と求められます。
おそらく100をかけているところで何らかの問題が出ていると思うのですが…
100をintやdouble型にしてみても結果は同じでした。
どのように計算すれば上手くいくのでしょうか。
アドバイスをお願い致します。
No.6ベストアンサー
- 回答日時:
2進の小数点以下は近似値でしかないのです。
2の-1乗は0.5、-2乗は0.25・・・
なので0.55をセットした段階で近似値に置き換わっていると思われます。
ただ、デバッグなのど表示では暗黙の丸目が行われていて0.55と表示されているだけでしょう
有効桁で一度丸めを行い切り上げを行うしかないのかも。
私の場合は文字列に変換してから行いましたけど
アドバイスありがとうございます。
はい、デバッグでは小数点以下第14位までしか表示されておらずに、
そこまではすべてゼロだった為になかなか気づきませんでした。
実際は"55.00000000000000700000"と、15位に"7"が入っていました。
今回丸めを行おうと思います。
でも、文字列でやったほうが正しく出来るケースも昔体験したような気がするのですが…
迷っています。
ありがとうございました。
No.5
- 回答日時:
0.55自体が2進表現にした場合に厳密な0.55にならないに起きる現象でしょう
double num = 0.55;
ddum *= 100.0;
double t1 = floor( num );
double t2 = num - t1;
if ( t2 == 0 ) {
printf( "num == 55\t" );
} else {
printf( "num != 55\t" );
}
printf( "%lf", t2 );
printf( "%.20lf", 0.55 );
num = 55.0;
double tmp = ceil(num);
で tmpが55になるのは 55を浮動小数点であらわしても55のまま誤差が無いためです
分かりやすいアドバイスありがとうございます。
何だか基本的な事を分かっていなかったように思います。
55.0を直接入れた時は大丈夫というのもやっと理解出来ました。
こうなるのは当然とやっと分かったので、
処置を考える事が出来そうです。
ありがとうございました。
No.4
- 回答日時:
浮動小数点数で0.55は循環小数になってしまうので、正確に計算することはできません。
多分他にもだめな値はあると思います。
こういった場合には、最初からすべての値を100倍して計算し、最終的な表示の際に100分の1に戻す方法がよく使われます。
アドバイスありがとうございます。
循環小数…このような結果になるのは当たり前なのですね。
分かっているようで分かっていなかったように思います。
0.55*100だけが特殊な訳ではないのですね。
プログラムとしては、小数点以下の有効桁数は6桁で、
0.55*100の小数点以下で0以外のものが発生するのが
15桁目くらいなので、その間くらいで切り捨てをしてから
処理しようかと思います。
ありがとうございました。
No.2
- 回答日時:
やりたいのは切り上げですね
間違えました
見て頂いてありがとうございました。
切り上げとか数値の問題ではないのかもしれません…
あれから色々と調べていて、
普通に
double tmp = 0.55 * 100;
などとしたものを%.20fで表示してみると、
小数点以下第15位くらいに値が入っています。
きっとこれのせいでceilが一つ上に切り上げしてくるんですね。
これは誤差と考えて、
計算式を一度100億倍位にして、切り捨て(floor)してから
ceilにかけたりしてみようかと思います。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
今、見られている記事はコレ!
-
隣の枝がはみ出してきたら切ってもいい?最もやってはいけないことは?
「隣の木が越境してきて困るが、勝手に切ってはいけないと聞くし…」そう思っている方も多いだろう。実は、2023年4月1日に民法が改正され、この「越境枝」のルールが大きく変わった。 教えて!gooでも「境界から出て...
-
弁護士が解説!あなたの声を行政に届ける「パブリックコメント」制度のすべて
社会に対する意見や不満、疑問。それを発信する場所は、SNSやブログ、そしてニュースサイトのコメント欄など多岐にわたる。教えて!gooでも「ヤフコメ民について」というタイトルのトピックがあり、この投稿の通り、...
-
弁護士が語る「合法と違法を分けるオンラインカジノのシンプルな線引き」
「お金を賭けたら違法です」ーーこう答えたのは富士見坂法律事務所の井上義之弁護士。オンラインカジノが違法となるかどうかの基準は、このように非常にシンプルである。しかし2025年にはいって、違法賭博事件が相次...
-
釣りと密漁の違いは?知らなかったでは済まされない?事前にできることは?
知らなかったでは済まされないのが法律の世界であるが、全てを知ってから何かをするには少々手間がかかるし、最悪始めることすらできずに終わってしまうこともあり得る。教えてgooでも「釣りと密漁の境目はどこです...
-
カスハラとクレームの違いは?カスハラの法的責任は?企業がとるべき対応は?
東京都が、客からの迷惑行為などを称した「カスタマーハラスメント」、いわゆる「カスハラ」の防止を目的とした条例を、全国で初めて成立させた。条例に罰則はなく、2025年4月1日から施行される。 この動きは自治体...
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
プログラミングです 7行目の何...
-
プログラミングについての質問...
-
点線以下のプログラムです。①、...
-
(C言語)ニュートン法のプログ...
-
C言語初心者 構造体 課題について
-
浮動小数点の定数
-
C 開放してるのにエラー(doubl...
-
「割り算」 と 「分数の掛け算」
-
C言語の型による処理速度の違い
-
実数型の変数に値を入力した計...
-
C言語で表記についの質問です
-
DWORDの警告
-
至急です! マクロ定義で #defi...
-
2分法で方程式の複数の解を自...
-
Aの値からBの値を除するとは??
-
「Aに対するBの割合」と「Aに対...
-
信頼区間の1.96や1.65ってどこ...
-
プログラミング python
-
EXCEL AVEREGE関数について
-
C言語の問題です。 標準入力 (...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラムでの数字につく”f”の...
-
C 開放してるのにエラー(doubl...
-
至急です! マクロ定義で #defi...
-
C言語を実行すると-infが出てき...
-
C言語の型による処理速度の違い
-
c言語で、繰り返し文の中で、0....
-
C言語 関数プロトタイプ宣言の...
-
doubleの変数にintとintの割り...
-
float型とdouble型の変数の違い...
-
-1.#IND00と出てしまうのですが...
-
c言語のプログラミングについて...
-
C言語で台形公式を使った二重積...
-
C言語でdouble型の小数点の引き...
-
C言語のプログラムで#include<m...
-
2次方程式の解を求めるプログ...
-
C言語の複素数についてです。
-
doubleは常に%lfとするべきなのか
-
関数におけるif文とreturn文に...
-
difftime()について
-
int とdoubleの比較
おすすめ情報