Java 整数除法:为什么1/3==0的结果?
我在写这段代码:Java 整数除法:为什么1/3==0的结果?,java,integer-division,Java,Integer Division,我在写这段代码: public static void main(String[] args) { double g = 1 / 3; System.out.printf("%.2f", g); } 结果是0。这是为什么?我该如何解决这个问题?将其显式转换为双精度 double g = 1.0/3.0 这是因为Java对1和3使用整数除法运算,因为您将它们作为整数常量输入。两个操作数(1和3)都是整数,因此使用整数算术(此处为除法)。将结果变量声明为double只会导致在除法
public static void main(String[] args) {
double g = 1 / 3;
System.out.printf("%.2f", g);
}
结果是0。这是为什么?我该如何解决这个问题?将其显式转换为
双精度
double g = 1.0/3.0
这是因为Java对1
和3
使用整数除法运算,因为您将它们作为整数常量输入。两个操作数(1和3)都是整数,因此使用整数算术(此处为除法)。将结果变量声明为double只会导致在除法后发生隐式转换
整数除法当然返回除法的真实结果,取整为零。因此,0.333…
的结果在这里四舍五入为0。(请注意,处理器实际上并不进行任何舍入,但您仍然可以这样想。)
另外,请注意,如果两个操作数(数字)都以浮点形式给出;3.0和1.0,甚至只是第一个,然后使用浮点运算,给出0.333…
1和3是整数contant,因此Java进行整数除法,结果是0。如果你想写双常量,你必须写1.0
和3.0
改为“double g=1.0/3.0;”。因为你在做整数除法
正如@Noldorin所说,如果两个运算符都是整数,则使用整数除法
结果0.33333333不能表示为整数,因此只为结果指定整数部分(0)
如果任何运算符是双精度
/浮点
,则将进行浮点运算。但如果你这样做,你也会遇到同样的问题:
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);
}
1/3
使用整数除法,因为两边都是整数
您至少需要其中一个为浮点
或双精度
int x = ...;
int y = ...;
double value = ((double) x) / y;
如果您像您的问题一样在源代码中输入值,您可以执行1.0/3
;1.0
是双精度的
如果您从其他地方获得值,可以使用(double)
将int
转换为double
int x = ...;
int y = ...;
double value = ((double) x) / y;
你应该使用
double g=1.0/3;
或
整数除法返回整数。许多其他方法都没有指出真正的问题: 仅对整数执行的操作将运算结果强制转换为整数 这必然意味着可以显示为整数的浮点结果将被截断(去掉小数部分) 你问什么是铸造(类型铸造/类型转换) 它在语言的实现上有所不同,但维基百科有一个相当全面的观点,它也谈到了胁迫,这是回答你问题的关键信息
JAVA中的转换非常简单,但需要一些理解。如JLS中所述: 如果除移位运算符以外的整数运算符至少有一个long类型的操作数,则使用64位精度执行该操作,并且数字运算符的结果为long类型。如果另一个操作数不长,则首先通过数字提升(§5.6)将其加宽(§5.1.5)以键入long 举例永远是翻译JLS的最佳方式;) 否则,该操作将使用32位精度执行,数值运算符的结果为int类型。如果任一操作数不是int,则首先通过数值提升将其加宽为int类型 使用Eclipse的一个小示例表明,即使添加两个
short
s也不会那么容易:
short s = 1;
s = s + s; <- Compiling error
//possible loss of precision
// required: short
// found: int
原因是这里有一个隐式的强制转换,它将像
i = (int) i + 1.5f
i = (int) 2.5f
i = 2
(1/3)表示整数除法,这就是为什么不能从这个除法中得到十进制值。要解决此问题,请使用:
public static void main(String[] args) {
double g = 1.0 / 3;
System.out.printf("%.2f", g);
}
因为1和3都是整数,所以结果不是四舍五入的,而是被截断的。所以你忽略分数,只取整数
要避免这种情况,请至少将数字1或3中的一个作为十进制形式1.0和/或3.0。最简单的解决方案就是这样做
double g = (double) 1 / 3;
因为您没有输入1.0/3.0,所以它允许您手动将其转换为数据类型double,因为Java假定它是整数除法,即使这意味着缩小转换范围,它也会这样做。这就是所谓的cast操作符。
在这里,我们只强制转换一个操作数,这足以避免整数除法(向零舍入)尝试一下:
public static void main(String[] args) {
double a = 1.0;
double b = 3.0;
double g = a / b;
System.out.printf(""+ g);
}
是我干的
double g = 1.0/3.0;
System.out.printf("%gf", g);
在进行双重计算时使用.0,否则Java将假定您使用的是整数。如果计算使用任意数量的双倍值,则输出将是双倍值。如果这些都是整数,那么输出将是整数
结果是0。为什么会这样,我该如何解决这个问题
TL;DR
您可以通过执行以下操作来解决此问题:
double g = 1.0/3.0;
或
或
或
当您使用变量时,最后一个选项是必需的,例如inta=1,b=3;双g=(双)a/b代码>
更完整的答案
双g=1/3
这将导致0
,因为
- 首先是除数<除数李>
- 这两个变量的类型都是
int
,因此导致int
(),这自然不能表示浮点值,例如0.333333..
- “整数除法向0舍入。”
为什么double g=1.0/3.0代码>和双g=((双)1)/3代码>工作
从中可以看出:
一个转换上下文是数值运算符的操作数,例如+
或*。这种操作数的转换过程称为数值转换
晋升在二进制文件的情况下,升级是特别的
double g = (double) 1 / 3;
public static void main(String[] args) {
double a = 1.0;
double b = 3.0;
double g = a / b;
System.out.printf(""+ g);
}
double g = 1.0/3.0;
System.out.printf("%gf", g);
double g = 1.0/3.0;
double g = 1.0/3;
double g = 1/3.0;
double g = (double) 1 / 3;