C#和Java:3/2*3.2 = 3.2,为什么?

Che*_*ung 4 c# java

考虑以下C#和Java,

double d = 3 / 2 * 3.2;
Run Code Online (Sandbox Code Playgroud)

Java的

System.out.println(d); // 3.2
Run Code Online (Sandbox Code Playgroud)

C#

Console.WriteLine(d); //3.2
Run Code Online (Sandbox Code Playgroud)

它跳过3/2,

我们知道正确的答案应该是4.8

如果我改变

double d = 3.00 / 2 * 3.2;
Run Code Online (Sandbox Code Playgroud)

我可以得到4.8,

所以我想问一下,如果(3/2*3.2)是非法的,为什么eclipse和vs2008没有错误?以及如何在C#和Java中防止这个问题?

Roe*_*ler 25

3/2是整数除法,结果是1.

1 * 3.2等于3.2,这是你收到的结果.

这是一个定义明确的公式,具有明确定义的预期结果,因此编译器没有错误.使用3.00,这是强制编译器使用浮点数学的最直接的方法.

来自Thorbjørn的答案:另一个选择是标准化所有浮点计算,从1.0*你的例子开始,它将是1.0*3/2*3.2.


coo*_*ird 11

3 / 2被认为是整数除法,因此结果出来了1.

然后,在1和之间进行相乘3.2并使整数1提升到浮点1,从而产生3.2.

这个想法是:

// Both "3" and "2" are integers, so integer division is performed.
3 / 2 == 1

// "3.2" is a floating point value, while "1" is an integer, so "1" is
// promoted to an floating point value.
1 * 3.2  -->  1.0 * 3.2 == 3.2
Run Code Online (Sandbox Code Playgroud)

键入时2.0,小数点告诉Java将文字视为浮点值(在本例中为a double),因此计算结果4.8与预期一致.如果没有小数点,则该值为整数字面值.

这不是错误,而是如何处理文字的问题.

以下链接提供了更多信息:


Mar*_*rth 7

这是完全合法的,但是3/2是一个整数除法(这就像做除法然后选择最接近0的数字(在某些语言中 - 无穷大)).您需要为编译器提供某种"提示"想要的分区.

你可以通过写作来避免它

3.0 / 2 * 3.2          or      3 / 2.0 * 3.2
3.0 / 2.0 * 3.2
3d / 2d * 3.2 (C#)
(double)3 / 2 * 3.2
Run Code Online (Sandbox Code Playgroud)


Tho*_*sen 6

如果你想要使用小数而不是整数进行计算,那么要么从中开始

 1.0 * 3 / 2 * 3.2
Run Code Online (Sandbox Code Playgroud)

或者告诉编译器第一个数字是实数/双数:

3d / 2 * 3.2
Run Code Online (Sandbox Code Playgroud)