私はこのコードを書いていました:
public static void main(String[] args) {
double g = 1 / 3;
System.out.printf("%.2f", g);
}
結果は0です。これはなぜですか。この問題を解決する方法を教えてください。
2つのオペランド(1と3)は整数であるため、整数演算(ここでは除算)が使用されます。結果変数をdoubleとして宣言すると、暗黙的な変換が発生します除算後。
もちろん整数除算は、ゼロに丸められた除算の真の結果を返します。したがって、0.333...
の結果はここでは0に切り捨てられます。 (プロセッサは実際には丸めを行いませんが、それでもそのように考えることができます。)
また、bothオペランド(数値)がfloatとして指定されている場合も注意してください。 3.0と1.0、またはfirstのみを使用した場合、浮動小数点演算が使用され、0.333...
が得られます。
1/3
は両側が整数であるため、整数除算を使用します。
少なくとも1つはfloat
またはdouble
である必要があります。
質問のようにソースコードに値を入力する場合は、1.0/3
を実行できます。 1.0
はdoubleです。
他の場所から値を取得する場合は、(double)
を使用してint
をdouble
に変換できます。
int x = ...;
int y = ...;
double value = ((double) x) / y;
double
として明示的にキャストします
double g = 1.0/3.0
これは、Javaが整数定数として入力したため、1
および3
の整数除算演算を使用するために発生します。
整数除算をしているからです。
@Noldorinが言うように、両方の演算子が整数の場合、整数除算が使用されます。
結果0.33333333は整数として表現できないため、整数部分(0)のみが結果に割り当てられます。
演算子のいずれかがdouble
/float
である場合、浮動小数点演算が行われます。ただし、それを行うと同じ問題が発生します。
int n = 1.0 / 3.0;
あなたは使うべきです
double g=1.0/3;
または
double g=1/3.0;
整数除算は整数を返します。
最も簡単な解決策は、これを行うことです
double g = ((double) 1 / 3);
1.0/3.0を入力しなかったため、これが行うことは、Javaが整数除算であると想定し、変換を狭めることを意図した場合でも、データ型doubleに手動で変換できるようにすることです。 。これは、キャスト演算子と呼ばれるものです。
1と3は整数定数であるため、Javaは整数除算を行い、結果は0です。二重定数を記述したい場合は、1.0
と3.0
を記述する必要があります。
1と3を整数として扱うため、結果を0に切り下げて整数にします。
探している結果を得るには、Javaに数値が次のように2倍であることを明示的に伝えます。
double g = 1.0/3.0;
1をフロートにし、フロート除算を使用します
public static void main(String d[]){
double g=1f/3;
System.out.printf("%.2f",g);
}
Javaでの変換は非常に簡単ですが、ある程度の理解が必要です。 整数演算 のJLSで説明されているように:
シフト演算子以外の整数演算子にlong型のオペランドが少なくとも1つある場合、演算は64ビット精度を使用して実行され、数値演算子の結果はlong型になります。もう一方のオペランドが長くない場合、最初に数値の昇格(§5.6)でlong型に拡張されます(§5.1.5)。
そして、例は常にJLSを翻訳する最良の方法です;)
int + long -> long
int(1) + long(2) + int(3) -> long(1+2) + long(3)
それ以外の場合、演算は32ビット精度を使用して実行され、数値演算子の結果はint型になります。いずれかのオペランドがintでない場合、最初に数値プロモーションによってint型に拡張されます。
short + int -> int + int -> int
Eclipseを使用して2つのshort
sを追加してもそれほど簡単ではないことを示す小さな例:
short s = 1;
s = s + s; <- Compiling error
//possible loss of precision
// required: short
// found: int
これには、精度が失われる可能性のある鋳造が必要です。
浮動小数点演算子 についても同じことが言えます
数値演算子のオペランドの少なくとも1つがdouble型である場合、演算は64ビット浮動小数点演算を使用して実行され、数値演算子の結果はdouble型の値になります。もう一方のオペランドがdoubleでない場合、数値プロモーション(§5.6)でdoubleを入力するために、最初にオペランドが広げられます(§5.1.5)。
したがって、プロモーションはフロートでダブルに行われます。
そして、整数と浮動値の両方が混在すると、前述のように浮動値になります
二項演算子のオペランドの少なくとも1つが浮動小数点型である場合、もう一方が整数であっても、演算は浮動小数点演算になります。
これは二項演算子には当てはまりますが、+=
のような「代入演算子」には当てはまりません。
これを証明するには、単純な実例で十分です
int i = 1;
i += 1.5f;
理由は、ここで暗黙のキャストが行われ、これが次のように実行されるからです。
i = (int) i + 1.5f
i = (int) 2.5f
i = 2
(1/3)は整数除算を意味します。これが、この除算から小数値を取得できない理由です。この問題を解決するには:
public static void main(String[] args) {
double g = 1.0 / 3;
System.out.printf("%.2f", g);
}
public static void main(String[] args) {
double g = 1 / 3;
System.out.printf("%.2f", g);
}
1と3は両方とも整数なので、結果は丸められませんが、切り捨てられます。したがって、分数を無視し、整数のみを取ります。
これを回避するには、1または3の数字の少なくとも1つを10進数形式1.0または3.0として使用します。