为什么Java的部门被打破了?
我是一位经验丰富的php开发人员,刚刚开始学习Java。 我现在正在学习一些Lynda课程,而且我还处于早期阶段。 我正在编写示例程序,要求用户输入并进行简单的计算和处理。
昨天我遇到了这种情况:
double result = 1 / 2;
我的穴居人大脑我认为result == 0.5
,但不是,不是用Java。 显然1 / 2 == 0.0
。 是的,我知道如果我将其中一个操作数更改为double,结果也将是double。
实际上这让我害怕。 我不禁想到这是非常破碎的。 认为整数除法产生整数是非常天真的。 我认为这种情况很少发生。
但是,由于Java被广泛使用并且正在搜索“为什么java的部门被破坏?” 不会产生任何结果,我可能错了。
我的问题是:
- 为什么除法表现得像这样?
- 我还能在哪里找到这样的魔法/伏都教/意外行为?
您正在考虑像PHP开发人员; PHP是动态类型语言。 这意味着类型是在运行时推导出来的,因此分数不能在逻辑上产生整数,因此从除法运算中隐含了double
(或float
)。
Java,C,C ++,C#和许多其他语言都是强类型语言,所以当一个整数除以一个整数后,你得到一个整数, 100/50
给我回2
,就像100/45
给我2
,因为100/45
实际上是2.2222...
,截断小数以得到一个整数(整数除法),你得到2
。
在强类型语言中,如果希望结果符合预期,则需要显式(或隐式),这就是为什么在除法运算中将一个参数设置为double或float将导致浮点除法的原因(它给出了分数)。
所以在Java中,您可以执行以下操作之一来获取小数:
double result = 1.0 / 2; double result = 1f / 2; double result = (float)1 / 2;
从松散类型的动态语言转变为强类型的静态语言可能会让人感到不安,但是没有必要害怕。 只需要了解除了输入之外你必须特别注意validation,还必须validation类型。
从PHP到Java,你应该知道你不能做这样的事情:
$result = "2.0"; $result = "1.0" / $result; echo $result * 3;
在PHP中,这将产生输出1.5
(因为(1/2)*3 == 1.5
),但在Java中,
String result = "2.0"; result = "1.0" / result; System.out.println(result * 1.5);
这将导致错误,因为您无法分割字符串(它不是数字)。
希望能有所帮助。
Java是一种强类型语言,因此您应该了解表达式中值的类型。 如果不…
1
是int
(为2
),因此1/2
是1和2的整数除法,因此结果为0
作为int
。 然后将结果转换为相应的double值,因此为0.0
。
整数除法与浮点除法不同,如数学(自然数除法不同于实数除法)。
我对此并不专业,但我认为这是因为运算符被定义为执行整数运算。 Java使用整数除法来计算结果,因为它看到两者都是整数。 它将这个“除法”方法作为输入作为两个整数,并且除法运算符被重载,并执行该整数除法。 如果不是这种情况,那么Java每次都必须在重载方法中执行一次转换为double,如果你可以先执行转换,这实际上是无用的。
如果你用c ++试试,你会看到结果是一样的。 原因是在将值赋给变量之前,您应该计算它。 您键入的数字(1和2)是整数,因此它们的内存分配应该是整数。 然后,除法应按整数完成。 之后,它会将其转换为double,这样会得到0.0
。
为什么除法表现得像这样?
因为语言规范以这种方式定义它。
我还能在哪里找到这样的魔法/伏都教/意外行为?
因为你基本上称之为“魔术/伏都教”的东西在语言规范中得到了完美的定义,所以答案是“无处不在”。
所以问题实际上是为什么在Java中有这个设计决策。 从我的观点来看,对于强类型语言来说, int
division导致int
是一个完美的声音设计决策。 纯int
算法经常被使用,因此int
除法会导致float
或double
,你需要进行大量的舍入,这不会很好。