使 Int 舍入到最接近的值

Make Int round off to nearest value

我有两个 Int 值(它们必须是 Ints),我希望它们在方程式中四舍五入到最接近的值;

var Example = Int()
var secondExample = Int()

Example = (secondExample / 7000)

这个等式使得变量 Example 总是向下舍入到最低值。例如说数字如下;

var Example = Int()
var secondExample : Int = 20000

Example = (20000 / 7000)

20000 / 7000 等于 2.857... 但是变量 Example 显示 2.

如何使 Example 四舍五入到最接近的数字 而不将其更改为 Double

对于非负整数,下面的函数给出 纯整数算术所需的结果:

func divideAndRound(numerator: Int, _ denominator: Int) -> Int {
    return (2 * numerator + denominator)/(2 * denominator)
}

示例:

print(20000.0/7000.0) // 2.85714285714286
print(divideAndRound(20000, 7000)) // 3 (rounded up)

print(10000.0/7000.0) // 1.42857142857143
print(divideAndRound(10000, 7000)) // 1 (rounded down)

想法是

 a   1   2 * a + b
 - + - = ---------
 b   2     2 * b

这是任意签名的可能实现 也不会溢出的整数:

func divideAndRound(num: Int, _ den: Int) -> Int {
    return num / den + (num % den) / (den / 2 + den % 2)
}

(基于@user3441734更新的解决方案,所以我们有一个参考 现在在我们的答案之间循环:)

还有一个 ldiv 函数可以计算商 和除法的余数,所以最后一个函数也可以是 实施为

func divideAndRound(num: Int, _ den: Int) -> Int {
    let div = ldiv(num, den)
    let div2 = ldiv(den, 2)
    return div.quot + div.rem / (div2.quot + div2.rem)
}

(我没有测试哪个版本更快。)

看马丁的回答!他的想法很棒,所以我扩展了他的负数解决方案

func divideAndRound(n: Int, _ d: Int) -> Int {
    let sn = n < 0 ? -1 : 1
    let sd = d < 0 ? -1 : 1
    let s = sn * sd
    let n = n * sn
    let d = d * sd
    return (2 * n + d)/(2 * d) * s
}

divideAndRound(1, 2) // 1
divideAndRound(1, 3) // 0
divideAndRound(-1, 2) // -1
divideAndRound(-1, 3) // 0
divideAndRound(1, -2) // -1
divideAndRound(1, -3) // 0

唯一的麻烦是 (2 * n + d) 会溢出,代码会崩溃。

更新! 在儿童数学的帮助下

func divr(a: Int, _ b: Int)->Int {
    return (a % b) * 2 / b  + a / b
}

它应该适用于任何 Int :-) 除了 0 分母