ios “% 不可用:使用 truncatingRemainder 代替”是什么意思?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40495301/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What does "% is unavailable: Use truncatingRemainder instead" mean?
提问by Cosmic Arrows
I get the following error when using code for an extension, I'm not sure if they're asking to just use a different operator or modify the values in the expression based on an internet search.
使用扩展代码时出现以下错误,我不确定他们是要求使用不同的运算符还是根据 Internet 搜索修改表达式中的值。
Error: % is unavailable: Use truncatingRemainder instead
错误:% 不可用:改用 truncatingRemainder
Extension code:
扩展代码:
extension CMTime {
var durationText:String {
let totalSeconds = CMTimeGetSeconds(self)
let hours:Int = Int(totalSeconds / 3600)
let minutes:Int = Int(totalSeconds % 3600 / 60)
let seconds:Int = Int(totalSeconds % 60)
if hours > 0 {
return String(format: "%i:%02i:%02i", hours, minutes, seconds)
} else {
return String(format: "%02i:%02i", minutes, seconds)
}
}
}
The error(s) occur when setting the minutes and seconds variables.
设置分钟和秒变量时发生错误。
回答by Martin R
CMTimeGetSeconds()
returns a floating point number (Float64
aka
Double
). In Swift 2 you could compute the
remainder of a floating point division as
CMTimeGetSeconds()
返回一个浮点数(Float64
又名
Double
)。在 Swift 2 中,您可以将浮点除法的余数计算为
let rem = 2.5 % 1.1
print(rem) // 0.3
In Swift 3 this is done with
在 Swift 3 中,这是通过
let rem = 2.5.truncatingRemainder(dividingBy: 1.1)
print(rem) // 0.3
Applied to your code:
应用于您的代码:
let totalSeconds = CMTimeGetSeconds(self)
let hours = Int(totalSeconds / 3600)
let minutes = Int((totalSeconds.truncatingRemainder(dividingBy: 3600)) / 60)
let seconds = Int(totalSeconds.truncatingRemainder(dividingBy: 60))
However, in this particular case it is easier to convert the duration to an integer in the first place:
但是,在这种特殊情况下,首先将持续时间转换为整数会更容易:
let totalSeconds = Int(CMTimeGetSeconds(self)) // Truncate to integer
// Or:
let totalSeconds = lrint(CMTimeGetSeconds(self)) // Round to nearest integer
Then the next lines simplify to
然后下一行简化为
let hours = totalSeconds / 3600
let minutes = (totalSeconds % 3600) / 60
let seconds = totalSeconds % 60
回答by rickster
The %
modulus operator is defined only for integer types. For floating-point types, you need to be more specific about the kind of IEEE 754 division/remainder behavior you want, so you have to call a method: either remainder
or truncatingRemainder
. (If you're doing floating-point math you actually need to care about this, and lots of other stuff, or you can get unexpected / bad results.)
的%
模数运算符仅被定义为整数类型。对于浮点型,你需要了解你想要的那种IEEE 754除法/余的行为更具体的,所以你要调用一个方法:要么remainder
或truncatingRemainder
。(如果你在做浮点数学,你实际上需要关心这个,还有很多其他的东西,否则你会得到意想不到的/糟糕的结果。)
If you actually intend to do integer modulus, you need to convert the return value of CMTimeGetSeconds
to an integer before using %
. (Note that if you do, you'll lop off the fractional seconds... depending on where you're using CMTime
that may be important. Do you want minutes:seconds:frames, for example?)
如果你真的打算做整数模数,你需要CMTimeGetSeconds
在使用之前将 的返回值转换为整数%
。(请注意,如果这样做,您将删除小数秒...取决于您使用的位置CMTime
,这可能很重要。例如,您想要分:秒:帧吗?)
Depending on how you want to present CMTime
values in your UI, it might be better to extract the seconds value and pass it to NSDateFormatter
or NSDateComponentsFormatter
so you get appropriate locale support.
根据您希望如何CMTime
在 UI 中显示值,最好提取秒值并将其传递给NSDateFormatter
orNSDateComponentsFormatter
以获得适当的语言环境支持。
回答by eonist
Bring back the simple modulo syntax in swift 3:
在 swift 3 中恢复简单的模语法:
This syntax was actually suggested on Apples official swift mailing list herebut for some reason they opted for a less elegant syntax.
这个语法是在苹果官方迅速邮件列表实际上建议这里,但由于某种原因,他们选择了一个不太优雅的语法。
infix operator %%/*<--infix operator is required for custom infix char combos*/
/**
* Brings back simple modulo syntax (was removed in swift 3)
* Calculates the remainder of expression1 divided by expression2
* The sign of the modulo result matches the sign of the dividend (the first number). For example, -4 % 3 and -4 % -3 both evaluate to -1
* EXAMPLE:
* print(12 %% 5) // 2
* print(4.3 %% 2.1) // 0.0999999999999996
* print(4 %% 4) // 0
* NOTE: The first print returns 2, rather than 12/5 or 2.4, because the modulo (%) operator returns only the remainder. The second trace returns 0.0999999999999996 instead of the expected 0.1 because of the limitations of floating-point accuracy in binary computing.
* NOTE: Int's can still use single %
* NOTE: there is also .remainder which supports returning negatives as oppose to truncatingRemainder (aka the old %) which returns only positive.
*/
public func %% (left:CGFloat, right:CGFloat) -> CGFloat {
return left.truncatingRemainder(dividingBy: right)
}
This simple swift 3 migration tip is part of a more comprehensive swift 3 migration guide with many insights (35k loc / 8-days of migration) http://eon.codes/blog/2017/01/12/swift-3-migration/
这个简单的 swift 3 迁移技巧是更全面的 swift 3 迁移指南的一部分,其中包含许多见解(35k loc / 8 天的迁移)http://eon.codes/blog/2017/01/12/swift-3-migration /
回答by benwiggy
I found that the following works in Swift 3:
我发现以下在 Swift 3 中有效:
let minutes = Int(floor(totalSeconds / 60))
let seconds = Int(totalSeconds) % 60
where totalSeconds
is a TimeInterval
(Double
).
哪里totalSeconds
是TimeInterval
( Double
)
回答by Peter Schorn
There's no need to create a separate modulo operator for floating point numbers, unless you think it makes the code safer. You can overload the %
operator to accept floating point numbers like so:
无需为浮点数创建单独的模运算符,除非您认为它使代码更安全。您可以重载%
运算符以接受浮点数,如下所示:
func %<N: BinaryFloatingPoint>(lhs: N, rhs: N) -> N {
lhs.truncatingRemainder(dividingBy: rhs)
}
Usage
用法
let a: Float80 = 10
let b: Float80 = 3
print(a % b)
You can now use %
with any two floating point numbers of the same tye.
您现在可以使用%
相同类型的任意两个浮点数。