将浮点数截断为两位小数的最简单方法是什么?

7
在Swift中,有没有一种方法可以将浮点数截断为2位小数,以便您可以进行进一步的计算?我看到的所有线程都涉及将其转换为字符串,但我不知道如何在数学上使用它。我尝试使用一个扩展(在此论坛上找到),想着在截断后可以再次转换为浮点数,但最终又回到了起点,得到了另一个非截断的浮点数。我需要返回值是四分之一步长(例如6.50、6.75、5.25等),但我得到的结果是6.990022...等。肯定有一种简单的方法来解决这个问题,但我卡住了。提前感谢您...以下是问题:
func roundToNearestQuarter(#power : Float) -> String {

     var errorToLowerQuarterRaw : Float = power % 0.25  // 0.210000038146973

     var errorToLowerQuarterString = errorToLowerQuarterStepRaw.string(2)  // "0.21"

     var errorToLowerQuarter = NSString(string: errorToLowerQuaterStepString).floatValue  // 0.209999993443489

// more code

}

roundToNearestQuater(6.71)

如果有小数位,它就不是“float”。Swift的“float”是二进制的。 - Hot Licks
2个回答

11

你无法将FloatDouble精确地舍入到2个小数位。

原因是这些数据类型使用二进制浮点表示法,无法准确表示像0.1或0.01这样的数字。参见例如:

但是你说:

我需要我的返回值以四分之一步长(即6.50、6.75、5.25等)返回,

这是完全可能的,因为0.25 = 2-2 可以准确地表示为浮点数。

round()函数将浮点数四舍五入为最接近的整数值。要舍入到最近的四分之一,您只需使用因子4 "缩放" 计算即可:

func roundToNearestQuarter(num : Float) -> Float {
    return round(num * 4.0)/4.0
}

roundToNearestQuarter(6.71) // 6.75
roundToNearestQuarter(6.6)  // 6.5

@Attackfarm:你为什么这么认为?这个回答中所说的一切对于Double类型也是正确的。 - Martin R
@Attackfarm:看起来 Double 可以精确存储所有数字,因为 println() 会将输出四舍五入到小数点后6位,而 Double 的精度约为15位小数。但是试试 let x = 0.1 ; let y = 0.2 ; println(x + y - 0.3) ... - Martin R
好的,我没有意识到println()有这个限制。 - Attackfarm
2
如果您想要通过向下舍入来截断,请使用“floor”而不是“round”。 - Nick Yap

1
如果您需要进行真正精确的工作(例如与货币相关的应用程序),则可能希望使用NSDecimalNumber而不是浮点数。
可以将上述方法应用于NSDecimalNumbers,如下所示。在此示例中,您要舍入的“步骤”可以是您选择的任何内容,只需相应地设置“增量”。
let number: NSDecimalNumber = 100.52
let increment: NSDecimalNumber = 0.25

let handler = NSDecimalNumberHandler(roundingMode: NSRoundingMode.RoundBankers, scale: 0, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: false)     // Rounds to the nearest whole number
let result = number.decimalNumberByDividingBy(increment).decimalNumberByRoundingAccordingToBehavior(handler).decimalNumberByMultiplyingBy(increment)

想了解更多关于使用NSDecimalNumber进行四舍五入的内容,请参见这里:如何在Swift中对NSDecimalNumber进行四舍五入?

是的,使用NSDecimalNumber做数学运算很啰嗦,但并不复杂。如果你发现自己经常涉及到这方面的项目,我建议你考虑设置Swift操作符扩展,以便以更优雅的方式操纵它们。在这里查看一个不错的示例:https://gist.github.com/mattt/1ed12090d7c89f36fd28


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接