9

プログラムを C# から Java に移植しています。という事実に直面しました

ジャワ

Math.pow(0.392156862745098,1./3.) = 0.7319587495200227

C#

Math.Pow( 0.392156862745098, 1.0 / 3.0) =0.73195874952002271

この最後の数字は、その後の計算で十分な違いをもたらします。C# の pow をエミュレートする方法はありますか?

ありがとう

4

6 に答える 6

35

Chris Shain が書いたことを確認するために、同じバイナリ値を取得します。

// Java
public class Test
{
    public static void main(String[] args)
    {
        double input = 0.392156862745098;
        double pow = Math.pow(input, 1.0/3.0);            
        System.out.println(Double.doubleToLongBits(pow));
    }
}

// C#
using System;

public class Test
{
    static void Main()
    {
        double input = 0.392156862745098;
        double pow = Math.Pow(input, 1.0/3.0);            
        Console.WriteLine(BitConverter.DoubleToInt64Bits(pow));
    }
}

両方の出力: 4604768117848454313

つまり、double 値はまったく同じビット パターンであり、(同じ結果が得られると仮定して) 表示されている違いは、値の違いではなく、書式設定によるものです。ちなみに、その double の正確な値は

0.73195874952002271118800535987247712910175323486328125

ここで、浮動小数点演算で明らかに奇妙なことが発生する可能性があることに注意してください。特に、最適化によって 80 ビット演算が許可される状況と許可されない状況がある場合などです。

Henk が言うように、最後の 1 つか 2 つの違いが問題を引き起こす場合、その設計は壊れています。

于 2012-04-12T20:16:07.103 に答える
18

計算がこの種の違いに敏感な場合は、他の手段 (再設計) が必要になります。

于 2012-04-12T20:11:57.633 に答える
13

この最後の桁は、以降の計算で十分な違いにつながります

それらは同じ数なので、それは不可能です。Aには、とdoubleを区別するのに十分な精度がありません。それらは両方ともとして表されます0.73195874952002270.73195874952002271

0.73195874952002271118800535987247712910175323486328125.

違いは丸めです。Javaは16桁の有効数字を使用し、C#は17桁を使用しています。しかし、これは単なる表示の問題です。

于 2012-04-12T20:23:37.947 に答える
8

Java と C# はどちらも、Math.Pow から IEEE 浮動小数点数 (具体的には double) を返します。表示されている違いは、ほぼ間違いなく、数値を 10 進数で表示するときの書式設定によるものです。基になる (バイナリ) 値はおそらく同じであり、数学の問題は別の場所にあります。

于 2012-04-12T20:13:09.817 に答える
1

17桁の精度は、言語に関係なく、IEEE浮動小数点数で実行できる最高の精度です。

http://en.wikipedia.org/wiki/Double-precision_floating-point_format

于 2012-04-12T22:07:23.517 に答える
1

浮動小数点演算は本質的に不正確です。C# の回答の方が「優れている」と主張していますが、どちらもそれほど正確ではありません。たとえば、Wolfram Alpha (実際にははるかに正確です) は次の値を提供します。

http://www.wolframalpha.com/input/?i=Pow%280.392156862745098%2C+1.0+%2F+3.0%29

17 桁目の単位の違いが後の計算の失敗を引き起こしている場合、Java の の実装ではなく、数学に問題があると思いますpow。このような小さな違いに依存しないように、計算を再構築する方法を考える必要があります。

于 2012-04-12T20:16:45.373 に答える