整数除法:为什么1/3==0的结果是0?

发布于 2024-10-11 22:03:14 字数 172 浏览 3 评论 0原文

我正在写这段代码:

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

结果是0。这是为什么,我该如何解决这个问题?

I was writing this code:

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

The result is 0. Why is this, and how do I solve this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

淡莣 2024-10-18 22:03:14

两个操作数(1 和 3)都是整数,因此使用整数运算(此处为除法)。将结果变量声明为 double 只会导致除法后发生隐式转换。

整数除法当然返回除法的真实结果,四舍五入为零。因此,0.333... 的结果在此向下舍入为 0。 (请注意,处理器实际上并不进行任何舍入,但您仍然可以这样想。)

此外,请注意,如果两个操作数(数字)都以浮点数形式给出; 3.0 和 1.0,甚至只是第一个,然后使用浮点运算,得到 0.333...

The two operands (1 and 3) are integers, therefore integer arithmetic (division here) is used. Declaring the result variable as double just causes an implicit conversion to occur after division.

Integer division of course returns the true result of division rounded towards zero. The result of 0.333... is thus rounded down to 0 here. (Note that the processor doesn't actually do any rounding, but you can think of it that way still.)

Also, note that if both operands (numbers) are given as floats; 3.0 and 1.0, or even just the first, then floating-point arithmetic is used, giving you 0.333....

注定孤独终老 2024-10-18 22:03:14

1/3 使用整数除法,因为两边都是整数。

您至少需要其中一个为 floatdouble

如果您像您的问题一样在源代码中输入值,则可以执行 1.0/31.0 是双精度值。

如果您从其他地方获取值,则可以使用 (double)int 转换为 double

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

1/3 uses integer division as both sides are integers.

You need at least one of them to be float or double.

If you are entering the values in the source code like your question, you can do 1.0/3 ; the 1.0 is a double.

If you get the values from elsewhere you can use (double) to turn the int into a double.

int x = ...;
int y = ...;
double value = ((double) x) / y;
妖妓 2024-10-18 22:03:14

显式地将其转换为 double

double g = 1.0/3.0

发生这种情况是因为 Java 对 13 使用整数除法运算,因为您将它们作为整数常量输入。

Explicitly cast it as a double

double g = 1.0/3.0

This happens because Java uses the integer division operation for 1 and 3 since you entered them as integer constants.

落叶缤纷 2024-10-18 22:03:14

因为你正在进行整数除法。

正如@Noldorin 所说,如果两个运算符都是整数,则使用整数除法。

结果 0.33333333 无法表示为整数,因此仅将整数部分 (0) 分配给结果。

如果任何运算符是双精度/浮点型,则将进行浮点运算。但如果你这样做,你会遇到同样的问题:

int n = 1.0 / 3.0;

Because you are doing integer division.

As @Noldorin says, if both operators are integers, then integer division is used.

The result 0.33333333 can't be represented as an integer, therefore only the integer part (0) is assigned to the result.

If any of the operators is a double / float, then floating point arithmetic will take place. But you'll have the same problem if you do that:

int n = 1.0 / 3.0;
遗失的美好 2024-10-18 22:03:14

最简单的解决方案就是这样做

double g = (double) 1 / 3;

,因为您没有输入 1.0 / 3.0,所以它的作用是让您手动将其转换为数据类型 double,因为 Java 假定它是整数除法,即使这意味着缩小,它也会这样做转换。这就是所谓的强制转换运算符。
这里我们只转换一个操作数,这足以避免整数除法(向零舍入)

The easiest solution is to just do this

double g = (double) 1 / 3;

What this does, since you didn't enter 1.0 / 3.0, is let you manually convert it to data type double since Java assumed it was Integer division, and it would do it even if it meant narrowing the conversion. This is what is called a cast operator.
Here we cast only one operand, and this is enough to avoid integer division (rounding towards zero)

幽梦紫曦~ 2024-10-18 22:03:14

结果是0。这是为什么,如何解决这个问题?

TL;DR

您可以通过执行以下操作来解决此问题:

double g = 1.0/3.0; 

or or

double g = 1.0/3; 

or

double g = 1/3.0; 

or

double g = (double) 1 / 3;

当您使用变量时,需要使用最后一个选项,例如 int a = 1, b = 3;双 g = (双) a / b;

更完整的答案

双 g = 1 / 3;

这导致 0 因为

  • 首先被除数 0除数;
  • 两个变量都是 int 类型,因此导致 int (5.6.2. JLS) 自然无法表示 0.333333.. 等浮点值。
  • “整数除法向 0 舍入。” 15.17.2 JLS

为什么 double g = 1.0/3.0;double g = ((double) 1) / 3; 有效?

来自第 5 章. 转化和促销一可以阅读:

一个转换上下文是数字运算符的操作数,例如 +
或者 *。此类操作数的转换过程称为数值
晋升。促销的特殊之处在于,在二进制的情况下
运算符,为一个操作数选择的转换可能部分取决于
另一个操作数表达式的类型。

5.6.2。二进制数字促销

当运算符将二进制数字提升应用于一对
操作数,每个操作数必须表示一个可转换为
数字类型,以下规则按顺序适用:

如果任何操作数是引用类型,则对其进行拆箱
转换(§5.1.8)。

加宽基元转换(第 5.1.2 节)适用于转换或
两个操作数均由以下规则指定:

如果其中一个操作数为 double 类型,则另一个操作数将转换为 double。

否则,如果其中一个操作数为 float 类型,则另一个将被转换
漂浮。

否则,如果其中一个操作数为 long 类型,则另一个将被转换
太长了。

否则,两个操作数都将转换为 int 类型。

The result is 0. Why is this, and how do I solve this problem?

TL;DR

You can solve it by doing:

double g = 1.0/3.0; 

or

double g = 1.0/3; 

or

double g = 1/3.0; 

or

double g = (double) 1 / 3;

The last of these options is required when you are using variables e.g. int a = 1, b = 3; double g = (double) a / b;.

A more completed answer

double g = 1 / 3;

This result in 0 because

  • first the dividend < divisor;
  • both variables are of type int therefore resulting in int (5.6.2. JLS) which naturally cannot represent the a floating point value such as 0.333333...
  • "Integer division rounds toward 0." 15.17.2 JLS

Why double g = 1.0/3.0; and double g = ((double) 1) / 3; work?

From Chapter 5. Conversions and Promotions one can read:

One conversion context is the operand of a numeric operator such as +
or *. The conversion process for such operands is called numeric
promotion. Promotion is special in that, in the case of binary
operators, the conversion chosen for one operand may depend in part on
the type of the other operand expression.

and 5.6.2. Binary Numeric Promotion

When an operator applies binary numeric promotion to a pair of
operands, each of which must denote a value that is convertible to a
numeric type, the following rules apply, in order:

If any operand is of a reference type, it is subjected to unboxing
conversion (§5.1.8).

Widening primitive conversion (§5.1.2) is applied to convert either or
both operands as specified by the following rules:

If either operand is of type double, the other is converted to double.

Otherwise, if either operand is of type float, the other is converted
to float.

Otherwise, if either operand is of type long, the other is converted
to long.

Otherwise, both operands are converted to type int.

枯叶蝶 2024-10-18 22:03:14

您应该使用

double g=1.0/3;

double g=1/3.0;

整数除法返回整数。

you should use

double g=1.0/3;

or

double g=1/3.0;

Integer division returns integer.

金兰素衣 2024-10-18 22:03:14

JAVA中的转换非常简单,但需要一些理解。正如 JLS 中对 的解释整数运算

如果除移位运算符之外的整数运算符至少有一个 long 类型的操作数,则使用 64 位精度进行运算,并且数值运算符的结果为 long 类型。如果另一个操作数不长,则首先将其加宽(第 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 的一个小示例表明,即使添加两个 short 也不会那么容易:

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

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

这将需要进行可能会损失精度的转换。

也是如此浮点运算符

如果数值运算符的至少一个操作数是 double 类型,则该运算使用 64 位浮点算术执行,并且数值运算符的结果是 double 类型的值。如果另一个操作数不是双精度数,则首先通过数字提升将其扩展(第 5.1.5 节)以键入双精度型(第 5.6 节)。

所以促销是在浮动上完成的。

如上所述,整数和浮点值的混合会产生浮点值

如果二元运算符的至少一个操作数是浮点类型,则该运算是浮点运算,即使另一个是整数也是如此。

这对于二元运算符是正确的,但对于像 += 这样的“赋值运算符”则不然。

一个简单的工作示例足以证明这一点。

int i = 1;
i += 1.5f;

原因是这里完成了隐式转换,这将像这样执行

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

The conversion in JAVA is quite simple but need some understanding. As explain in the JLS for integer operations:

If an integer operator other than a shift operator has at least one operand of type long, then the operation is carried out using 64-bit precision, and the result of the numerical operator is of type long. If the other operand is not long, it is first widened (§5.1.5) to type long by numeric promotion (§5.6).

And an example is always the best way to translate the JLS ;)

int + long -> long
int(1) + long(2) + int(3) -> long(1+2) + long(3)

Otherwise, the operation is carried out using 32-bit precision, and the result of the numerical operator is of type int. If either operand is not an int, it is first widened to type int by numeric promotion.

short + int -> int + int -> int

A small example using Eclipse to show that even an addition of two shorts will not be that easy :

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

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

This will required a casting with a possible loss of precision.

The same is true for the floating point operators

If at least one of the operands to a numerical operator is of type double, then the operation is carried out using 64-bit floating-point arithmetic, and the result of the numerical operator is a value of type double. If the other operand is not a double, it is first widened (§5.1.5) to type double by numeric promotion (§5.6).

So the promotion is done on the float into double.

And the mix of both integer and floating value result in floating values as said

If at least one of the operands to a binary operator is of floating-point type, then the operation is a floating-point operation, even if the other is integral.

This is true for binary operators but not for "Assignment Operators" like +=

A simple working example is enough to prove this

int i = 1;
i += 1.5f;

The reason is that there is an implicit cast done here, this will be execute like

i = (int) i + 1.5f
i = (int) 2.5f
i = 2
疾风者 2024-10-18 22:03:14

我这样做了。

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

在进行双重计算时使用 .0,否则 Java 会假设您使用的是整数。如果计算使用任意数量的双精度值,则输出将是双精度值。如果都是整数,那么输出将是一个整数。

I did this.

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

Use .0 while doing double calculations or else Java will assume you are using Integers. If a Calculation uses any amount of double values, then the output will be a double value. If the are all Integers, then the output will be an Integer.

耶耶耶 2024-10-18 22:03:14

将 1 设置为浮点型并使用浮点除法

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

Make the 1 a float and float division will be used

public static void main(String d[]){
    double g=1f/3;
    System.out.printf("%.2f",g);
}
请别遗忘我 2024-10-18 22:03:14

1 和 3 是整数常量,因此 Java 进行整数除法,结果为 0。如果要编写双精度常量,则必须编写 1.03.0

1 and 3 are integer contants and so Java does an integer division which's result is 0. If you want to write double constants you have to write 1.0 and 3.0.

雨轻弹 2024-10-18 22:03:14

因为它将 1 和 3 视为整数,因此将结果向下舍入为 0,使其成为整数。

要获得您正在寻找的结果,请显式告诉 java 这些数字是双精度数,如下所示:

double g = 1.0/3.0;

Because it treats 1 and 3 as integers, therefore rounding the result down to 0, so that it is an integer.

To get the result you are looking for, explicitly tell java that the numbers are doubles like so:

double g = 1.0/3.0;
酷到爆炸 2024-10-18 22:03:14

(1/3) 表示整数除法,这就是为什么您不能从此除法中获得小数值。要解决此问题,请使用:

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

(1/3) means Integer division, thats why you can not get decimal value from this division. To solve this problem use:

public static void main(String[] args) {
        double g = 1.0 / 3;
        System.out.printf("%.2f", g);
    }
超可爱的懒熊 2024-10-18 22:03:14
public static void main(String[] args) {
    double g = 1 / 3;
    System.out.printf("%.2f", g);
}

由于 1 和 3 都是整数,因此结果不会四舍五入,而是会被截断。所以你忽略分数而只取整数。

为了避免这种情况,至少将数字 1 或 3 之一作为十进制形式 1.0 和/或 3.0。

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

Since both 1 and 3 are ints the result not rounded but it's truncated. So you ignore fractions and take only wholes.

To avoid this have at least one of your numbers 1 or 3 as a decimal form 1.0 and/or 3.0.

物价感观 2024-10-18 22:03:14

我注意到许多回复中都没有提到这一点,但您也可以执行 1.0 * 1 / 3 来获得浮点除法。当您的变量不能仅在其后添加 .0 时,这会更有用,例如

import java.io.*;

public class Main {
    public static void main(String[] args) {
        int x = 10;
        int y = 15;
        System.out.println(1.0 * x / y);
    }
}

I noticed that this is somehow not mentioned in the many replies, but you can also do 1.0 * 1 / 3 to get floating point division. This is more useful when you have variables that you can't just add .0 after it, e.g.

import java.io.*;

public class Main {
    public static void main(String[] args) {
        int x = 10;
        int y = 15;
        System.out.println(1.0 * x / y);
    }
}
桃扇骨 2024-10-18 22:03:14

执行“双 g=1.0/3.0;”反而。

Do "double g=1.0/3.0;" instead.

谁人与我共长歌 2024-10-18 22:03:14

试试这个:

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

Try this out:

public static void main(String[] args) {
    double a = 1.0;
    double b = 3.0;
    double g = a / b;
    System.out.printf(""+ g);
}
相权↑美人 2024-10-18 22:03:14

我的代码是:

System.out.println("enter weight: ");
int weight = myObj.nextInt();

System.out.println("enter height: ");
int height = myObj.nextInt();

double BMI = weight / (height *height)
System.out.println("BMI is: " + BMI);

如果用户输入体重(分子)= 5,身高(分母)= 7,
BMI 为 0,其中分母 >分子与它返回整数 (5/7 = 0.71 ) 所以结果是 0 (没有小数值)

解决方案:

选项 1:

doubleouble  BMI = (double) weight / ((double)height * (double)height);

选项 2:

double  BMI = (double) weight / (height * height);

My code was:

System.out.println("enter weight: ");
int weight = myObj.nextInt();

System.out.println("enter height: ");
int height = myObj.nextInt();

double BMI = weight / (height *height)
System.out.println("BMI is: " + BMI);

If user enters weight(Numerator) = 5, and height (Denominator) = 7,
BMI is 0 where Denominator > Numerator & it returns interger (5/7 = 0.71 ) so result is 0 ( without decimal values )

Solution :

Option 1:

doubleouble  BMI = (double) weight / ((double)height * (double)height);

Option 2:

double  BMI = (double) weight / (height * height);
断肠人 2024-10-18 22:03:14

许多其他人未能指出真正的问题:

仅对整数进行运算会将运算结果转换为整数。

这必然意味着可以显示为整数的浮点结果将被截断(去掉小数部分)。

您问什么是强制转换(类型转换/类型转换)?

它因语言的实现而异,但维基百科有一个相当全面的视图,并且它也讨论了强制,这是回答您的问题的关键信息。

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

Many others have failed to point out the real issue:

An operation on only integers casts the result of the operation to an integer.

This necessarily means that floating point results, that could be displayed as an integer, will be truncated (lop off the decimal part).

What is casting (typecasting / type conversion) you ask?

It varies on the implementation of the language, but Wikipedia has a fairly comprehensive view, and it does talk about coercion as well, which is a pivotal piece of information in answering your question.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文