292

对于此代码块:

int num = 5;
int denom = 7;
double d = num / denom;

d值为0.0。它可以通过强制转换强制工作:

double d = ((double) num) / denom;

但是还有其他方法可以得到正确的double结果吗?我不喜欢铸造原语,谁知道会发生什么。

4

11 回答 11

181
double num = 5;

这避免了演员表。但是您会发现演员转换是明确定义的。您不必猜测,只需检查JLS即可。int 到 double 是一个扩大的转换。从§5.1.2 开始

扩大原始转换不会丢失有关数值整体大小的信息。

[...]

将 int 或 long 值转换为 float,或将 long 值转换为 double,可能会导致精度损失——也就是说,结果可能会丢失一些值的最低有效位。在这种情况下,生成的浮点值将是整数值的正确舍入版本,使用 IEEE 754 舍入到最近模式(§4.2.4)

5 可以精确地表示为双精度数。

于 2010-06-29T20:51:14.267 回答
121

铸造原语有什么问题?

如果您出于某种原因不想投射,您可以这样做

double d = num * 1.0 / denom;
于 2010-06-29T20:52:23.267 回答
83

我不喜欢铸造原语,谁知道会发生什么。

为什么你对铸造原语有一种非理性的恐惧?int当您将 an转换为 a时,不会发生任何不好的事情double。如果您只是不确定它是如何工作的,请在Java 语言规范中查找。转换为inttodouble是一种扩大的原始转换

您可以通过转换分母而不是分子来摆脱多余的括号:

double d = num / (double) denom;
于 2010-06-30T07:05:43.167 回答
31

如果你改变一个变量的类型,如果你的公式改变,你必须记住再次潜入双精度,因为如果这个变量不再是计算的一部分,结果就会混乱。我养成了在计算中进行转换的习惯,并在其旁边添加注释。

double d = 5 / (double) 20; //cast to double, to do floating point calculations

请注意,转换结果不会这样做

double d = (double)(5 / 20); //produces 0.0
于 2013-05-23T09:35:49.293 回答
23

类型转换是唯一的方法

可能你不会明确地这样做,但它会发生。

现在,有几种方法可以尝试获得精确的double值(其中numdenomint类型,当然还有强制转换)-

  1. 显式转换:
  • double d = (double) num / denom;
  • double d = ((double) num) / denom;
  • double d = num / (double) denom;
  • double d = (double) num / (double) denom;

但不是double d = (double) (num / denom);

  1. 隐式转换:
  • double d = num * 1.0 / denom;
  • double d = num / 1d / denom;
  • double d = ( num + 0.0 ) / denom;
  • double d = num; d /= denom;

但不是double d = num / denom * 1.0;
和不是double d = 0.0 + ( num / denom );


现在,如果您要问-哪个更好?明确的?还是隐含的?

好吧,让我们不要在这里直接回答。请记住——我们程序员不喜欢源代码中的惊喜或魔法。我们真的很讨厌复活节彩蛋。

此外,额外的操作肯定不会让您的代码更有效率。对?

于 2016-04-07T09:13:10.583 回答
21

将整数之一/两个整数强制转换为浮点数以强制使用浮点数学来完成操作。否则整数数学总是首选。所以:

1. double d = (double)5 / 20;
2. double v = (double)5 / (double) 20;
3. double v = 5 / (double) 20;

请注意,转换结果不会这样做。因为第一次除法是按照优先规则完成的。

double d = (double)(5 / 20); //produces 0.0

我认为您正在考虑的铸造没有任何问题。

于 2015-04-14T04:24:56.350 回答
2

使用类似的东西:

double step = 1d / 5;

(1d 是加倍的演员表)

于 2015-09-14T08:12:26.493 回答
1

最好的方法是

int i = 3;
Double d = i * 1.0;

d is 3.0 now.
于 2017-08-16T15:48:41.953 回答
0

您可能会考虑包装操作。例如:

class Utils
{
    public static double divide(int num, int denom) {
        return ((double) num) / denom;
    }
}

这使您可以查看(仅一次)演员是否完全按照您的意愿行事。这种方法也可以接受测试,以确保它继续做你想做的事。您使用什么技巧来导致除法也无关紧要(您可以在此处使用任何答案),只要它产生正确的结果即可。在任何需要将两个整数相除的地方,您现在都可以调用Utils::divide并相信它会做正确的事情。

于 2016-09-02T16:06:42.763 回答
0

就用这个。

int fxd=1;
double percent= (double)(fxd*40)/100;
于 2017-04-25T08:07:23.373 回答
0

只需添加“D”。

int i = 6;
double d = i / 2D; // This will divide bei double.
System.out.println(d); // This will print a double. = 3D
于 2020-08-11T01:59:33.787 回答