web-dev-qa-db-ja.com

Java-これはバグですか、それとも機能ですか?

Javaアプリケーションでこの簡単な計算を試みています:

System.out.println("b=" + (1 - 7 / 10));

明らかに、出力はb=0.3になるはずですが、実際にはb=1になります。

何?!なぜこれが起こるのですか?

私が書いた場合:

System.out.println("b=" + (1 - 0.7));

b=0.3という正しい結果が得られます。

ここで何が問題になっていますか?

16
msr

整数除算を使用しています。

7.0/10代わりに。

60
Xavier Ho

式7/10で整数を使用しましたが、整数7を整数10で割った値はゼロです。

あなたが期待しているのは、浮動小数点除算です。以下のいずれかが、予想した方法を評価します。

7.0 / 10
7 / 10.0
7.0 / 10.0
7 / (double) 10
24
JustJeff

これを質問の答えとして受け取らないでください。そうではありませんが、intとfloatの違いを利用することに関するアドバイスです。回答ボックスでこのコメントをフォーマットできることを除いて、コメントの下にこれを配置します。

この機能は、Fortran(またはそれ以前)の時代からすべての立派なプログラミング言語で使用されてきました-私はかつてFortranおよびCobolパンチカードプログラマーだったことを認めなければなりません。

例として、整数には小数残差.3333 ..を保持する機能がないため、10/3の整数除算では整数値3が生成されます。

私たち(昔のプログラマー)がこの機能を使用していた方法の1つは、ループ制御です。

1000個の文字列の配列を出力したいが、15番目の文字列ごとに改行を挿入して、行末と次の行の先頭にきれいな文字を挿入するとします。整数kがその配列内の文字列の位置であることを考えると、これを活用します。

int(k/15)*15 == k

kが15で割り切れる場合にのみtrueになります。これは、15番目のセルごとの頻度で発生します。これは、私の友人が祖父のデッドウォッチを1日2回正確であると言ったことに似ています。

int(1/15) = 0 -> int(1/15)*15 = 0
int(2/15) = 0 -> int(2/15)*15 = 0
...
int(14/15) = 0 -> int(14/15)*15 = 0
int(15/15) = 1 -> int(15/15)*15 = 15

int(16/15) = 1 -> int(16/15)*15 = 15
int(17/15) = 1 -> int(17/15)*15 = 15
...
int(29/15) = 1 -> int(29/15)*15 = 15
int(30/15) = 2 -> int(30/15)*15 = 30

したがって、ループ、

leftPrettyfy();
for(int k=0; k<sa.length; k++){
  print(sa[k]);
  int z = k + 1;
  if ((z/15)*15 == z){
    rightPrettyfy();
    leftPrettyfy();
  }
}

ループ内でkを空想的な方法で変化させることにより、三角形の印刷物を印刷できます。

1
2  3
4  5  6
7  8  9  10
11 12 13 14 15

これは、これをバグと見なす場合、この「bug」はこれまで使用してきたさまざまな言語から削除したくない便利な機能であることを示すためです。

9
Blessed Geek

私は文字の識別子がより読みやすく、解析されたタイプをよりよく示すと思います:

1 - 7f / 10
1 - 7 / 10f

または:

1 - 7d / 10
1 - 7 / 10d
1
Fred Haslam

私の場合、私はこれをやっていた:

double a = (double) (MAX_BANDWIDTH_SHARED_MB/(qCount+1));

「正しい」の代わりに:

double a = (double)MAX_BANDWIDTH_SHARED_MB/(qCount+1);

括弧に注意してください!

0
Felipe Volpato