如何在Double中将Double舍入到最近的Int?

时间:2014-10-14 00:35:29

标签: swift int double rounding

我试图制作一个增长率(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必须成为变量并在整个程序中进行更改(以便进行下一次计算),我不希望它发生。

9 个答案:

答案 0 :(得分:207)

round中有一个Foundation(它实际上位于Darwin,但Foundation导入Darwin且大部分时间都有您需要使用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)

舍入到小数点后两位:

let numberOfPlaces = 2.0
let multiplier = pow(10.0, numberOfPlaces)
let num = 10.12345
let rounded = round(num * multiplier) / multiplier
print(rounded)

输出:

  

10.12

注意:由于浮点数学运算的方式,rounded可能并不总是完全准确。最好把它想象成舍入的近似值。如果您是出于显示目的而这样做,最好使用字符串格式来格式化数字,而不是使用数学来围绕它。

答案 1 :(得分:123)

要将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

正如人们可能期望的那样(or might not),会向{@ 1}}这样的数字进行向上舍入,并向下舍入类似3.5的数字。如果您需要不同的舍入行为,可以使用rounding rules之一。例如:

-3.5

如果你需要一个实际的var x = 3.7 x.round(.towardZero) // 3.0 ,那么只需将其投射到一个(但只有在你确定Double赢得大于Int时):

Int.max

注释

  • 这个答案完全被重写了。我的旧答案涉及C let myInt = Int(myDouble.rounded()) roundlroundfloor等数学函数。但是,既然Swift内置了这个功能,我就不能再推荐使用这些功能了。感谢@dfri向我指出这一点。查看@dfri's excellent answer here。我也为rounding a CGFloat做了类似的事情。

答案 2 :(得分:63)

Swift 3&amp; 4 - 在rounded(_:)协议

中使用FloatingPoint方法作为蓝图

FloatingPoint protocol rounded(_:) method

FloatingPointRoundingRule蓝图(例如DoubleFloat符合)
func rounded(_ rule: FloatingPointRoundingRule) -> Self

其中@Suragch's excellent answer是一个列举了许多不同舍入规则的枚举:

  

<强> case awayFromZero

     

舍入到最接近的允许值,其大小大于或   等于来源的。

     

<强> case down

     

舍入到最接近的允许值,该值小于或等于   源。

     

<强> case toNearestOrAwayFromZero

     

舍入到最接近的允许值;如果两个值相等,   选择幅度更大的那个。

     

<强> case toNearestOrEven

     

舍入到最接近的允许值;如果两个值相等,   选择了偶数。

     

<强> case towardZero

     

舍入到最接近的允许值,其大小小于或   等于来源的。

     

<强> case up

     

舍入到最大允许值大于或等于   来源。

我们在rounded() method中使用类似的示例来展示这些不同的舍入选项。

.awayFromZero

舍入到最接近的允许值,其大小大于或等于源的大小; C函数之间没有直接的等价物,因为它分别对selfceilfloor的符号有条件地使用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函数。

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函数。

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

也可以使用零参数swift/stdlib/public/core/FloatingPoint.swift.gyb来访问此舍入规则。

3.000.rounded() // 3.0
// ...

(-3.000).rounded() // -3.0
// ...

.toNearestOrEven

舍入到最接近的允许值;如果两个值相等,则选择偶数;相当于C rint(/非常类似于nearbyint)函数。

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

如果舍入的目的是准备使用整数(例如,在舍入后使用IntFloatPoint初始化),我们可能只是使用初始化{{{ 1}}使用Int(或Double等),小数部分将被截断。

Float

Int(3.000) // 3 Int(3.001) // 3 Int(3.999) // 3 Int(-3.000) // -3 Int(-3.001) // -3 Int(-3.999) // -3

相当于C .up函数。

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 的源代码,以验证C函数与不同FloatingPoint规则的等效性

如果我们愿意,我们可以查看FloatingPointRoundingRule协议的源代码,直接查看与公共FloatingPoint规则等效的C函数。

swift/stdlib/public/core/FloatingPointTypes.swift.gyb我们看到FloatingPointRoundingRule方法的默认实现使我们改变了rounded(_:)方法:

round(_:)

从{{3}}我们找到public func rounded(_ rule: FloatingPointRoundingRule) -> Self { var lhs = self lhs.round(rule) return lhs } 的默认实现,其中round(_:)规则与C舍入函数之间的等效性是显而易见的:

FloatingPointRoundingRule

答案 3 :(得分:5)

斯威夫特3: 如果你想要舍入到某个数字,例如5.678434 - &gt; 5.68你可以将round()或roundf()函数与乘法结合起来:

    let value:Float = 5.678434
    let roundedValue = roundf(value * 100) / 100
    print(roundedValue) //5.68

答案 4 :(得分:2)

**In Swift**

var a = 14.123456789
var b = 14.123456789
var c = 14.123456789
var d = 14.123456789
var e = 14.123456789
var f = 14.123456789

a.rounded(.up)                      //15
b.rounded(.down)                    //14
c.rounded(.awayFromZero)            //15
d.rounded(.towardZero)              //14
e.rounded(.toNearestOrAwayFromZero) //14
f.rounded(.toNearestOrEven)         //14

答案 5 :(得分:1)

Swift 3

var myNum = 8.09

myNum.rounded()// result = 8,存储在myNum

答案 6 :(得分:1)

您还可以在Swift 3中扩展FloatingPoint,如下所示:

extension FloatingPoint {
    func rounded(to n: Int) -> Self {
        return (self / Self(n)).rounded() * Self(n)

    }
}

324.0.rounded(to: 5)   // 325

答案 7 :(得分:0)

一个非常简单的解决方案对我有用:

  if (62 % 50 != 0) {
      var number = 62 / 50 + 1 // adding 1 is doing the actual "round up"
  }

数字包含值2

答案 8 :(得分:0)

您可能还想在将值转换为Int之前检查double是否大于最大Int值。

let number = Double.infinity
if number >= Double(integerLiteral: Int64.max) {
  let rounded = Int.max
} else {
  let rounded = Int(number.rounded())
}