如何快速将一个Double舍入到最近的Int?
我试图做一个增长率计算器( Double
),将结果四舍五入到最近的整数,并从那里重新计算,如此:
let firstUsers = 10.0 let growth = 0.1 var users = firstUsers var week = 0 while users < 14 { println("week \(week) has \(users) users") users += users * growth week += 1 }
但迄今为止我还没有办法
编辑我有点这样做:
var firstUsers = 10.0 let growth = 0.1 var users:Int = Int(firstUsers) var week = 0 while users <= 14 { println("week \(week) has \(users) users") firstUsers += firstUsers * growth users = Int(firstUsers) week += 1 }
虽然我不介意它总是四舍五入,但我不喜欢它,因为第一个firstUsers
必须成为一个variables,并在整个程序中改变(为了进行下一个计算),我不希望它发生。
Foundation
图书馆有一个round
(实际上在Darwin
,但是Foundation
importDarwin
,大部分时间你会想用Foundation
而不是直接使用Darwin
) 。
import Foundation users = round(users)
在操场上运行你的代码然后调用:
print(round(users))
输出:
15.0
round()
总是在小数位数>= .5
时四舍五入,当< .5
(标准四舍五入)时小数位。 您可以使用floor()
强制四舍五入, ceil()
强制四舍五入。
如果你需要四舍五入到一个特定的地方,那么你乘以pow(10.0, number of places)
, round
,然后除以pow(10, number of places)
:
舍入到小数点后2位:
let numberOfPlaces = 2.0 let multiplier = pow(10.0, numberOfPlaces) let num = 10.12345 let rounded = round(10.12345 * multiplier) / multiplier print(rounded)
输出:
10.12
注意:由于浮点math运算的方式, rounded
可能并不总是非常准确。 最好把它看作是四舍五入的近似值。 如果你这样做是为了显示目的,最好使用string格式来格式化数字,而不是使用math来四舍五入。
要将double加到最接近的整数,只需使用round()
。
var x = 3.7 x.round() // x = 4.0
如果您不想修改原始值,则使用rounded()
:
let x = 3.7 let y = x.rounded() // y = 4.0. x = 3.7
正如人们所期望的那样( 或者不可能 ),像3.5
这样的数字会被舍入,像-3.5
这样的数字被舍去。 如果您需要不同的舍入行为,则可以使用其中一个舍入规则 。 例如:
var x = 3.7 x.round(.towardZero) // 3.0
如果你需要一个真正的Int
那么就把它转换成一个:
let myInt = Int(myDouble.rounded())
笔记
- 这个答案是完全重写的。 我的旧回答涉及C,math函数,如
round
,lround
,floor
和ceil
。 但是,现在Swift已经内置了这个function,我不能再推荐使用这些函数。 感谢@dfri指出这一点。 在这里查看@ dfri的优秀答案 。 我也做了类似的四舍五入CGFloat
。
Swift 3 – 使用FloatingPoint
协议中的rounded(_:)
方法
FloatingPoint
协议 (例如Double
和Float
符合)蓝图rounded(_:)
方法
func rounded(_ rule: FloatingPointRoundingRule) -> Self
FloatingPointRoundingRule
是枚举枚举许多不同舍入规则的枚举:
case awayFromZero
四舍五入到最接近的允许值,其幅度大于或等于源的值。
case down
舍入到小于或等于源的最近允许值。
case toNearestOrAwayFromZero
舍入最接近的允许值; 如果两个值相等,则select较大幅度的值。
case toNearestOrEven
舍入最接近的允许值; 如果两个值相等,则select偶数。
case towardZero
四舍五入到最接近的允许值,其幅度小于或等于源的值。
case up
舍入到大于或等于源的最接近的允许值。
我们利用类似于@ Suragch优秀答案的例子来展示这些不同的舍入选项。
.awayFromZero
四舍五入到最接近的允许值,其幅度大于或等于源的值; 在C函数之间不存在直接的等价关系,因为这有条件地用self
,单元或floor
符号表示self
的正负值。
3.000.rounded(.awayFromZero) // 3.0 3.001.rounded(.awayFromZero) // 4.0 3.999.rounded(.awayFromZero) // 4.0 (-3.000).rounded(.awayFromZero) // -3.0 (-3.001).rounded(.awayFromZero) // -4.0 (-3.999).rounded(.awayFromZero) // -4.0
.down
相当于C floor
function。
3.000.rounded(.down) // 3.0 3.001.rounded(.down) // 3.0 3.999.rounded(.down) // 3.0 (-3.000).rounded(.down) // -3.0 (-3.001).rounded(.down) // -4.0 (-3.999).rounded(.down) // -4.0
.toNearestOrAwayFromZero
相当于C round
function。
3.000.rounded(.toNearestOrAwayFromZero) // 3.0 3.001.rounded(.toNearestOrAwayFromZero) // 3.0 3.499.rounded(.toNearestOrAwayFromZero) // 3.0 3.500.rounded(.toNearestOrAwayFromZero) // 4.0 3.999.rounded(.toNearestOrAwayFromZero) // 4.0 (-3.000).rounded(.toNearestOrAwayFromZero) // -3.0 (-3.001).rounded(.toNearestOrAwayFromZero) // -3.0 (-3.499).rounded(.toNearestOrAwayFromZero) // -3.0 (-3.500).rounded(.toNearestOrAwayFromZero) // -4.0 (-3.999).rounded(.toNearestOrAwayFromZero) // -4.0
这个舍入规则也可以使用zero参数的rounded()
方法来访问。
3.000.rounded() // 3.0 // ... (-3.000).rounded() // -3.0 // ...
.toNearestOrEven
舍入最接近的允许值; 如果两个数值相等,则select偶数; 相当于C rint
(/非常类似于nearbyint
)的function。
3.499.rounded(.toNearestOrEven) // 3.0 3.500.rounded(.toNearestOrEven) // 4.0 (up to even) 3.501.rounded(.toNearestOrEven) // 4.0 4.499.rounded(.toNearestOrEven) // 4.0 4.500.rounded(.toNearestOrEven) // 4.0 (down to even) 4.501.rounded(.toNearestOrEven) // 4.0
.towardZero
等价于C trunc
函数。
3.000.rounded(.towardZero) // 3.0 3.001.rounded(.towardZero) // 3.0 3.999.rounded(.towardZero) // 3.0 (-3.000).rounded(.towardZero) // 3.0 (-3.001).rounded(.towardZero) // 3.0 (-3.999).rounded(.towardZero) // 3.0
如果四舍五入的目的是准备使用整数(例如,在四舍五入之后使用Int
by FloatPoint
初始化),那么我们可以简单地利用这样一个事实,即当使用Double
(或Float
等)初始化Int
时,小数部分将被截断。
Int(3.000) // 3 Int(3.001) // 3 Int(3.999) // 3 Int(-3.000) // -3 Int(-3.001) // -3 Int(-3.999) // -3
.up
相当于C ceil
函数。
3.000.rounded(.up) // 3.0 3.001.rounded(.up) // 4.0 3.999.rounded(.up) // 4.0 (-3.000).rounded(.up) // 3.0 (-3.001).rounded(.up) // 3.0 (-3.999).rounded(.up) // 3.0
附录:访问FloatingPoint
的源代码来validationC函数与不同的FloatingPointRoundingRule
规则等价
如果我们愿意的话,我们可以看看FloatingPoint
协议的源代码,直接看到与公共FloatingPointRoundingRule
规则等价的C函数。
从swift / stdlib / public / core / FloatingPoint.swift.gyb,我们看到rounded(_:)
方法的默认实现使得我们有了变异round(_:)
方法:
public func rounded(_ rule: FloatingPointRoundingRule) -> Self { var lhs = self lhs.round(rule) return lhs }
从swift / stdlib / public / core / FloatingPointTypes.swift.gyb我们find了round(_:)
的默认实现,其中FloatingPointRoundingRule
规则和C舍入函数之间的等价性是显而易见的:
public mutating func round(_ rule: FloatingPointRoundingRule) { switch rule { case .toNearestOrAwayFromZero: _value = Builtin.int_round_FPIEEE${bits}(_value) case .toNearestOrEven: _value = Builtin.int_rint_FPIEEE${bits}(_value) case .towardZero: _value = Builtin.int_trunc_FPIEEE${bits}(_value) case .awayFromZero: if sign == .minus { _value = Builtin.int_floor_FPIEEE${bits}(_value) } else { _value = Builtin.int_ceil_FPIEEE${bits}(_value) } case .up: _value = Builtin.int_ceil_FPIEEE${bits}(_value) case .down: _value = Builtin.int_floor_FPIEEE${bits}(_value) } }
您也可以在Swift 3中扩展FloatingPoint,如下所示:
extension FloatingPoint { func rounded(to n: Int) -> Self { return (self / Self(n)).rounded() * Self(n) } } 324.0.rounded(to: 5) // 325
Swift 3:如果你想四舍五入到一个特定的数字,例如5.678434 – > 5.68,你可以将round()或roundf()函数与乘法相结合:
let value:Float = 5.678434 let roundedValue = roundf(value * 100) / 100 print(roundedValue) //5.68
Swift 3
var myNum = 8.09
myNum.rounded()// result = 8它存储在myNum中