web-dev-qa-db-ja.com

「%は使用できません:代わりにtruncatingRemainderを使用してください」とはどういう意味ですか?

拡張機能のコードを使用すると、次のエラーが表示されます。別の演算子を使用するだけなのか、インターネット検索に基づいて式の値を変更するのかどうかはわかりません。

エラー:%は利用できません:代わりにtruncatingRemainderを使用してください

拡張コード:

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)
        }
    }
}

分と秒の変数を設定すると、エラーが発生します。

84
Cosmic Arrows

CMTimeGetSeconds()は浮動小数点数(Float64別名Double)を返します。 Swift 2では、浮動小数点除算の剰余を次のように計算できます。

let rem = 2.5 % 1.1
print(rem) // 0.3

Swift 3では、これは

let rem = 2.5.truncatingRemainder(dividingBy: 1.1)
print(rem) // 0.3

コードに適用:

let totalSeconds = CMTimeGetSeconds(self)
let hours = Int(totalSeconds / 3600)
let minutes = Int((totalSeconds.truncatingRemainder(dividingBy: 3600)) / 60)
let seconds = Int(totalSeconds.truncatingRemainder(dividingBy: 60))

ただし、この特定のケースでは、最初から継続時間を整数に変換する方が簡単です。

let totalSeconds = Int(CMTimeGetSeconds(self)) // Truncate to integer
// Or:
let totalSeconds = lrint(CMTimeGetSeconds(self)) // Round to nearest integer

次に、次の行は

let hours = totalSeconds / 3600
let minutes = (totalSeconds % 3600) / 60
let seconds = totalSeconds % 60
150
Martin R

%モジュラス演算子は、整数型に対してのみ定義されます。浮動小数点型の場合は、希望するIEEE 754除算/剰余の動作の種類をより具体的にする必要があるため、メソッドを呼び出す必要があります: remainder または truncatingRemainder =。 (浮動小数点演算を行っている場合は、実際にこれに注意する必要があり、 他の多くのもの 、または予期しない/悪い結果を得る可能性があります。)

実際に整数モジュラスを実行する場合は、%を使用する前に、CMTimeGetSecondsの戻り値を整数に変換する必要があります。 (その場合、重要な場合があるCMTimeを使用している場所に応じて、小数秒を切り捨てます。たとえば、minutes:seconds:framesが必要ですか?)

UIでCMTime値をどのように表示するかに応じて、秒の値を抽出し、それを NSDateFormatter または NSDateComponentsFormatter に渡して、適切なロケールサポートを取得することをお勧めします。

21
rickster

Swift 3の単純なモジュロ構文を取り戻します:

この構文は、実際にはAppleの公式Swiftメーリングリストで提案されました here ですが、何らかの理由で、エレガントではない構文を選択しました。

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)
}

この簡単なSwift 3移行のヒントは、多くの洞察(35k loc/8日間の移行)を含むより包括的なSwift 3移行ガイドの一部です http:// eon .codes/blog/2017/01/12/Swift-3-migration /

9
eonist

Swift 3で次の機能が動作することがわかりました。

    let minutes = Int(floor(totalSeconds / 60))
    let seconds = Int(totalSeconds) % 60

ここで、totalSecondsTimeIntervalDouble)です。

3
benwiggy