フロートとフロートの丸めの代わりにダブル

jakstack

編集:この質問は2つのトピックをカバーしています:

  • フロートの代わりにダブルで使用する効率
  • 丸め後の浮動小数点精度

floatの代わりにJavadoubleを常に使用する必要がない理由はありますか?

floatを使用する場合のこのテストコードは失敗し、doubleの代わりにfloatを使用することが唯一の違いであるため、理由が明確でないため、この質問をします。

public class BigDecimalTest {
@Test public void testDeltaUsingDouble() { //test passes
    BigDecimal left = new BigDecimal("0.99").setScale(2,BigDecimal.ROUND_DOWN);
    BigDecimal right = new BigDecimal("0.979").setScale(2,BigDecimal.ROUND_DOWN);

    Assert.assertEquals(left.doubleValue(), right.doubleValue(), 0.09);
    Assert.assertEquals(left.doubleValue(), right.doubleValue(), 0.03);

    Assert.assertNotEquals(left.doubleValue(), right.doubleValue(), 0.02);
    Assert.assertNotEquals(left.doubleValue(), right.doubleValue(), 0.01);
    Assert.assertNotEquals(left.doubleValue(), right.doubleValue(), 0.0);
}
@Test public void testDeltaUsingFloat() {  //test fails on 'failing assert'

    BigDecimal left = new BigDecimal("0.99").setScale(2,BigDecimal.ROUND_DOWN);
    BigDecimal right = new BigDecimal("0.979").setScale(2,BigDecimal.ROUND_DOWN);

    Assert.assertEquals(left.floatValue(), right.floatValue(), 0.09);
    Assert.assertEquals(left.floatValue(), right.floatValue(), 0.03);

    /* failing assert */ Assert.assertNotEquals(left.floatValue() + " - " + right.floatValue() + " = " + (left.floatValue() - right.floatValue()),left.floatValue(), right.floatValue(), 0.02);
    Assert.assertNotEquals(left.floatValue(), right.floatValue(), 0.01);
    Assert.assertNotEquals(left.floatValue(), right.floatValue(), 0.0);
}}

失敗メッセージ:

java.lang.AssertionError: 0.99 - 0.97 = 0.01999998. Actual: 0.9900000095367432
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failEquals(Assert.java:185)
at org.junit.Assert.assertNotEquals(Assert.java:230)
at com.icode.common.BigDecimalTest.testDeltaUsingFloat(BigDecimalTest.java:34)

このテストが失敗する理由と、floatの代わりに常にdoubleを使用するべきではない理由はありますか?もちろん、ダブル以外の理由はフロートよりも広いです。

編集:面白いことに、Assert.assertNotEquals(double、double、delta)はどちらの場合もdoubleを取るので、失敗したテストで返されるフロートはとにかくdoubleとして拡大されますが、なぜテストが失敗するのですか?

編集:この他の質問が関連している可能性がありますが、確かではありません16進数は同じではありません

編集:この質問の16進数の答えは同じではありませんが、 floatの.99の科学的表現IEEE 754は、同じ値のdoubleとは異なると結論付けることができます。これは丸めによるものです。

したがって、これを取得します。

  • 0.99-0.97 = 0.01999998 //フロートの場合
  • 0.99-0.97 = 0.020000000000000018 //二重の場合

上記の単体テストの最大デルタは0.02であり、(失敗したテストの)0.01999998はデルタ値を下回っているため、数値は同じであるように見えますが、テストは失敗していないと主張しています。

みんなあなたはこれすべてに同意しますか?

エリック・ポストピシル

BigDecimalドキュメントには、floatValue()ラウンドの方法については記載されていません私はそれが最も近い、均等に結ぶことを使用していると思います。

leftおよびrightは、それぞれ.99および.97に設定されます。これらをdouble最も近い丸めモードに変換すると、結果は0.9999999999999999911182158029987476766109466552734375(16進浮動小数点、0x1.fae147ae147aep-1)および0.9699999999999999733546474089962430298328399658203125(0x1.f0a3d70a3d70ap-1)になります。それらを引くと、結果は0.020000000000000017763568394002504646778106689453125になり、明らかに.02を超えます。

.99と.97をに変換するfloatと、結果は0.9900000095367431640625(0x1.fae148p-1)と0.9700000286102294921875(0x1.f0a3d8p-1)になります。これらを差し引くと、結果は0.019999980926513671875になり、明らかに.02未満になります。

簡単に言えば、10進数を浮動小数点に変換すると、丸めが上下する場合があります。これは、最も近い表現可能な浮動小数点値に対して、数値がたまたまどこにあるかによって異なります。それが制御または分析されていない場合、それは実質的にランダムです。したがって、予想よりも大きな値になる場合もあれば、小さい値になる場合もあります。

double代わりに使用しても、上記のような結果が発生しないfloatこと保証されません。doubleこの場合値が正確な数学的値を超え、値が超えなかったのは偶然ですfloat他の数字では、逆になる可能性があります。例えば、とはdouble.09-.07以下0.02以上であるが、とfloat.09f、 - .07f`が0.02よりも大きいです。

浮動小数点演算のハンドブックなど、浮動小数点演算の処理方法に関する情報はたくさんありますStackOverflowの質問でカバーするには大きすぎるテーマです。その上に大学のコースがあります。

多くの場合、今日の一般的なプロセッサでdoubleは、float;よりも使用するための追加費用はほとんどありません単純なスカラ浮動小数点演算をするためのほぼ同じ速度で実行されるdoublefloatデータが多すぎて(ディスクからメモリまたはメモリからプロセッサに)転送する時間が重要になる場合、データがディスク上で占めるスペースが大きくなる場合、またはソフトウェアがプロセッサのSIMD機能を使用する場合、パフォーマンスの違いが発生します。(SIMDを使用すると、プロセッサは複数のデータに対して同じ操作を並行して実行できます。現在のプロセッサは通常、floatSIMD操作の帯域幅をSIMD操作の約2倍にするdoubleか、doubleSIMD操作をまったく提供しません。)

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

ダブルの代わりにフロートを使用した場合の奇妙な出力

分類Dev

ダブル/フロートをBINARY精度に丸める方法は?

分類Dev

名前付きタプルのPytestと丸めフロート

分類Dev

プログラムにフォルダの代わりにショートカットを使用させる

分類Dev

整数の代わりに軸上のMatplotlibフロート値

分類Dev

grubの代わりにWindows10グラフィカルブートローダーを使用するにはどうすればよいですか?

分類Dev

jsonファイルの代わりにjsonオブジェクトをロードする方法

分類Dev

ブログ投稿の代わりにWooCommerce製品を検索するための検索フィールド

分類Dev

バッチの代わりにテンソルフローデータセットシャッフルの例

分類Dev

C#とPythonのフロート丸めの違い

分類Dev

printfがフロートするときの丸めの問題

分類Dev

ブートストラップモーダルの代わりにPHPファイルが開きます

分類Dev

フロートを次の奇数の整数に丸めます

分類Dev

Googleチャートコントロール-スライダーの代わりに最小および最大入力フィールド

分類Dev

サブフォルダーweb.configの代わりにルートweb.configを使用します

分類Dev

Visual Studio 2019:ソリューションエクスプローラーでプロジェクトをダブルクリックすると、プロジェクトファイルの表示を切り替える代わりに、.csprojファイルが開きます

分類Dev

フロートを四分の一に丸める方法

分類Dev

フロートをhaskellのintに丸める

分類Dev

フォームを送信する代わりに、CodeIgniterフォームのダウンロードファイル

分類Dev

「真の」結果が十分に正確に表現できない場合、ダブル/フロートはどのように丸められますか?

分類Dev

ApacheSamzaローカルストレージ-KVストアの代わりにOrientDB / Neo4Jグラフ

分類Dev

phpフォームはSQLクエリをアップロードする代わりに別のファイルにリダイレクトします

分類Dev

ここでフロートはどのようにしてダブルに変わりましたか?

分類Dev

ifブロックの代わりにシングルトンでwhileループ

分類Dev

ユーザープロファイルの代わりにアクティブなリストを介したEtsyAPIターゲットリージョン

分類Dev

(0f、1f)値の代わりにワールドユニットを使用したフィードシェーダープログラム

分類Dev

Django-ドロップダウンフォームにオブジェクトの代わりに外部キー値を表示する

分類Dev

ブール変更アプリケーションフローの代わりにオブジェクトを使用する

分類Dev

jの代わりにiを使用して複素数のテキストファイルをロードする

Related 関連記事

  1. 1

    ダブルの代わりにフロートを使用した場合の奇妙な出力

  2. 2

    ダブル/フロートをBINARY精度に丸める方法は?

  3. 3

    名前付きタプルのPytestと丸めフロート

  4. 4

    プログラムにフォルダの代わりにショートカットを使用させる

  5. 5

    整数の代わりに軸上のMatplotlibフロート値

  6. 6

    grubの代わりにWindows10グラフィカルブートローダーを使用するにはどうすればよいですか?

  7. 7

    jsonファイルの代わりにjsonオブジェクトをロードする方法

  8. 8

    ブログ投稿の代わりにWooCommerce製品を検索するための検索フィールド

  9. 9

    バッチの代わりにテンソルフローデータセットシャッフルの例

  10. 10

    C#とPythonのフロート丸めの違い

  11. 11

    printfがフロートするときの丸めの問題

  12. 12

    ブートストラップモーダルの代わりにPHPファイルが開きます

  13. 13

    フロートを次の奇数の整数に丸めます

  14. 14

    Googleチャートコントロール-スライダーの代わりに最小および最大入力フィールド

  15. 15

    サブフォルダーweb.configの代わりにルートweb.configを使用します

  16. 16

    Visual Studio 2019:ソリューションエクスプローラーでプロジェクトをダブルクリックすると、プロジェクトファイルの表示を切り替える代わりに、.csprojファイルが開きます

  17. 17

    フロートを四分の一に丸める方法

  18. 18

    フロートをhaskellのintに丸める

  19. 19

    フォームを送信する代わりに、CodeIgniterフォームのダウンロードファイル

  20. 20

    「真の」結果が十分に正確に表現できない場合、ダブル/フロートはどのように丸められますか?

  21. 21

    ApacheSamzaローカルストレージ-KVストアの代わりにOrientDB / Neo4Jグラフ

  22. 22

    phpフォームはSQLクエリをアップロードする代わりに別のファイルにリダイレクトします

  23. 23

    ここでフロートはどのようにしてダブルに変わりましたか?

  24. 24

    ifブロックの代わりにシングルトンでwhileループ

  25. 25

    ユーザープロファイルの代わりにアクティブなリストを介したEtsyAPIターゲットリージョン

  26. 26

    (0f、1f)値の代わりにワールドユニットを使用したフィードシェーダープログラム

  27. 27

    Django-ドロップダウンフォームにオブジェクトの代わりに外部キー値を表示する

  28. 28

    ブール変更アプリケーションフローの代わりにオブジェクトを使用する

  29. 29

    jの代わりにiを使用して複素数のテキストファイルをロードする

ホットタグ

アーカイブ