2010-06-01 46 views
38

我正在为一个学校项目创建一个RPN计算器。我对模运算符有问题。由于我们使用双数据类型,所以模数不适用于浮点数。例如,0.5%0.3应该返回0.2,但我得到一个除零的例外。如何使用float/double模数?

该指令说使用fmod()。我到处寻找fmod(),包括javadoc,但我找不到它。我开始认为这是一种我将不得不创造的方法?

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

回答

59

您第一次运行它时可能有错字。

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

Mindprod在Java中有一个good overview of how modulus works(最后看浮点模数)。

+1

但是由于舍入错误,'1.​​0%0.1'返回...'0.09999999999999995'。任何想法如何纠正这(大概与epsilon值?) – Groostav 2015-11-18 00:13:02

+1

舍入误差将始终发生在浮点计算。要么按照给定的值取值,要么将其四舍五入到最接近的必要值。 – Anarchofascist 2016-01-22 05:52:58

+0

'String.format(“%。8f”,1.0%0.1)'返回'0.10000000' – Anarchofascist 2016-01-22 05:58:40

5

我认为普通模运算符会在java中为此工作,但它不难编码。只需用分母除分子,然后取结果的整数部分。用分母乘以,并从分子中减去结果。

x = n/d 
xint = Integer portion of x 
result = n - d * xint 
2

fmod是处理浮点模数的标准C函数;我想你的源代码是说Java处理浮点模数与C的fmod函数相同。在Java中,你可以使用双打%运营商一样对整数:

int x = 5 % 3; // x = 2 
double y = .5 % .3; // y = .2 
37

不像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

+2

最后一个要点是文字墙。更清楚地说,举个例子: '0.5%0.3 = 0.2'和'(-0.5)%0.3 = -0.2' – GameDeveloper 2015-08-01 13:44:40