gpt4 book ai didi

Swift 余数函数和舍入

转载 作者:行者123 更新时间:2023-11-30 10:44:11 25 4
gpt4 key购买 nike

我正在制作自己的特定图形框架,但在处理一些简单的剩余 if 语句时遇到困难。

我希望 X 轴是对数的。每次用户平移图表时,它都会将 X-Min 和 X-Max 值更改 Translation.x 数量。

我有以下代码

for i in Int(xMin)...Int(xMax) {
let logValue = Double(log10(Float(i)))
let rounded = logValue.rounded(toPlaces:3)

if rounded.truncatingRemainder(dividingBy: 0.1) == 0 {
//Draw division line
print("Got Here")
}
}

extension Double {
/// Rounds the double to decimal places value
func rounded(toPlaces places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}

如果我在代码中放置断点,我可以看到如果 rounded 的值为 1.3,则代码永远不会到达打印行。如果我再次手动输入舍入为 100 的值,则永远不会到达打印行。

到目前为止,我在使用整数的 % 余数运算符时没有遇到任何问题,但是无法弄清楚我哪里出了问题。

最佳答案

发生这种情况是因为底层计算是二进制而不是十进制。

我们可以使用Decimal (自 Swift 3 起)做得更好。这是一个快速但肮脏的 mod 函数用于说明:

// a mod b = a - b*floor(a/b)
func mod(_ a: Decimal,_ b: Decimal) -> Decimal {
var d = a/(b)
var f : Decimal = 0
NSDecimalRound(&f, &d, 0, .down)
return a-(b*(f))
}

使用普通浮点计算:

var i = 1.3
var j = 0.1
i.truncatingRemainder(dividingBy: j) // 0.09999999999999998

i = 1.3
j = 0.15
i.truncatingRemainder(dividingBy: j) // 0.1000000000000001

带小数:

var a : Decimal = 1.3
var b : Decimal = 0.1
mod(a, b) // 0

a = 1.3
b = 0.15
mod(a, b) // 0.1

我们仍然需要小心:

var a : Decimal = 0.906 // 0.9060000000000002048 conversion to decimal issue

// Specify the significant digits directly
a = Decimal(sign: FloatingPointSign.plus, exponent: -3, significand: Decimal(906)) // 0.906
mod(a, Decimal(0.1)) // 0.006

因此,仍然应该进行仔细的舍入和/或允许一些小的“epsilon”误差范围。 (与 0 这样的精确数字相比可能不是一个好主意)。

关于Swift 余数函数和舍入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56134459/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com