内部划分:为什么1/3 == 0的结果?

问题描述 投票:84回答:15

我写的是这段代码:

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

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

java integer-division
15个回答
122
投票

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

整数除法当然会将除法的真实结果舍入为零。因此,0.333...的结果在这里向下舍入为0。 (请注意,处理器实际上并没有进行任何舍入,但你可以这样想。)

另请注意,如果两个操作数(数字)都以浮点数形式给出; 3.0和1.0,或者甚至只是第一个,然后使用浮点算法,给你0.333...


1
投票

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

double g = ((double) 1 / 3);

这样做,因为你没有输入1.0 / 3.0,让你手动将它转换为数据类型double,因为Java假设它是整数除法,即使它意味着缩小转换也会这样做。这就是所谓的演员。


0
投票

(1/3)表示整数除法,这就是为什么你不能从这个除法得到十进制值。要解决这个问题,请使用:

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

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

由于1和3都是整数,因此结果不会舍入,但会被截断。因此,您忽略分数并仅采用整体。

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


-1
投票

做“双g = 1.0 / 3.0;”代替。


-1
投票

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

仅对整数进行的操作会将操作结果强制转换为整数。

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

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

它在语言的实现方面有所不同,但维基百科有一个相当全面的观点,它确实讨论了强制,这是回答你的问题的关键信息。

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


-1
投票

试试这个:

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

20
投票

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

你需要至少其中一个是floatdouble

如果你在问题的源代码中输入值,你可以做1.0/3; 1.0是双倍的。

如果您从其他地方获得值,您可以使用(double)int变成double

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

10
投票

明确地把它作为double

double g = 1.0/3.0

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


2
投票

你应该使用

double g=1.0/3;

要么

double g=1/3.0;

整数除法返回整数。


2
投票

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

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

结果0.33333333不能表示为整数,因此只将整数部分(0)分配给结果。

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

int n = 1.0 / 3.0;

1
投票

因为它将1和3视为整数,因此将结果舍入为0,因此它是一个整数。

要获得您正在寻找的结果,请明确告诉java这些数字是双倍的:

double g = 1.0/3.0;

1
投票

使1成为浮点数并使用浮点除法

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

1
投票

JAVA中的转换非常简单,但需要一些理解。正如QLS对integer operations的解释:

如果移位运算符以外的整数运算符至少有一个long类型的操作数,则使用64位精度执行运算,并且数值运算符的结果为long类型。如果另一个操作数不长,则首先将其扩展(第5.1.5节)以通过数字提升(第5.6节)键入long。

一个例子总是翻译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的一个小例子表明即使添加两个shorts也不会那么容易:

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

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

这将需要可能损失精度的铸件。

floating point operators也是如此

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

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

并且整数和浮点值的混合导致浮动值如上所述

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

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

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

int i = 1;
i += 1.5f;

原因是这里有一个隐式转换,这将执行就像

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

1
投票

1和3是整数内容,因此Java执行整数除法,结果为0.如果要编写双常量,则必须编写1.03.0

© www.soinside.com 2019 - 2024. All rights reserved.