我正在编写这段代码:
public static void main(String[] args) {
double g = 1 / 3;
System.out.printf("%.2f", g);
}
结果为0。为什么会这样,我该如何解决这个问题?我正在编写这段代码:
public static void main(String[] args) {
double g = 1 / 3;
System.out.printf("%.2f", g);
}
结果为0。为什么会这样,我该如何解决这个问题?这两个操作数(1和3)是整数,因此使用整数算术(在这里是除法)。将结果变量声明为double只会导致隐式转换发生在除法后。
当然,整数除法返回向零舍入的除法真正结果。因此,在这里,0.333...
的结果被向下舍入为0。(注意,处理器实际上并没有进行任何舍入,但您仍可以这样考虑。)
此外,请注意,如果两个操作数(数字)都以浮点数给出;3.0和1.0,或者仅第一个,则使用浮点运算,从而给出0.333...
。
int i = .99999999
将 int 设为 0。更具体地说,它取整数部分并丢弃剩余部分。 - Byron Whitlockrounding DOWN
是指向零舍入。FLOOR
舍入是指向负无穷大舍入。 - Andreas1/3
使用整数除法,因为两边都是整数。
你需要至少一个是 float
或 double
。
如果你在代码中输入值,就像你的问题一样,你可以这样做:1.0/3
; 这里的 1.0
是一个 double。
如果你从其他地方获取值,你可以使用 (double)
将 int
转换成 double
。
int x = ...;
int y = ...;
double value = ((double) x) / y;
将其明确转换为 double
double g = 1.0/3.0
1
和3
进行计算,因为它们被输入为整数常量。结果为0。为什么会这样,如何解决这个问题?
简短回答:
您可以通过以下方式解决:
double g = 1.0/3.0;
或者
double g = 1.0/3;
或者
double g = 1/3.0;
或者
double g = (double) 1 / 3;
int a = 1, b = 3; double g = (double) a / b;
。这将导致结果为double g = 1 / 3;
0
,因为:
int
类型,因此结果是int
类型(参见5.6.2. JLS),自然不能表示浮点值,如0.333333..
。double g = 1.0/3.0;
和double g = ((double) 1) / 3;
有效?和一个转换上下文是数值运算符的操作数,如+或*。这种操作数的转换过程称为数值提升。提升是特殊的,因为在二元运算符的情况下,选择一个操作数的转换可能部分取决于其他操作数表达式的类型。
5.6.2. 二进制数值提升
当运算符将一对操作数应用于二进制数值提升时,每个操作数都必须表示可转换为数值类型的值,则按照以下规则依次应用:
如果任何操作数是引用类型,则它将经受拆箱转换(§5.1.8)。
扩展原始转换(§5.1.2)被用来将一个或两个操作数转换为指定的类型,具体取决于以下规则:
如果任一操作数为double类型,则另一个操作数将被转换为double类型。
否则,如果任一操作数为float类型,则另一个操作数将被转换为float类型。
否则,如果任一操作数为long类型,则另一个操作数将被转换为long类型。
否则,两个操作数都将被转换为int类型。
double g = (double) 1 / 3;
由于您没有输入 1.0 / 3.0,这个操作会让您手动将它转换为 double 数据类型,因为 Java 默认认为这是整数除法,即使这意味着缩小转换。这就是所谓的强制类型转换运算符。
在这里我们只对一个操作数进行了类型转换,这已足够避免整数除法(朝向零舍入)
因为你正在进行整数除法。
正如@Noldorin所说,如果两个运算符都是整数,则使用整数除法。
结果0.33333333无法表示为整数,因此只有整数部分(0)被赋给结果。
如果任何一个运算符是double
/float
,那么将进行浮点运算。但是如果你这样做,你会遇到同样的问题:
int n = 1.0 / 3.0;
你应该使用:
double g=1.0/3;
或者
double g=1/3.0;
整数除法返回整数。
我做了这件事。
double g = 1.0/3.0;
System.out.printf("%gf", g);
而例子总是最好的翻译方式 ;)如果除移位运算符以外的整数运算符至少有一个操作数是long类型,则使用64位精度执行操作,并且数字运算符的结果为long类型。如果另一个操作数不是long型,则通过数值提升(§5.6)首先将其扩展(§5.1.5)为long型。
int + long -> long
int(1) + long(2) + int(3) -> long(1+2) + long(3)
short + int -> int + int -> int
short
相加也不会那么容易:short s = 1;
s = s + s; <- Compiling error
//possible loss of precision
// required: short
// found: int
这将需要进行一次转换,可能会导致精度损失。
浮点运算符也是如此
如果数值运算符的至少一个操作数是double类型,则使用64位浮点算术执行该操作,并且数值运算符的结果是double类型的值。如果另一个操作数不是double,则通过数值提升(§5.6)将其首先扩展(§5.1.5)为double类型。
因此,在float中进行了提升到double的操作。
当整数和浮点值混合时,结果为浮点值
如果二元运算符的至少一个操作数是浮点类型,则该操作是浮点操作,即使另一个操作数是整数也是如此。
这对于二元运算符是正确的,但不适用于“赋值运算符”例如+=
一个简单的工作示例就足以证明这一点
int i = 1;
i += 1.5f;
i = (int) i + 1.5f
i = (int) 2.5f
i = 2
将1转换为浮点数,即可使用浮点数除法
public static void main(String d[]){
double g=1f/3;
System.out.printf("%.2f",g);
}