为什么 Java 的除法被破坏了?

Why is Java's division broken?

我是一位经验丰富的 php 开发人员,刚开始学习 Java。我目前正在学习 Lynda 的一些课程,但我还处于早期阶段。我正在编写示例程序,要求用户输入并进行简单的计算和其他操作。

昨天遇到这种情况:

double result = 1 / 2;

以我穴居人的大脑,我会想 result == 0.5,但不,不是 Java。显然 1 / 2 == 0.0。是的,我知道如果我将其中一个操作数更改为双精度,结果也将是双精度。

这真的让我害怕。我不禁认为这很糟糕。认为整数除法得到整数是非常天真的想法。我认为这种情况甚至很少。

但是,由于 Java 的使用非常广泛并且正在搜索“为什么 java 的划分被破坏了?”没有产生任何结果,我可能错了。

我的问题是:

  1. 为什么除法会这样?
  2. 我还能在哪里找到这种 magic/voodoo/unexpected 行为?

我绝不是这方面的专家,但我认为这是因为如何定义运算符来进行整数运算。 Java 使用整数除法来计算结果,因为它看到两者都是整数。它将两个整数作为此 "division" 方法的输入,重载除法运算符,并执行此整数除法。如果不是这种情况,那么 Java 每次都必须在重载方法中执行强制转换为 double,如果您无论如何都可以先执行强制转换,这实际上是无用的。

Java 是一种强类型语言,因此您应该了解表达式中值的类型。如果不是...

1是一个int(如2),所以1/2是1和2的整数除法,所以结果是0作为 int。然后将结果转换为对应的double值,所以0.0.

整数除法与浮点数除法不同,在数学中(自然数除法与实数除法不同)。

如果你用c++试试,你会发现结果是一样的。 原因是在给变量赋值之前,你应该计算它。您键入的数字(1 和 2)是整数,因此它们的内存分配应该是整数。然后,除法应该根据整数进行。之后它会将其转换为 double,得到 0.0.

Why does division behave like this?

因为语言规范是这样定义的。

Where else can I expect to find such magic/voodoo/unexpected behaviour?

因为您基本上是在调用 "magic/voodoo" 语言规范中完美定义的内容,所以答案是 "everywhere"。

所以问题实际上是为什么 Java 中有这个设计决策。在我看来,int 除法得到 int 是强类型语言的完美设计决策。纯 int 算法经常使用,因此 int 除法会导致 floatdouble,你需要大量舍入,这不是很好。

您像 PHP 开发人员一样思考; PHP 是 dynamically typed 语言。这意味着类型是在 运行 时间推导出来的,因此分数在逻辑上不能产生整数,因此除法运算隐含了 double(或 float)。

Java、C、C++、C# 和许多其他语言都是 strongly typed 语言,所以当一个整数除以一个整数时,你得到一个整数,100/50 给我返回2,就像100/45给我2一样,因为100/45其实是2.2222...,t运行小数点取整数(整数除法)你得到 2.

在强类型语言中,如果你希望结果如你所愿,你需要显式(或隐式),这就是为什么你的除法运算中的一个参数是 double 或 float 会导致浮点除法(返回分数)。

因此在 Java 中,您可以执行以下操作之一来获取小数:

double result = 1.0 / 2;
double result = 1f / 2;
double result = (float)1 / 2;

从一种松散类型的动态语言转变为一种强类型的静态语言可能会令人不快,但没有必要害怕。只需了解您必须特别注意输入以外的验证,您还必须验证类型。

从 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);

这将导致错误,因为您不能分割字符串(它不是数字)。

希望能帮到你。

package demo;

public class ChocolatesPurchased
{
    public static void main(String args[])
    {
        float p = 3;
        float cost = 2.5f;
        p *= cost;
        System.out.println(p);
    }
}