7

みんなおはよう、

浮動小数点演算で問題が発生し、「。to_f」、「* 100」、「。0」で完全に失われました。

私は誰かが私の特定の問題について私を助けてくれることを望んでいました。また、次回のためにこれを理解できるように、彼らの解決策が機能する理由を正確に説明してください。

私のプログラムは2つのことをする必要があります:

  1. 小数のリストを合計し、合計が正確に1.0になるかどうかを判断します
  2. 1.0と数値の合計の差を決定します-変数の値を正確な差に設定して、合計が1.0になるようにします。

例えば:

  1. [0.28、0.55、0.17]->合計は1.0になるはずですが、1.xxxxxxを取得し続けます。私は次の方法で合計を実装しています:

    sum = array.inject(0.0){|sum,x| sum+ (x*100)} / 100
    
  2. この機能が必要な理由は、Excelからの小数のセットを読み取っているからです。これらは100%正確ではないため(小数点が不足しています)、通常、合計は0.999999xxxxxまたは1.000xxxxxになります。たとえば、次のような値を取得します。

    0.568887955,0.070564759,0.360547286
    

これを修正するには、最初のn-1の数値の合計を取り、最後の数値を少し変更して、すべての数値の合計が1.0になるようにします(上記の式を使用した検証、または最終的には何でも満たす必要があります) )。私は現在、これを次のように実装しています。

          sum = 0.0
          array.each do |item|
            sum += item * 100.0
          end
          array[i] = (100 - sum.round)/100.0

インジェクトでこれができることは知っていますが、何が機能するかを確認するためにそれを試してみました。これは(出力の検査から)一般的に機能していると思いますが、上記の検証合計を常に満たすとは限りません。したがって、必要に応じて、これも調整できます。これらの数値には、小数点以下2桁の精度しか必要ないことに注意してください。つまり、0.5623225ではなく0.56です。プレゼンテーション時、またはこの計算中に切り捨てることができます...私には関係ありません。

ご助力ありがとうございます!

4

3 に答える 3

11

精度が重要な場合は、定義上、正確ではない浮動小数点値を使用しないでください。Ruby には、精度が重要な演算を行うための精度データ型がいくつかあります。それらは、実際に計算する必要があるものに応じて、頭の中で 、BigDecimalRationalおよびです。Complex

あなたの場合、探しているのは BigDecimal のようです。これは基本的に固定桁数の数値であり、小数点以下の固定桁数があります(浮動小数点とは対照的に、小数点以下の桁数は任意です)。

Excel から読み取り、意図的に "0.9987" のような文字列を浮動小数点にキャストすると、文字列に含まれている正確な値がすぐに失われます。

require "bigdecimal"
BigDecimal("0.9987")

その値は正確です。0.9987です。0.998732109、またはそれに近いものではなく、0.9987 です。通常の算術演算をすべて使用できます。算術演算に浮動小数点を混ぜない限り、戻り値は正確なままです。

配列に Excel から取得した生の文字列が含まれている場合 (つまり#to_f、それらを 'd していない場合)、これにより、それらの合計と 1 の差である BigDecimal が得られます。

1 - array.map{|v| BigDecimal(v)}.reduce(:+)
于 2012-05-28T14:01:54.970 に答える
2

また:

  • フロートとround(2)合計を引き続き使用します。12.341.round(2) # => 12.34

  • 整数を使用する (つまり、ドルではなくセント)

  • BigDecimal を使用すると、小数点以下 2 桁のみで BigDecimal を開始する限り、それらを合計した後に丸める必要はありません。

于 2012-05-28T14:01:22.433 に答える
0

アルゴリズムは、別の表現ではなく IEEE 浮動小数点を選択するよりも、精度と精度に大きく関係していると思います。

正確さと精度の問題に対処しながら、人々はいくつかの細かい計算を行っていました。彼らは、使用するアルゴリズムを管理し、関数をより深く表現する方法を理解することによってそれを行います. そのより良い理解を脇に置き、別の表現が解決策であると仮定することは、間違いを犯している可能性があると思います.

たとえば、関数の多項式表現は、漸近線または特異点を適切に処理しません。

浮動小数点をすぐに破棄しないでください。それらの使い方を賢くすることで、うまくいくかもしれません。

于 2012-05-28T16:35:54.257 に答える