簡體   English   中英

如何檢測浮點表示錯誤…99999…或…00000…並在C ++中對其進行更正

[英]How to detect floating point representation errors …99999… or …00000… and correct them in C++

我正在使用Firebird 1.5.x數據庫,該數據庫存儲在雙精度或numeric(15,2)字段中的變量存在問題。 例如,我可以發出更新(field_1和field_2被聲明為numeric(15,2)):

update test_table set
  field_1=0.34,
  field_2=0.69;

但是,當在SQL存儲過程中將field_1和field_2讀入變量var_1和var_2時,var_1和var_2分別假定值為0.340000000000000024和0.689999999999999947。 乘法var_1 * var_2 * 25得到5.8649999999999999635,可以四舍五入為5.86。 這顯然是錯誤的,因為正確的最終值為5.87。

四舍五入是通過用戶定義的函數完成的,該函數來自我開發的C ++ DLL。 想法是檢測具有表示錯誤的情況,進行更正,並將舍入過程僅應用於更正后的值。

因此,問題是-如何檢測和糾正表示法錯誤。 例如,檢測應將0.6899999999999999999947校正為0.69,然后檢測應將0.340000000000000024校正為0.34。 通常存在這樣的情況,即點后的有效數字個數大於或小於2,例如0.23459999999999999854應該校正為0.2346。

如果可能的話,可以使用C ++做到這一點,也許已經有一些解決方案了?

ps我在最新的Firebird 2.x版本中測試了這種情況,將數據庫字段讀入存儲過程中的變量沒有問題。 但是我可以猜測,盡管如此,在某些冗長的計算中,表示錯誤也會在最新的Firebird版本中出現。

謝謝!

在所有使用浮點變量的編程語言中都存在此問題。

您需要了解沒有顯示1/3的准確方法。 任何顯示該價值的行為都必須在有關各方之間達成妥協。 所需的精度必須得到同意。 如果您了解這一點,我們可以繼續。

那么,我們如何(例如)開發准確的會計系統? 一種方法是對在計算中使用的所有值進行舍入(column_name,required_precision)。 還可以將任何除法的結果四舍五入到相同的精度。 在整個應用程序中始終使用商定的精度非常重要。

另一種選擇是始終將浮點值乘以100(如果您的值表示貨幣),然后將結果值分配給Integer變量。 同樣,除法結果必須四舍五入到小數點后0位,然后再分配給整數存儲。 然后將值除以100以用於顯示。 這樣就好了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM