整数除法:为什么1/3==0的结果是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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(19)
两个操作数(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...
.1/3
使用整数除法,因为两边都是整数。您至少需要其中一个为
float
或double
。如果您像您的问题一样在源代码中输入值,则可以执行
1.0/3
;1.0
是双精度值。如果您从其他地方获取值,则可以使用
(double)
将int
转换为double
。1/3
uses integer division as both sides are integers.You need at least one of them to be
float
ordouble
.If you are entering the values in the source code like your question, you can do
1.0/3
; the1.0
is a double.If you get the values from elsewhere you can use
(double)
to turn theint
into adouble
.显式地将其转换为
double
发生这种情况是因为 Java 对
1
和3
使用整数除法运算,因为您将它们作为整数常量输入。Explicitly cast it as a
double
This happens because Java uses the integer division operation for
1
and3
since you entered them as integer constants.因为你正在进行整数除法。
正如@Noldorin 所说,如果两个运算符都是整数,则使用整数除法。
结果 0.33333333 无法表示为整数,因此仅将整数部分 (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:最简单的解决方案就是这样做
,因为您没有输入 1.0 / 3.0,所以它的作用是让您手动将其转换为数据类型 double,因为 Java 假定它是整数除法,即使这意味着缩小,它也会这样做转换。这就是所谓的强制转换运算符。
这里我们只转换一个操作数,这足以避免整数除法(向零舍入)
The easiest solution is to just do this
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)
TL;DR
您可以通过执行以下操作来解决此问题:
or or
or
or
当您使用变量时,需要使用最后一个选项,例如
int a = 1, b = 3;双 g = (双) a / b;
。更完整的答案
这导致
0
因为0
除数;int
类型,因此导致int
(5.6.2. JLS) 自然无法表示0.333333..
等浮点值。为什么
double g = 1.0/3.0;
和double g = ((double) 1) / 3;
有效?来自第 5 章. 转化和促销一可以阅读:
和
5.6.2。二进制数字促销
TL;DR
You can solve it by doing:
or
or
or
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
This result in
0
becauseint
therefore resulting inint
(5.6.2. JLS) which naturally cannot represent the a floating point value such as0.333333..
.Why
double g = 1.0/3.0;
anddouble g = ((double) 1) / 3;
work?From Chapter 5. Conversions and Promotions one can read:
and
5.6.2. Binary Numeric Promotion
您应该使用
或
整数除法返回整数。
you should use
or
Integer division returns integer.
JAVA中的转换非常简单,但需要一些理解。正如 JLS 中对 的解释整数运算:
例子始终是翻译 JLS 的最佳方式;)
使用 Eclipse 的一个小示例表明,即使添加两个
short
也不会那么容易:这将需要进行可能会损失精度的转换。
也是如此浮点运算符
所以促销是在浮动上完成的。
如上所述,整数和浮点值的混合会产生浮点值
这对于二元运算符是正确的,但对于像
+=
这样的“赋值运算符”则不然。一个简单的工作示例足以证明这一点。
原因是这里完成了隐式转换,这将像这样执行
The conversion in JAVA is quite simple but need some understanding. As explain in the JLS for integer operations:
And an example is always the best way to translate the JLS ;)
A small example using Eclipse to show that even an addition of two
short
s will not be that easy :This will required a casting with a possible loss of precision.
The same is true for the floating point operators
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
This is true for binary operators but not for "Assignment Operators" like
+=
A simple working example is enough to prove this
The reason is that there is an implicit cast done here, this will be execute like
我这样做了。
在进行双重计算时使用 .0,否则 Java 会假设您使用的是整数。如果计算使用任意数量的双精度值,则输出将是双精度值。如果都是整数,那么输出将是一个整数。
I did this.
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.
将 1 设置为浮点型并使用浮点除法
Make the 1 a float and float division will be used
1 和 3 是整数常量,因此 Java 进行整数除法,结果为 0。如果要编写双精度常量,则必须编写
1.0
和3.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
and3.0
.因为它将 1 和 3 视为整数,因此将结果向下舍入为 0,使其成为整数。
要获得您正在寻找的结果,请显式告诉 java 这些数字是双精度数,如下所示:
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:
(1/3) 表示整数除法,这就是为什么您不能从此除法中获得小数值。要解决此问题,请使用:
(1/3) means Integer division, thats why you can not get decimal value from this division. To solve this problem use:
由于 1 和 3 都是整数,因此结果不会四舍五入,而是会被截断。所以你忽略分数而只取整数。
为了避免这种情况,至少将数字 1 或 3 之一作为十进制形式 1.0 和/或 3.0。
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.
我注意到许多回复中都没有提到这一点,但您也可以执行
1.0 * 1 / 3
来获得浮点除法。当您的变量不能仅在其后添加 .0 时,这会更有用,例如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.执行“双 g=1.0/3.0;”反而。
Do "double g=1.0/3.0;" instead.
试试这个:
Try this out:
我的代码是:
如果用户输入体重(分子)= 5,身高(分母)= 7,
BMI 为 0,其中分母 >分子与它返回整数 (5/7 = 0.71 ) 所以结果是 0 (没有小数值)
解决方案:
选项 1:
选项 2:
My code was:
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:
Option 2:
许多其他人未能指出真正的问题:
这必然意味着可以显示为整数的浮点结果将被截断(去掉小数部分)。
您问什么是强制转换(类型转换/类型转换)?
它因语言的实现而异,但维基百科有一个相当全面的视图,并且它也讨论了强制,这是回答您的问题的关键信息。
http://en.wikipedia.org/wiki/Type_conversion
Many others have failed to point out the real issue:
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