假设您有一个double值,并希望将其舍入为整数...
许多round()函数返回一个double而不是一个整数:
(这很可能是因为doubles have a much wider range of possible values。)
鉴于此"默认"行为,它可能解释了为什么你会经常看到以下建议:
Int(round(myDouble))
(我们假设Int()
removes everything after the decimal:4.9 - > 4。)
到目前为止一直很好,直到你意识到how complex floating points 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
。
Int(round(x))
?Int(round())
?floor(double) -> double
。 Int(floor(double))
安全吗?答案 0 :(得分:2)
浮点模型是在这些基础上构建的:
b
p
精度)e
,也限制在某个范围内所以浮点值是这样的:(-1)^signBit * significand * b^e
有效数可以用标准化形式x.xxxxxxxx
表示,浮点数左边有1个非空数字(零除外,或最终值接近零,失去精度并逐渐下溢),p-1
浮点后的数字。
但是通过适当地移动指数(e+1-p
),它也可以被视为具有p
位数xxxxxxxxx.0
的整数。
对于指数的可合理范围,我们看到每个直到b^p
的整数都可以由这样的浮点模型精确表示。由于精度有限,只有基数b
中的最后一位数字会丢失,所以如果我们有一个太大而不适合有效数字的整数,它必然会有一个零分数部分。因此,除了一个整数值(零分数部分)之外,没有理由进行回答。
您注意到的唯一不安全部分是Int
范围可能远小于浮点值范围。因此,将大浮点数转换为Int可能会导致溢出异常,或者更糟糕的是,带有未定义行为的静默溢出...
因此,为了消除分数部分,不需要转换为Int。它必须用于其他目的(比如提供只接受Int的程序的另一部分)。