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;