No.7ベストアンサー
- 回答日時:
普通は、四捨五入に類することをやります。
a = d * 20.0 + 0.05;
(この 0.05 を必要な精度の桁数で決定する。この場合だと、小数点第2位で四捨五入)
あと、気になるところが。
> a = d * 20.0;
> これだと、コンパイルエラーです。
これは、C言語の正しい書き方です。
これでコンパイルエラーになるコンパイラは、今は存在しないと思いますが。
また、
> a = (int)(d * 20.0);
> だと、intがそれぞれにかかって、
> 結局 0 * 20 と同じ事で。
> =0
これも、int がそれぞにかかるのではなくて、
d * 20.0 の計算結果が、誤差の関係で、1.0 にならなかったから、切り捨てられて 0 になっているだけです。
一般に、double を int に代入するのに、キャストは不要です。
ですから、
a = d * 20.0 + 0.05;
という式も、右辺の式を double で計算した後、暗黙のキャストで int 型の a に普通に代入されます。
この回答への補足
ありがとうございます。
四捨五入方法、使ってみます。
C#でデバッグしてみましたが、
a = d * 20.0;は、
「型'double'を'int'に暗黙的に変換できません。明示的な変換が存在します。(castが不足していないかどうかを確認してください)」
といって警告ではなくエラーになりました。
>これも、int がそれぞにかかるのではなくて、
d * 20.0 の計算結果が、誤差の関係で、1.0 にならなかったから、切り捨てられて 0 になっているだけです。
たしかにそうなりました。
No.8
- 回答日時:
がると申します。
小数点以下、を使うことを避けられてみては如何でしょうか?
素直に「整数のみ」で扱えるようにして、必要に応じて「表示だけ切り替える」のが、一番確実です。
浮動小数点というものは「誤差があって当たり前」のものですから。
小細工で「今回の結果を無理矢理1にすること」は可能でしょうけれども、同じ小細工を別の計算式でやると、大抵「やっぱり思ったとおりにいかない」とか言う話になり、わやくちゃになっちゃうモノなので。
No.6
- 回答日時:
★スピードが要求されるのならばすべて int 型の整数で計算します。
・float、double 型よりも整数型の方が高速です。
よって、100 倍した数値を int 型で表して計算すればよい。
つまり:
int a;
int d;
d = 115 - 110; ←100倍した値で計算。
a = (d * 20);
a ←100. になるが利用するときは 100 で割る。このときに float、double 型で計算する。
↓
printf( "%lf\n", ((double)a / 100) ); ←ここで double 型にキャストして 100 で割る。
その他:
・浮動小数点は小数部を 2 進数で表すため数学的にきっちりした結果にはなりません。
1/2、1/4、1/8、1/16、1/32…という数の合計が正確に表せる数です。
つまり、
0.03125
0.06250
0.09375
0.12500
0.15625
0.18750
0.21875
0.25000
:
という数値だけが誤差がなく数を表せるのです。
・スピードが要求されるような場面では、出来るかぎり int 型の整数値を利用して下さい。
小数として参照する直前で 100 で割るようにすればよい。または 1000 倍、10000倍にして
計算して参照する直前で 1000、10000 で割ればよい。精度も良くなりますし、高速です。
・以上。参考に!
No.5
- 回答日時:
doubleからintに変換するときにマクロを使うとか。
#defineONROUND(a)(int)(((a)<0.0)?((a)-0.5):((a)+0.5))
な~んてね・・・
a = ONROUND(d * 20.0);
でどうでしょ?
No.4
- 回答日時:
double は、浮動小数点型ですので、仕様上そうなります。
a を 1 として取り出したいのであれば、一旦、d*20 を
有効数字 小数点以下2桁の文字列にして、それを int で
読み込むのは、どうでしょうか。
int a;
double b,d;
char bb[20];
d = 1.15 - 1.1;
b = d*20.0;
sprintf(bb,"%.2lf",b);
sscanf(bb,"%d",&a);
この回答への補足
なるほど~。使えますね。
ですが、制御機器のため、スピードが要求されるので、
惜しくも、sprintfやsscanfが使えないのです。
No.3
- 回答日時:
一介のデザイナーでプログラマではないので自信はありませんが・・・。
「プログラミング言語C」で2番目に登場する華氏の温度から摂氏の温度を求めるプログラム。
celsius = 5 * (fahr - 32) / 9;
celsius = (fahr - 32) * 5 / 9;
確か、下ではなく上の書き方をしていましたよね。
(下の書き方は)
「5 と 9 は整数だから、 5/9 は切り捨てられてゼロとなり、もちろんすべての摂氏温度がゼロになってしまう。」
(「プログラミング言語C」13頁)
この例に倣うならば・・・
Private Sub Command1_Click()
Dim a As Integer
Dim d As Double
d = (115 - 110) / 100
a = Int(d * 20)
MsgBox a
End Sub
VB6.0 でも C でも通貨型を使わなければ同じことなのでVB6.0でテストしてみました。
なお、プロのプログラマの方の回答もお待ち下さい。
この回答への補足
これも使えますね。でも、こういう式を使った部分が、大量にありまして、ちょっと手作業が厳しい状態です。
少なければ私もこれでやろうかなと思ってました。
No.2
- 回答日時:
たいていの処理系で double の値は「2進数に基づく浮動小数」で表現されるので, 2^-n という形でないと正確に表すことができません. そのようなものを有限のビット数で表現しなければならないので, 切り捨てられたり切り上げられたりします. これは double など浮動小数を使うときには常についてまわる問題なので, プログラムを書くときにきちんと注意する必要があります.
で, 対策ですが....
・そもそも double なんて使わない: 可能であればこれが最も簡単
・DBL_EPSILON を考慮してプログラムを書く: 面倒
・うまくいく関数たちを使う: 存在するかどうかは知りません
・C を使わない: C# なら OK だったと思う
かなぁ? この辺を処理する設定は, 普通はないと思います.
この回答への補足
いちお、doubleをやめて、floatにしたら、うまくいきました。
0.04999のいい具合のとこで四捨五入されたからだとおもいます。
Cでも、C#でも、Excelでも、やはり0.0499・・・82になりました。
日立のコンパイラのマニュアル見たら、小数点を切り捨てるか四捨五入かというのと、有効数字の桁数を設定するなんて書いてあったのですが、設定場所が見当たらず、日立に問い合わせ中です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・「みんな教えて! 選手権!!」開催のお知らせ
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~1/20】 追い込まれた犯人が咄嗟に言った一言とは?
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・【選手権お題その3】この画像で一言【大喜利】
- ・【お題】逆襲の桃太郎
- ・自分独自の健康法はある?
- ・最強の防寒、あったか術を教えてください!
- ・【大喜利】【投稿~1/9】 忍者がやってるYouTubeが炎上してしまった理由
- ・歳とったな〜〜と思ったことは?
- ・ちょっと先の未来クイズ第6問
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・【選手権お題その2】この漫画の2コマ目を考えてください
- ・【選手権お題その1】これってもしかして自分だけかもしれないな…と思うあるあるを教えてください
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C 開放してるのにエラー(doubl...
-
C言語初心者 構造体 課題について
-
プログラムでの数字につく”f”の...
-
プログラミングでのテイラー展開
-
doubleの変数にintとintの割り...
-
微分方程式(ルンゲ=クッタ)...
-
float型とdouble型の変数の違い...
-
2自由度減衰振動のルンゲクッタ法
-
ラグランジュの補間法のCプログ...
-
C言語 関数プロトタイプ宣言の...
-
C言語の複素数についてです。
-
3次方程式の求解プログラム(...
-
(C言語)ニュートン法のプログ...
-
C言語を実行すると-infが出てき...
-
c言語で、繰り返し文の中で、0....
-
0から1までの乱数(実数値)を発...
-
long double型の戻り値を持つ関...
-
VisualC++2005にてerror C2664...
-
C言語で-23乗を取り扱うには
-
関数におけるif文とreturn文に...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラムでの数字につく”f”の...
-
C言語を実行すると-infが出てき...
-
c言語で、繰り返し文の中で、0....
-
C 開放してるのにエラー(doubl...
-
doubleの変数にintとintの割り...
-
float型とdouble型の変数の違い...
-
至急です! マクロ定義で #defi...
-
C言語の型による処理速度の違い
-
C言語 関数プロトタイプ宣言の...
-
c言語のコンパイルエラー canno...
-
C++で外積
-
int とdoubleの比較
-
(C,C++言語)関数の引数は自動キ...
-
関数におけるif文とreturn文に...
-
Cで3乗根を求める方法
-
C言語で-23乗を取り扱うには
-
C言語初心者 構造体 課題について
-
数値を指数部と仮数部に分離したい
-
相互相関関数
-
2次方程式の解を求めるプログ...
おすすめ情報