可以为舍入的数字提供与舍入数字不同的答案吗?

时间:2017-12-04 13:21:04

标签: floating-point rounding precision ieee-754 floor

我是否纠正那个楼层(round($ number))不一定等于round($ number)假设" round"返回一个双?

举个例子,假设$ number = 123456.9999999999999999。我猜这个" round"将是一个无操作,因为$ number已经尽可能接近123457。  "地板"然后会产生123456。

这是正确的还是有关于#34; floor"或者" round"这会阻止这个吗?

2 个答案:

答案 0 :(得分:4)

由于IEEE-754浮点表示的工作方式, 1 不可能表示非整数值(例如123456.9999999999999999)和最接近的整数值(例如123457)无法代表。

因此,在一个理智的实现中,round的结果应该始终是一个整数值。实际上,在C的情况下,语言标准要求这样做。 2

因此,在这种理智的语言中,floor(round(x))round(x)始终相同。

<子> 1。 IEEE-754现在非常普遍。从技术上讲,有可能构建一个浮点系统,其中不是为真,但我怀疑这个系统在实践中是否存在。

<子> 2。你的另一个例子PHP有一个sketchy "decimal precision" feature让我怀疑同样的保证适用!实际上,implementation涉及各种疯狂的东西,包括转换为字符串并返回

答案 1 :(得分:0)

  

对于舍入的数字可以给出与舍入数字不同的答案吗?

有时候看角落案例可能会暴露一个反例。

void rtest(double x) {
  double y1 = floor(round(x));
  double y2 = round(x);
  printf("%d %- 14e %- 14e %- 14e\n", y1 != y2, x, y1, y2);
}

int main(void) {
  double x[] = { 0.0, DBL_TRUE_MIN, DBL_MIN, 1.0, 3.14, 3.99, DBL_MAX, 1.0/0.0, 0.0/0.0};
  for (unsigned i=0; i< sizeof x/sizeof x[0]; i++) {
    rtest(x[i]);
    rtest(-x[i]);
  }
}

输出

0  0.000000e+00   0.000000e+00   0.000000e+00 
0 -0.000000e+00  -0.000000e+00  -0.000000e+00 
0  4.940656e-324  0.000000e+00   0.000000e+00 
0 -4.940656e-324 -0.000000e+00  -0.000000e+00 
0  2.225074e-308  0.000000e+00   0.000000e+00 
0 -2.225074e-308 -0.000000e+00  -0.000000e+00 
0  1.000000e+00   1.000000e+00   1.000000e+00 
0 -1.000000e+00  -1.000000e+00  -1.000000e+00 
0  3.140000e+00   3.000000e+00   3.000000e+00 
0 -3.140000e+00  -3.000000e+00  -3.000000e+00 
0  3.990000e+00   4.000000e+00   4.000000e+00 
0 -3.990000e+00  -4.000000e+00  -4.000000e+00 
0  1.797693e+308  1.797693e+308  1.797693e+308
0 -1.797693e+308 -1.797693e+308 -1.797693e+308
0  inf            inf            inf          
0 -inf           -inf           -inf          
1 -nan           -nan           -nan          
1  nan            nan            nan

当处理ieee-754号码时,floor(round(x)) != round(x)为真或(&#34;不一定等于&#34;每个OP的问题)当x为非数字时

否则round()的结果总是整数值或无穷大,而“floor-ing”不会改变该值。

我检查了各种舍入模式并找到了相同的结果。