整数除算:1/3 == 0 の結果はなぜですか?
-
11-10-2019 - |
質問
私はこのコードを書いていました:
public static void main(String[] args) {
double g = 1 / 3;
System.out.printf("%.2f", g);
}
結果は 0 です。これはなぜですか?この問題を解決するにはどうすればよいですか?
解決
2つのオペランド(1および3)は整数であるため、整数算術(ここの分割)が使用されます。結果変数をダブルとして宣言すると、暗黙の変換が発生するだけです 分割後.
もちろん、整数部門は、ゼロに丸められた分割の真の結果を返します。結果として 0.333...
したがって、ここでは0に丸められます。 (プロセッサは実際には丸めをかけていませんが、それでもそのように考えることができます。)
また、IFに注意してください 両方とも オペランド(数字)はフロートとして与えられます。 3.0と1.0、または単なる 最初, 、その後、浮動小数点の算術が使用され、あなたに与えます 0.333...
.
他のヒント
1/3
両側は整数であるため、整数部門を使用します。
そのうちの少なくとも1つが必要です float
また double
.
質問のようにソースコードに値を入力している場合は、できる 1.0/3
; 1.0
ダブルです。
他の場所から値を取得した場合、使用できます (double)
を回す int
に double
.
int x = ...;
int y = ...;
double value = ((double) x) / y;
明示的にそれをキャストします double
double g = 1.0/3.0
これは、Javaが整数部門操作を使用しているために起こります 1
と 3
整数定数として入力したため。
使用する必要があります
double g=1.0/3;
また
double g=1/3.0;
整数部門は整数を返します。
あなたが整数部門をやっているからです。
@noldorinが言うように、両方の演算子が整数である場合、整数部門が使用されます。
結果0.33333333は整数として表現できないため、整数部(0)のみが結果に割り当てられます。
オペレーターのいずれかがaの場合 double
/ float
, 、その後、浮動小数点算術が行われます。しかし、あなたがそれをするなら、あなたは同じ問題を抱えています:
int n = 1.0 / 3.0;
1と3を整数として扱い、したがって結果を0に丸めているため、整数になります。
探している結果を得るには、数字がそうであるように倍増していることをJavaに明示的に伝えます。
double g = 1.0/3.0;
1フロートとフロート部門を使用する
public static void main(String d[]){
double g=1f/3;
System.out.printf("%.2f",g);
}
Javaの変換は非常に簡単ですが、理解が必要です。 JLSで説明するように 整数操作:
シフト演算子以外の整数演算子に少なくとも1つのオペランドが長い場合、操作は64ビット精度を使用して実行され、数値演算子の結果は型長いです。他のオペランドが長くない場合、最初に拡張され(§5.1.5)、数値プロモーション(§5.6)によって長いタイプを入力します。
そして、例は常に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つが2倍の場合、操作は64ビットの浮動小数点算術を使用して実行され、数値演算子の結果はタイプのダブルの値です。他のオペランドが2倍でない場合、最初に拡張され(§5.1.5)、数値プロモーション(§5.6)によって2倍タイプします。
そのため、プロモーションはフロートでダブルに行われます。
そして、整数と浮動値の両方のミックスは、言ったように浮動的な値をもたらします
バイナリ演算子へのオペランドの少なくとも1つが浮動小数点タイプである場合、他のものが積分であっても、動作は浮動小数点操作です。
これはバイナリ演算子に当てはまりますが、「割り当て演算子」のようなものではありません +=
これを証明するのに十分な単純な作業例で十分です
int i = 1;
i += 1.5f;
その理由は、ここで行われた暗黙のキャストがあるため、これは次のように実行されます
i = (int) i + 1.5f
i = (int) 2.5f
i = 2
1と3は整数のコンタントであるため、Javaは整数部門を行い、結果の結果は0です。 1.0
と 3.0
.
最も簡単な解決策は、これを行うことです
double g = ((double) 1 / 3);
1.0 / 3.0を入力しなかったため、Javaが整数部門であると想定していたため、データ型を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の両方がINTであるため、結果は丸められていませんが、切り捨てられています。したがって、あなたは分数を無視し、whowersのみを取ることができます。
これを避けるために、小数式1.0および/または3.0として、1つまたは3の数字の少なくとも1つを持っています。
「double g = 1.0/3.0;」代わりは。
他の多くの人は、本当の問題を指摘できませんでした。
整数のみの操作は、整数の操作の結果を整数にキャストします。
これは、必然的に浮動小数点が生じることを意味します たぶん......だろう 整数として表示され、切り捨てられます(小数部から外れています)。
とは 鋳造 (タイプキャスト /タイプ変換)あなたは尋ねますか?
それは言語の実装によって異なりますが、ウィキペディアにはかなり包括的な見解があり、それは話しています 強制 同様に、これはあなたの質問に答える際の重要な情報です。
これを試してみてください:
public static void main(String[] args) {
double a = 1.0;
double b = 3.0;
double g = a / b;
System.out.printf(""+ g);
}