Int除算:1/3 == 0の結果はなぜですか?


107

私はこのコードを書いていました:

public static void main(String[] args) {
    double g = 1 / 3;
    System.out.printf("%.2f", g);
}

結果は0です。これはなぜですか。この問題を解決するにはどうすればよいですか。

回答:


147

2つのオペランド(1と3)は整数であるため、整数演算(ここでは除算)が使用されます。結果変数をdoubleとして宣言すると、除算後に暗黙の変換が発生します。

もちろん整数除算は、ゼロに向かって丸められた除算の真の結果を返します。0.333...したがって、ここでは0に切り捨てられます。(プロセッサは実際には丸めを行いませんが、そのように考えることもできます)。

また、両方のオペランド(数値)が浮動小数点として指定されている場合注意してください。3.0と1.0、または最初の場合でも、浮動小数点演算が使用されます0.333...


33
+1すると、常に切り捨てられます。int i = .99999999intを0に設定します。より具体的には、整数部分を取り、残りを破棄します。
Byron Whitlock、2011年

37
ゼロより大きい値に対しては「下向き」である「ゼロに向かって」丸めます。(+0.9は0に丸められ、-0.9も0に丸められます。)
エイドリアン・スミス

@バイロン:そうだね。除算は非常に異なる方法で実装されているため、プロセッサが実際に丸めを実行するとは思わないが、そのように考えると便利です。
ノルドリン2011年

15
いいえ、丸めではありません:トランケーション
バジルブルク

3
@BasilBourque Java用語では、丸めDOWNはゼロに向かっています。丸めFLOORは負の無限大に向かっています。
Andreas

23

1/3 両側が整数であるため、整数除算を使用します。

floatまたはになるには、少なくとも1つ必要doubleです。

質問のようにソースコードに値を入力する場合は、次のようにできます1.0/3。これ1.0はダブルです。

他の場所から値を取得する場合は(double)、をにint変換するために使用できますdouble

int x = ...;
int y = ...;
double value = ((double) x) / y;

10

明示的にそれを double

double g = 1.0/3.0

これは、Javaが整数除算演算を使用するため1、および3整数定数として入力したために発生します。


2

あなたは使うべきです

double g=1.0/3;

または

double g=1/3.0;

整数除算は整数を返します。


2

整数除算を行っているからです。

@Noldorinが言うように、両方の演算子が整数の場合、整数除算が使用されます。

結果0.33333333は整数として表すことができないため、整数部分(0)のみが結果に割り当てられます。

演算子のいずれかがdouble/のfloat場合、浮動小数点演算が行われます。しかし、これを行うと同じ問題が発生します。

int n = 1.0 / 3.0;

1

1と3を整数として扱うため、結果は0に切り捨てられ、整数になります。

探している結果を得るには、数値が次のように倍であることを明示的にjavaに伝えます。

double g = 1.0/3.0;

1

1をフロートにし、フロート分割が使用されます

public static void main(String d[]){
    double g=1f/3;
    System.out.printf("%.2f",g);
}

1

JAVAでの変換は非常に簡単ですが、ある程度の理解が必要です。整数演算のJLSで説明するように:

シフト演算子以外の整数演算子に少なくとも1つのlong型のオペランドがある場合、演算は64ビット精度を使用して実行され、数値演算子の結果はlong型になります。他のオペランドがlongでない場合、最初に拡張され(§5.1.5)、数値の昇格(§5.6)によってlongと入力されます。

そして、例は常に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のを追加してもそれほど簡単ではないことを示す小さな例:

short s = 1;
s = s + s; <- Compiling error

//possible loss of precision
//  required: short
//  found:    int

これには、精度を失う可能性のある鋳造が必要になります。

同じことが浮動小数点演算子にも当てはまります

数値演算子の少なくとも1つのオペランドがdouble型の場合、演算は64ビット浮動小数点演算を使用して実行され、数値演算子の結果はdouble型の値になります。他のオペランドがdoubleでない場合は、最初に拡張され(§5.1.5)、数値の昇格によるdouble型(§5.6)になります。

したがって、プロモーションはフロートからダブルに行われます。

そして、整数値と浮動小数点値の両方が混在すると、前述のように浮動小数点値になります

2項演算子のオペランドの少なくとも1つが浮動小数点型である場合、もう一方が整数であっても、演算は浮動小数点演算です。

これは、二項演算子には当てはまりますが、「代入演算子」には当てはまりません。 +=

簡単な作業例でこれを証明するには十分です

int i = 1;
i += 1.5f;

ここで行われる暗黙のキャストがあるため、これは次のように実行されます

i = (int) i + 1.5f
i = (int) 2.5f
i = 2

1

1と3は整数定数なので、Javaは整数除算を実行し、結果は0に1.0なり3.0ます。二重定数を記述したい場合は、とを記述する必要があります。


1

最も簡単な解決策は、これを行うことです

double g = ((double) 1 / 3);

これは、1.0 / 3.0を入力しなかったため、Javaが整数の除算であると想定していたため、手動でデータ型をdoubleに変換でき、変換を狭めることを意味する場合でも実行されます。これは、いわゆるキャスト演算子です。


1

これは私がしました。

double g = 1.0/3.0;
System.out.printf("%gf", g);

二重計算を行う場合は.0を使用してください。使用しない場合、Javaは整数を使用していると想定します。計算でdouble値がいくらか使用されている場合、出力はdouble値になります。すべてが整数の場合、出力は整数になります。


0

(1/3)は整数の除算を意味します。そのため、この除算から小数値を取得できません。この問題を解決するには、以下を使用します。

public static void main(String[] args) {
        double g = 1.0 / 3;
        System.out.printf("%.2f", g);
    }

0
public static void main(String[] args) {
    double g = 1 / 3;
    System.out.printf("%.2f", g);
}

1と3はどちらも整数なので、結果は丸められませんが、切り捨てられます。したがって、分数は無視して整数のみを取得します。

これを回避するには、少なくとも1つまたは3つの数値を小数形式1.0または3.0として使用します。


0

これを試してください:

public static void main(String[] args) {
    double a = 1.0;
    double b = 3.0;
    double g = a / b;
    System.out.printf(""+ g);
}

コードのみの回答を投稿しないでください。コードの機能と、コードが質問の問題を解決する方法(および理由)を説明してください。また、これは既存の賛成投票の回答がある8年前の質問であり、あなたの回答が既存の回答よりも価値があるかどうかを検討してください。
Mark Rotteveel

-1

「double g = 1.0 / 3.0;」を実行します 代わりに。


ちょうど好奇心が強い...この答えの何が問題になっていますか?私が最初に問題に遭遇したとき、私はこのアプローチを使用しました。このソリューションの何が問題であるかについての説明をいただければ幸いです。前もって感謝します。
ポートセントジョー氏

@ Mr.PortStJoeそれは質問をしている人に詳細を提供しません。最高評価の回答を見ると、なぜそれが起こっているのかが説明されていることがわかります。答えは技術的に正しいかもしれませんが、その有用性は制限されていると見なされる場合があります。
Andrew T Finnell

-1

他の多くは本当の問題を指摘することに失敗しました:

整数のみに対する演算は、演算の結果を整数にキャストします。

これは、整数として表示される可能性のある浮動小数点の結果が切り捨てられることを意味します(小数部を切り捨てます)。

何をしているキャストと尋ねる(型キャスト/型変換)?

言語の実装によって異なりますが、ウィキペディアにはかなり包括的な見解があり、強制への回答も含まれています。これは、質問への回答において極めて重要な情報です。

http://en.wikipedia.org/wiki/Type_conversion


この答えには欠陥があります。1/2ターゲット言語(java)ではなく、のようなすべての整数デビジョンに関与する型キャストまたは型変換はありません。整数除算を呼び出すだけで、結果は整数になります。型キャストは、割り当て中にからintへのアップコンバージョンが原因ですdouble
ヨーヨー

@YoYo 0.5は整数だって言ってるの?私はそうは思いません、相棒。
ソバ

1
この相棒はについて何も言わなかった0.5。単に、Javaでは1/2、整数除算であり、ゼロの整数になります。doubleにゼロを割り当てることができますが、doubleであってもゼロのまま0.0です。
YoYo 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.