2016-07-13 18 views
0

私はmysqlデータベースの金利を扱います。これらは二重に格納され、小数点以下の桁数(例:4.657)になりますが、時にはそれ以上です。時々、私はこれらを百分の1の場所(例:4.65)に報告する必要がありますが、これらを丸めることはできません - それらを切り捨てる必要があります。だから、5.6575%で私の金利データベースでは、私は5.65%ではなく、5.66%を取得する必要があります。MYSQL数値関数(floor、truncate)が期待通りに機能しない - 説明?

一般に、TRUNCATE(int_rate、2)はうまく動作します。これまで私は問題はなかった。

私は、以下の金利に問題があります:8.0300%、8.0400%、9.0300%、9.0400%、10.0300%、10.0400%...金利が8%を超えて3 4位は100位、残りは0位です。

TRUNCATE(int_rate、2)を実行すると、8.04がDBにある場合、8.03が返されます。 FLOOR(int_rate * 100)/ 100

数値をハードコードしてDBから抜かないと、TRUNCATE(8.04、2)またはTRUNCATEが正しく切り捨てられます。 (8.0400、2)は、期待どおり8.04を返します。

4.0400%でも問題ありません。だから8.0600%です!なぜこれらの結果を出すのですか?また、誰もがこのエラーなしでこれを行う方法を提案することができれば、それは驚くべきことでしょう!

のMySql:PHP floating point numbersから取ら5.0.95

+0

浮動小数点は概算です。 '8.04'は実際には' 8.0399999999'のようなものなので、それを切り捨てると '8.03'が返されます。 – Barmar

+0

'8.04'をハードコードすると、それは' DOUBLE'ではなくDECIMALとして解釈され、精度を失うことはありません。あなたのテーブルに 'DECIMAL'型を使わないのはなぜですか?これは精度を失うことのないアプリケーション向けに設計されています。 – Barmar

答えて

0

浮動小数点数は精度が限られています。それはシステムに依存しますが、PHPは通常、1.11e-16のオーダーの丸めによる最大相対誤差を与えるIEEE 754倍精度フォーマットを使用します。基本的でない算術演算は、より大きな誤差を与える可能性があり、もちろん、いくつかの演算が複合されたときにはエラー伝搬を考慮する必要があります。

さらに、基数10の浮動小数点数(0.1または0.7など)で正確に表現できる有理数は、基数2の浮動小数点数として正確には表現されません。仮数。したがって、それらは内部精度のわずかな損失なしに内部バイナリの対応物に変換することはできません。内部表現が7.99999999999991118 ....

のようになるので、floor((0.1 + 0.7)* 10)は通常予想される8の代わりに7を返します。可能な修正:TRUNCATEの代わりにROUNDを試しましたか?

+0

質問はPHPについてではなく、MySQLに関するものです。理由は同じですが、最後の段落は実際には適用されません。 – Barmar

+0

@Barmar ...あなたが正しいです...私はそれを削除...答えは、問題を説明し、私はソースを言及せずにウェブサイトからカットアンドペーストをしたくない... – patrick

+0

@Barmar:私は法的に丸められないので丸を使うことはできません。誰かが4.239の金利を持っているなら、4.24ではなく4.23が必要です。 私には分かりません。金利8.04- int_rate * 100 = 804 floor(int_rate * 100)= 803 int_rate 4.56789 * 100は456.789であるため、床を使用する必要があります。 – Charistine

関連する問題