1

私のアプリケーションには次のコードがあり、文字列を解析してdoubleに変換する必要があります

int i = ((QString)"294.4").toDouble() * 100;

私は値29440をiの値として見ることになっています。ただし、そうするたびに29439の値が得られます。常に発生するとは限らないため、なぜ発生しているのかわかりません。たとえば、294.1、294.2、294.3は正常に機能します。294.5も正常に動作します。

浮動小数点数の解釈が問題になるはずであり、未確定の動作が予想されることは理解していますが、これは非常に単純なケースのようです。

誰かが値を確実に解析して、同等の文字列で表される正確な値を常に提供する方法を教えてもらえますか?

4

1 に答える 1

3

これはQtの問題ではなく、浮動小数点数の内部表現の問題です(基数10ベースではなく、基数2ベース)。通貨を表すためにDoubleまたはFloatを使用しないのはなぜですか?を参照してください。いくつかの良い背景情報のために。

正確な値に依存する場合は、浮動小数点数を使用せずに、整数と数値の小数部分を別々の整数に格納します。

int integ = 294;
int fraction = 4;   /* assumption: one fractional digit */

次に、計算にのみ整数演算を使用します。

浮動小数点数を表すライブラリクラスはありますか?を参照してください。これらの種類の計算のためのさまざまな既存のライブラリへのリンク。


コメントからのフィードバックに基づいて、文字列を整数部分と小数部分に解析することをお勧めします。たとえば、次のようになります。

struct Money {
    int integ;
    int fract;
};

Money parseMoney(const QString& input) {
    QString cleanInput = input;
    Money result = {0,0};

    // remove group separators
    QLocale locale = QLocale::system();
    cleanInput.remove(locale.groupSeparator());

    // convert to money
    QStringList parts = cleanInput.split(locale.decimalPoint());
    if (parts.count() == 1) {
       result.integ = parts[0].toInt();
    } else if (parts.count() == 2) {
       result.integ = parts[0].toInt();
       result.fract = parts[1].toInt() * 10;
    } else {
         // error, not a number
    }

    return result;
}

入力は現在のロケールに従ってフォーマットされた文字列であると想定されます。たとえば、グループ区切り文字が「」の場合、小数点は「。」です。入力文字列が「3,294.4」の場合、Moneyの結果は{3294、40}になります。

于 2012-10-16T10:27:50.607 に答える