2

重複の可能性:
Ruby の算術

status_update モデルは 2 つの値を取り、それらを使っていくつかの簡単な計算を行い、そこから「current_lbm」と「current_bf_pct」を割り当てます。

current_lbm と current_bf_pct は、制限しないと大量の小数を生成するため、.round(2) メソッドを使用して値を小数点以下 2 桁に制限しました。

これを行うメソッドを次に示します。

after_initialize :default_values
.
.
def default_values      
 if self.current_bf_pct >= 0.5
   self.current_bf_pct /= 100
    if self.current_bf_pct <= 0.04
      self.current_fb_pct *= 100
    end 
 end
 self.current_fat_weight = self.current_weight * self.current_bf_pct
 self.current_lbm = self.current_weight - self.current_fat_weight
 self.current_fat_weight = self.current_fat_weight.round(2)
 self.current_lbm = self.current_lbm.round(2)
end   

結果は次のとおりです。

09/13/2012 186.0 4.5 177.63 8.37
09/13/2012 187.0 5.5 176.72 10.29
09/13/2012 188.0 6.5 175.78 12.22
09/13/2012 189.0 7.5 174.83 14.18
09/13/2012 190.0 8.5 173.85 16.15
09/13/2012 191.0 9.5 172.86 18.15
09/13/2012 192.0 10.5 171.84 20.16
09/13/2012 193.0 11.5 170.81 22.2
09/13/2012 194.0 12.5 169.75 24.25
09/13/2012 195.0 13.5 168.68 26.33
09/13/2012 196.0 14.499999999999998 167.58 28.42
09/13/2012 197.0 15.5 166.47 30.54
09/13/2012 198.0 16.5 165.33 32.67
09/13/2012 199.0 17.5 164.18 34.82
09/13/2012 200.0 18.5 163.0 37.0   

私の質問は... 14.499999999999998 で一体何が起こっているのですか??

これらはビューからの結果です。current_bf_pct 行は、日付から 3 番目の行です。ビューで 100 を掛けるので、小数ではありません。

4

1 に答える 1

3

フロートをそのまま表示する場合は、これを回避できません(rubyの算術演算を参照)。フロートを文字列に変換して表示することをお勧めします。

例(実際の結果は異なる場合があります):

>> 7.3-7.2
=> 0.09999999999999964

小数点以下1桁の文字列に変換します。

>> '%.1f' % (7.3-7.2)
=> "0.1"

'%'演算子は、次の省略形です。

sprintf '%.1f', (7.3-7.2)

を読んでくださいsprintf。少し学習曲線ですが、非常に強力です。

もう1つの解決策は、BigDecimalを使用することです(2番目の引数は精度です。これが何を意味するかを必ず理解してください)。

BigDecimal(7.3-7.2, 1).to_s

十分に大きな精度を使用すると、問題が再び発生します。

>> BigDecimal(7.3-7.2, 16).to_s
=> "0.09999999999999964"
于 2012-09-13T20:32:11.967 に答える