52

我正在为一个学校项目创建一个 RPN 计算器,但在使用模数运算符时遇到了问题。由于我们使用的是双精度数据类型,因此模数不适用于浮点数。例如,0.5 % 0.3 应该返回 0.2,但我得到了除以零的异常。

说明说要使用fmod(). 我到处寻找fmod(),包括 javadoc,但我找不到它。我开始认为这是我必须创造的一种方法?

编辑:嗯,奇怪。我刚刚再次插入这些数字,它似乎工作正常……但以防万一。在使用浮点类型时,我是否需要注意在 Java 中使用 mod 运算符?我知道这样的事情不能在 C++ 中完成(我认为)。

4

4 回答 4

75

当你第一次运行它时,你可能有一个错字。

评估0.5 % 0.3按预期返回“0.2”(双倍)。

Mindprod很好地概述了模数在 Java 中的工作原理。

于 2010-06-01T02:59:41.540 回答
46

与 C 不同,Java 允许将 % 用于整数和浮点,并且(与 C89 和 C++ 不同)它对所有输入(包括负数)都有很好的定义:

JLS §15.17.3

浮点余数运算的结果由 IEEE 算术规则确定:

  • 如果任一操作数为 NaN,则结果为 NaN。
  • 如果结果不是 NaN,则结果的符号等于被除数的符号。
  • 如果被除数为无穷大,或除数为零,或两者兼而有之,则结果为 NaN。
  • 如果被除数是有限的且除数是无穷大,则结果等于被除数。
  • 如果被除数为零且除数是有限的,则结果等于被除数。
  • 在其余情况下,既不涉及无穷大,也不涉及零,也不涉及 NaN,被除数 n 除以除数 d 的浮点余数 r 由数学关系 r=n-(d·q ) 其中 q 是一个整数,仅当 n/d 为负时为负,仅当 n/d 为正时为正,并且其大小尽可能大而不超过 n 和 d 的真实数学商的大小。

因此,对于您的示例, 0.5/0.3 = 1.6... 。q 与 0.5(被除数)同号(正),大小为 1(最大大小不超过 1.6... 大小的整数),r = 0.5 - (0.3 * 1) = 0.2

于 2010-06-01T03:03:30.877 回答
7

我认为常规模数运算符在 Java 中可以解决这个问题,但编写代码并不难。只需将分子除以分母,然后取结果的整数部分。将其乘以分母,然后从分子中减去结果。

x = n/d
xint = Integer portion of x
result = n - d*xint
于 2010-06-01T02:59:08.297 回答
3

fmod是处理浮点模数的标准 C 函数;我想你的消息来源是说 Java 处理浮点模数与 C 的fmod函数相同。在 Java 中,您可以%像在整数上一样使用双精度运算符:

int x = 5 % 3; // x = 2
double y = .5 % .3; // y = .2
于 2010-06-01T02:59:54.300 回答