负数的模数如何在swift中工作? 当我这样做(-1%3)时,它给出了-1,但余下的是2.它有什么收获?
答案 0 :(得分:21)
Swift 余数运算符 %
计算余数
整数除法:
a % b = a - (a/b) * b
其中/
是截断整数除法。在你的情况下
(-1) % 3 = (-1) - ((-1)/3) * 3 = (-1) - 0 * 3 = -1
因此余数总是与股息相同(除非 余数为零)。
这与所要求的定义相同,例如:在C99标准中, 例如,看看 Does either ANSI C or ISO C specify what -5 % 10 should be?。也可以看看 Wikipedia: Modulo operation了解概述 如何在不同的编程语言中处理它。
可以在Swift中定义“真实”模数函数,如下所示:
func mod(_ a: Int, _ n: Int) -> Int {
precondition(n > 0, "modulus must be positive")
let r = a % n
return r >= 0 ? r : r + n
}
print(mod(-1, 3)) // 2
答案 1 :(得分:5)
来自Language Guide - Basic Operators:
剩余运营商
余数运算符(
a % b
)计算出b
的倍数 将放在a
内,并返回剩余的值(称为 其余的)。余数运算符(
%
)也称为模运算符 其他语言。但是,它在Swift中对负数的行为 意味着它严格来说是一个余数而不是一个模数 操作强>...
在计算a的余数时应用相同的方法 a的负值:
-9 % 4 // equals -1
在等式中插入
-9
和4
会产生:-9 = (4 x -2) + -1
给出余数值
-1
。
在您的情况下,3
不适合1
,其余为1
(与-1
相同 - >余数为-1
)
答案 2 :(得分:0)
如果您真正想要的是捕获0到b之间的数字,请尝试使用此功能:
infix operator %%
extension Int {
static func %% (_ left: Int, _ right: Int) -> Int {
if left >= 0 { return left % right }
if left >= -right { return (left+right) }
return ((left % right)+right)%right
}
}
print(-1 %% 3) //prints 2
这将适用于a的所有值,这与先前的答案不同,而仅适用于> -b的情况。
相对于仅重载%,我更喜欢%%运算符,因为很明显您没有在执行真正的mod函数。
使用if语句而不是仅使用最终返回行的原因是为了提高速度,因为mod函数需要除法,除法比有条件的除法更昂贵。
答案 3 :(得分:0)
受cdeerinck启发,为了简化而牺牲速度的答案是:
infix operator %%
extension Int {
static func %% (_ left: Int, _ right: Int) -> Int {
let mod = left % right
return mod >= 0 ? mod : mod + right
}
}
我在操场上用这个小圈进行了测试:
for test in [6, 5, 4, 0, -1, -2, -100, -101] {
print(test, "%% 5", test %% 5)
}