3

私は、円内の座標(r ^ 2 = x ^ 2 + y ^ 2)がr = 1である方程式を解く学校の課題を行っており、yを解くx値をインクリメントします。10分の1しかインクリメントしないのに、循環小数が表示されます。理由がわからないので、いくつかの方法で試しました。これがコードです。

    double r = 1;
    double rSqr;
    double x = 1;
    double xSqr;
    double y;
    double ySqr;
    double inc = 0.1;
    int count = 0;
    while(x > -r)
    {
        x = r - (count * inc);
        rSqr = Math.pow(r, 2);
        xSqr = Math.pow(x, 2);
        ySqr = rSqr - xSqr;
        y = Math.sqrt(ySqr);
        count++;
        System.out.println(x + " " + y);
    }

そして出力はこれです

1.0 0.0
0.9 0.4358898943540673
0.8 0.5999999999999999
0.7 0.714142842854285
0.6 0.8
0.5 0.8660254037844386
0.3999999999999999 0.9165151389911681
0.29999999999999993 0.9539392014169457
0.19999999999999996 0.9797958971132712
0.09999999999999998 0.99498743710662
0.0 1.0
-0.10000000000000009 0.99498743710662
-0.20000000000000018 0.9797958971132712
-0.30000000000000004 0.9539392014169457
-0.40000000000000013 0.9165151389911679
-0.5 0.8660254037844386
-0.6000000000000001 0.7999999999999999
-0.7000000000000002 0.7141428428542849
-0.8 0.5999999999999999
-0.9000000000000001 0.43588989435406705
-1.0 0.0
4

2 に答える 2

4

問題はそれdoubleが不正確であるということです。10進数を表すために64ビットを使用します。一部のビットは数値部分に使用され、一部は指数に使用されますが、たとえば、一見単純な10進数の多くは、この方法では正確に表現できません0.1。詳細については、このwikiの記事を参照してください。

この問題を回避する1つの方法は、を使用して数値を表示するDecimalFormatことです。これにより、表示目的で数値を丸めることができます。次にいくつかのサンプルコードを示します。

public static void main(String[] args) {
    DecimalFormat decimalFormat = new DecimalFormat("#0.000");
    double d = 1 - .9; // one way to get a repeating decimal floating point number 
    System.out.println(d);
    System.out.println(decimalFormat.format(d));
}

出力:

0.09999999999999998
0.100
于 2012-11-17T18:09:53.760 に答える
1

これは、IEEE754浮動小数点表現です。

問題を解決する代わりに、データ型としてBigDecimalを使用してください。doubleただし、そのまま注意しBigDecimalimmutableください。

        BigDecimal r = BigDecimal.ONE;
        BigDecimal rSqr;
        BigDecimal x = BigDecimal.ONE;
        BigDecimal xSqr;
        BigDecimal y;
        BigDecimal ySqr;
        BigDecimal inc = new BigDecimal("0.1");
        int count = 0;

        while(x.compareTo(r.negate())>0)
        {
        // i'll let you fill in this part
        }
于 2012-11-17T17:53:40.730 に答える