
現在、VB6.0を使用しており、小数点の扱いに困っています。
Sub Keisan()
Dim A As String
Dim B As String
Dim C As String
A = 1.29033
B = 1.91458
C = CStr(A + CDec((B - A) / 6) * 3)
MsgBox C
End Sub
上記のプログラムを実行すると、
「1.602455000000001」と表示されますが、
電卓を用いて計算すると、
「1.602454998・・・」となり、微妙に誤差が出てしまいます。
小数点を整数にして計算→元の桁数に戻す、という
処理を行うと、誤差なく求めることが出来ましたが、
「もっとスマートなコードにして」と言われてしまいまして
どうしたものかと思っております。
この誤差を解決する方法は無いでしょうか?
No.3ベストアンサー
- 回答日時:
この問題は、パソコンと電卓との計算の誤差だと考えられます。
1.602455000000001と1.602454998 はとちらも結論から言うと正しいのだが。
問題は、(B-A)/6 が割りきれないところから出ていると思われます。
0.104041666666・・・・=(B-A)/6
電卓は、1演算の都度、小数点指定桁数で切り捨てて計算するみたいです。
これは、電卓の液晶画面が指定桁数しか表示出来ないところから来ている
と思われます。
今回の問題は、電卓に合わすとの事なので、合わす為には、演算が入る
度に、電卓と同じ桁数で切捨てればOKとの事になります。
ご質問のプログラムもそこを考慮して、CDec((B - A) / 6) とわざとCDec関数を
間に入れていますが、結局小数点9桁で切り捨てられていないので、切捨てられて
いない分だけ計算結果が大きくなります。
下記のプログラムが比較的簡単かなと思います。これでも完璧かどうか
わかりませんが、乗算・除算の計算の度に下のfint関数を呼び出す事です。
ここで注意するのは、fint関数の2番目の引き数です。この引数は、電卓の液晶画面の
表示桁数です。下のサンプルは、表示桁数10桁(小数点も含む)にしています。
Sub Sub Keisan()
Dim A As Double
Dim B As Double
Dim C As String
A = 1.29033
B = 1.91458
C = A + fint((B - A) / 6, 10) * 3
MsgBox C
End Sub
Function fint(cd as double, ck as integer) As Double
cm = Format(cd, "#.000000000000000000")
fint = Left$(cm, ck)
End Function
尚、演算の内容によっては、上のプログラムでもごくまれに電卓と誤差が
出る可能性があります。確立的にはどれだけかは分かりませんが0.01%
位の確立で誤差が発生するかもしれません。(推測です)。
100%絶対に合わすのであれば、ご指摘の通り、整数にて処理を
するのが確実です。ただ、プログラムが複雑になる分バグも出やすく、
簡潔でそこそこ精度があるのであれば、上のプログラムで充分だと
思います。
ありがとうございます!!!
教えて頂いた方法で上手くいきました!!!
電卓の表示桁数で抜き取ればよかったんですね。
言われてみると納得です。
プログラムのこういう瞬間「は」すごく楽しいと思いますw
しかし、小数点の演算箇所は相当数あるんですよね・・・
あれ全部修正してテストするのかと思うと怖くなってきましたw
No.4
- 回答日時:
まず、A, B, CがStringの定義なのがアレですね…
誤差を気にするのなら浮動小数点もダメです。
全てVariantで定義して、
A = CDec(1.29033)
とかにしましょう。
あと、計算の中間結果((B-A)/6 とか)も浮動小数点に勝手に変換されると
まずいので、
C = A + (B - A) / CDec(6) * CDec(3)
とかにしたほうがいいかも。
(検証はしてません、あしからず)
回答ありがとうございます。
計算結果は、
A + (B - A) / CDec(6) * CDec(3) = 1.602455
でした(この値でも正しいと思うんですけどねw)。
ちなみにString型で定義してある理由ですが、、、、、不明ですw
No.2
- 回答日時:
この演算結果は1.602455が正解なのでは?
CDec((B - A) / 6) * 3 は CDec((B-A)/2) とほぼ等価考えます
0.62425 / 2 = 0.312125
これに 1.29033 を加算するのですから 1.602455 となると思います
CDec((B - A) / 6) * 3部分に関して 有効桁数以下でRound関数で丸めてしまうといった手法も考えられます
C = CStr( A + Round( CDec( ( B - A )/ 6 ) * 3, 8 ) )
といった具合です
回答が遅くなり申しわけありません。
実は「3」はまた別の式を使って求めているので、正確には、
C = CStr(A + CDec((B - A) / 6) * (3))となります。
質問が正確でなくて本当にすいません。
なので、計算の順序を変えるというのは難しいかなと思っています。
回答頂きました式を実行すると、
CStr( A + Round( CDec( ( B - A )/ 6 ) * 3, 8 ) ) = 1.602455
となりました。
正確な式と、桁数を増やしてみましたが、
CStr(A + Round(CDec((B - A) / 6), 12) * (3)) = 1.602455000001
となり、まだ誤差が出てしまいました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 【前回の続き続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/24 20:49
- Visual Basic(VBA) 【ご教示ください】VBAの記述方法がわかりません。 2 2022/08/12 21:28
- Visual Basic(VBA) VBAが止まります。 3 2022/08/31 14:09
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- Visual Basic(VBA) VBAでoutlook365が起動しません。 4 2022/08/25 13:31
- Visual Basic(VBA) 【前回の続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/16 16:44
- Visual Basic(VBA) エクセルのマクロについて教えてください。 2 2023/07/15 15:48
- Visual Basic(VBA) 別シートから年齢別の件数をカウントしたいの続き 5 2023/01/24 00:16
- Visual Basic(VBA) ExcelVBAに関する質問 3 2023/02/17 10:47
- Visual Basic(VBA) VBA★PDFをPDFアプリで印刷しようと思っていますが上手くゆきません 1 2022/06/06 22:04
このQ&Aを見た人はこんなQ&Aも見ています
-
VB6.0-整数と余りを求める
Visual Basic(VBA)
-
VBの「As String * 128」とは?
Visual Basic(VBA)
-
VB6 配列を初期化したい
Visual Basic(VBA)
-
-
4
VB6.0 プロジェクトオープン時のエラーについて
Visual Basic(VBA)
-
5
テキストボックスの入力制限
Visual Basic(VBA)
-
6
VB6で、Form1をコピーする方法を教えて下さい。
Visual Basic(VBA)
-
7
文字列の後ろから必要分だけ削除したい。
Visual Basic(VBA)
-
8
vb6で異なるのプロジェクト間で、値を渡したい
Visual Basic(VBA)
-
9
VB初心者。小数点以下の表示でつまづいています(涙
Visual Basic(VBA)
-
10
VB6のプロジェクトロードエラーについて
Visual Basic(VBA)
-
11
visual basic初心者です。 visual studioで電卓を作成しています。 実行時にテ
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ExcelでPC(パソコン)によって...
-
演算について
-
配列の要素数について
-
オーディオデータの22050hzから...
-
ExcelのINT関数の計算結果がお...
-
2進数の0.2?
-
加算と減算で乗算と除算を表現...
-
除算を使わずに10で割りたい。
-
C言語でセルオートマトンを作成...
-
VBAでの割り算の余りの求め方
-
色の判定
-
C言語プログラミングにて、arct...
-
O(n log n)について2
-
C++の打切り誤差についてお聞き...
-
VS2010でのint float数値について
-
計算機における誤差
-
EXCELの関数"STDEV(標準偏差)"...
-
8進数と16進数表現について
-
2038年問題 日付算出
-
時刻の比較
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ExcelでPC(パソコン)によって...
-
O(n log n)について2
-
有効数字について 以前質問をし...
-
c languageで 簡単な質問があ...
-
ExcelのINT関数の計算結果がお...
-
EXCELの関数"STDEV(標準偏差)"...
-
三菱シーケンサ(Aシリーズ)で...
-
VB.net Double と...
-
計算の丸め誤差の解消について
-
除算を使わずに10で割りたい。
-
2進数の足し算(C言語)
-
16進数 加算 減算 C言語
-
”/”を使わずに割り算したいんで...
-
CRCの計算方法について
-
VB6.0での小数点の扱いについて
-
VBAでミリ秒まで出力する方法
-
時刻の比較
-
2進数データのビット演算
-
教えて小数点の比較!(C言語)
-
C言語 型変換のタイミング
おすすめ情報