2017-05-11 68 views
0

假设你有一个双重价值,并希望将其四舍五入到整数...使用Int(round(x))是否安全?

许多轮()函数返回的不是整数双:

  • C# - 圆(双) - >双
  • C++ - 轮(双) - >双
  • Darwin - 轮(双) - >双
  • Swift - double.rounded() - >双
  • Java - 圆(双) - > INT
  • Ruby:float.round() - > INT

鉴于这种 “默认” 的行为(这是因为doubles have a much wider range of possible values是最有可能的),这也许就是为什么你会看到常用以下建议:

Int(round(myDouble)) 

(这里我们假设Int()removes everything after the decimal:4.9 - > 4)

到目前为止好,直到你意识到how complex floatingpoints really are。例如。例如,55实际上可能被存储为54.9999999999999999

正因为如此,它听起来像下面可能会发生:

Int(round(55.4))  // we ask it to round 55.4, expecting 55 
Int(54.9999999999999) // it rounded it to "55.0" 
54      // the Int() function removed all remaining digits 

我们预期55.4四舍五入为55,但它结束了评估,以54

  1. 如果我们使用Int(round(x)),那么类似上述事情会发生吗?
  2. 如果是这样,我们应该用什么来代替Int(round())
  3. 相关:许多语言定义为floor(double) -> doubleInt(floor(double))安全吗?
+0

该舍入值(循环函数的结果)的假设可具有非零分数部分不对应于现实。我不知道这种奇特的浮点模型是否曾经存在过,但如果是这样的话,它肯定会死掉。如果它不在模型中,它也不在库中:不轮回的循环函数是一个错误,而不是一个功能。 –

+0

所以你不想转换为Int去除小数,round()已经为你做了。要转换为Int,因为在代码中的一些功能的进一步不支持多态类型,如果你这样做,你就不得不面对有限的诠释范围 - 这是不安全的部分。如果语言支持无限整数,则整数结果可能已经是整数。 –

回答

1

浮点模型被构建在这些基础上:

  • b
  • 用的数字在该基数的数量有限(p精度)
  • 指数e用于有效数移位浮点,也限制在一定范围内
  • a符号

所以浮点值被制成这样的:(-1)^signBit * significand * b^e

有效位数可以以归一化形式与左浮点(除了零的1个非空位来表示,或最终值接近零的是输精度和逐渐下溢),以及浮点后的p-1数字。

但是通过适当地移位指数(e+1-p),它也可以被认为是具有p数字xxxxxxxxx.0的整数。

对于指数的合理范围,我们可以看到每个达到b^p的整数都可以完全由这种浮点模型表示。随着精度有限,只能在基地b最后一个数字被丢失,所以,如果我们有一个整数太大,无法在有效数字,它必然有一个空的小数部分。因此,没有理由回答除了整数值之外的任何其他内容(具有空白部分)。

只有不安全的一部分,你注意的是,Int范围可能比浮点值的范围要小得多。大浮点从而转换为INT可能导致溢出异常,或与未定义的行为差,无声溢出...

转换为int因此,不需要用于消除分数部分的缘故。它必须用于其他目的(例如喂养只接受Int的程序的另一部分)。