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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 10:45:02  来源:igfitidea点击:

What does "% is unavailable: Use truncatingRemainder instead" mean?

iosswiftswift3modulus

提问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 (Float64aka 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 remainderor 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除法/余的行为更具体的,所以你要调用一个方法:要么remaindertruncatingRemainder。(如果你在做浮点数学,你实际上需要关心这个,还有很多其他的东西,否则你会得到意想不到的/糟糕的结果。)

If you actually intend to do integer modulus, you need to convert the return value of CMTimeGetSecondsto an integer before using %. (Note that if you do, you'll lop off the fractional seconds... depending on where you're using CMTimethat may be important. Do you want minutes:seconds:frames, for example?)

如果你真的打算做整数模数,你需要CMTimeGetSeconds在使用之前将 的返回值转换为整数%。(请注意,如果这样做,您将删除小数秒...取决于您使用的位置CMTime,这可能很重要。例如,您想要分:秒:帧吗?)

Depending on how you want to present CMTimevalues in your UI, it might be better to extract the seconds value and pass it to NSDateFormatteror NSDateComponentsFormatterso you get appropriate locale support.

根据您希望如何CMTime在 UI 中显示值,最好提取秒值并将其传递给NSDateFormatterorNSDateComponentsFormatter以获得适当的语言环境支持。

回答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 totalSecondsis a TimeInterval(Double).

哪里totalSecondsTimeInterval( 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.

您现在可以使用%相同类型的任意两个浮点数。