我试图显示一个浮点数,但将其四舍五入,
f = 5.545
显示为:5.55
f = 5.544
显示为:5.54
我见过只显示两个小数点的方法,但是我想将其四舍五入。
谢谢!
答案 0 :(得分:0)
之所以发生这种情况,是因为浮点数在计算机中的表示方式是:它们实际上以2为底,而不是以10为底(有点过分简化,但足够好)。因此,当您键入0.545
时,计算机实际上将其记录为0.5499999999...
-非常接近0.545
,但略小。而且由于它小于0.545
,因此也难怪它会四舍五入为0.54
。
如果您确实必须有精确的以10为底的数字,您应该使用Decimal
而不是Float
或Double
。该软件包特别注意以10为基数表示浮点数,而不会丢失。
x :: Decimal
x = 0.545
show x
> "0.545"
需要注意的是printf
不支持Decimal
,因此您必须通过roundTo
进行四舍五入并通过show
转换为字符串来显示它。 roundTo
进行“银行取整”的另一个注意事项-如果最后一位为5,则将其舍入为最接近的偶数数字,因此,作为特殊情况,我们需要予以抵消(我找不到可以通过算术规则四舍五入的现成函数):
displayDecimal :: Decimal -> String
displayDecimal x = show (rounded + compensate)
where rounded = roundTo 2 x
compensate = if (x - rounded) == 0.005 then 0.01 else 0
displayDecimal 0.545
> "0.55"
displayDecimal 0.5450000000001
> "0.55"
displayDecimal 0.544
> "0.54"
displayDecimal 0.5449999999999
> "0.54"
但是,如果您只希望将其用于具有小数点后三位的数字,则可以避免在四舍五入之前仅添加一个很小的值,例如0.00001
。此值足够小,不会混淆您的实际数字,但又足够大,可以补偿以2为基数与以10为基数的差异:
displayRounded :: Double -> String
displayRounded x = printf "%.2f" (x + 0.00001)
displayRounded 0.544
> "0.54"
displayRounded 0.545
> "0.55"
答案 1 :(得分:0)
所以我还没有找到一个真正的解决方案,但是我意识到了:
Printf已经完成了工作,但不完全是我想要的。 假设我要舍入1.445,它将显示1.44。但是,如果数字为1.446,则显示为1.45。
并不是我想要的,但是足够接近。