web-dev-qa-db-ja.com

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

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

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

結果は0です。これはなぜですか。この問題を解決する方法を教えてください。

88
Tofiq

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

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

また、bothオペランド(数値)がfloatとして指定されている場合も注意してください。 3.0と1.0、またはfirstのみを使用した場合、浮動小数点演算が使用され、0.333...が得られます。

125
Noldorin

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

少なくとも1つはfloatまたはdoubleである必要があります。

質問のようにソースコードに値を入力する場合は、1.0/3を実行できます。 1.0はdoubleです。

他の場所から値を取得する場合は、(double)を使用してintdoubleに変換できます。

int x = ...;
int y = ...;
double value = ((double) x) / y;
21
Adrian Smith

doubleとして明示的にキャストします

double g = 1.0/3.0

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

10
Charlie

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

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

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

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

int n = 1.0 / 3.0;
2
Tom

あなたは使うべきです

double g=1.0/3;

または

double g=1/3.0;

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

2
user467871

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

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

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

1
Ramzi El-Jabali

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

1
Reboot

1と3を整数として扱うため、結果を0に切り下げて整数にします。

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

double g = 1.0/3.0;
1
DanielGibbs

1をフロートにし、フロート除算を使用します

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

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

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
AxelH

(1/3)は整数除算を意味します。これが、この除算から小数値を取得できない理由です。この問題を解決するには:

public static void main(String[] args) {
        double g = 1.0 / 3;
        System.out.printf("%.2f", g);
    }
0
Maruf Hossain
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として使用します。

0
Bek