"% अनुपलब्ध है: इसके बजाय truncatingRemainder का उपयोग करें" का अर्थ है?


104

एक्सटेंशन के लिए कोड का उपयोग करते समय मुझे निम्नलिखित त्रुटि मिलती है, मुझे यकीन नहीं है कि वे एक अलग ऑपरेटर का उपयोग करने या इंटरनेट खोज के आधार पर अभिव्यक्ति में मूल्यों को संशोधित करने के लिए कह रहे हैं।

त्रुटि:% अनुपलब्ध है: इसके बजाय 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)
        }
    }
}

मिनट और सेकंड चर सेट करते समय त्रुटि होती है।


1
मुझे लगता है कि CMTimeGetSeconds ने फ्लोट
ज़ोंबी

3
इसका मतलब है कि %ऑपरेटर अनुपलब्ध है और आपको truncatingRemainderइसके बजाय विधि जैसी किसी चीज़ का उपयोग करने पर विचार करना चाहिए ।
मैट

1
आप modulo का उपयोग केवल Float64और Intकेवल पर नहीं कर सकते इसलिए: let minutes:Int = Int(totalSeconds) % 3600 / 60; let seconds:Int = Int(totalSeconds) % 60सही तरीका है।
holex

जवाबों:


174

CMTimeGetSeconds()एक अस्थायी बिंदु संख्या ( Float64उर्फ Double) देता है। स्विफ्ट 2 में आप फ्लोटिंग पॉइंट डिवीजन के शेष भाग की गणना कर सकते हैं

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

स्विफ्ट 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

24

%मापांक ऑपरेटर केवल पूर्णांक प्रकार के लिए परिभाषित किया गया है। फ्लोटिंग प्वाइंट प्रकार के लिए, आप, आप चाहते हैं आईईईई 754 विभाजन / शेष व्यवहार प्रकार के बारे में विशिष्ट होने की जरूरत है ताकि आप एक विधि कॉल करना होगा: remainderया truncatingRemainder। (यदि आप फ्लोटिंग-पॉइंट गणित कर रहे हैं, तो आपको वास्तव में इस बारे में, और बहुत सारे अन्य सामान की देखभाल करने की आवश्यकता है , या आप अप्रत्याशित / खराब परिणाम प्राप्त कर सकते हैं।)

यदि आप वास्तव में पूर्णांक मापांक करने का इरादा रखते हैं, तो CMTimeGetSecondsउपयोग करने से पहले आपको पूर्णांक के रिटर्न मान को परिवर्तित करना होगा %। (ध्यान दें कि यदि आप करते हैं, तो आप भिन्नात्मक सेकंड बंद कर देंगे ... इस बात पर निर्भर करता है कि आप कहाँ उपयोग कर रहे हैं CMTimeजो महत्वपूर्ण हो सकता है। क्या आप मिनट चाहते हैं: सेकंड: फ्रेम, उदाहरण के लिए?)

कैसे आप वर्तमान करना चाहते हैं पर निर्भर करता है CMTimeआपके यूआई में मूल्यों, यह बेहतर हो सेकंड मूल्य निकालने और इसे करने के लिए पारित करने के लिए हो सकता है NSDateFormatterया NSDateComponentsFormatterतो आप उचित स्थान समर्थन मिलता है।


10

स्विफ्ट 3 में साधारण मोड्यूलो सिंटैक्स वापस लाएं:

इस सिंटैक्स को वास्तव में यहां एपल्स की आधिकारिक स्विफ्ट मेलिंग सूची में सुझाया गया था, लेकिन किसी कारण से उन्होंने कम सुरुचिपूर्ण सिंटैक्स का विकल्प चुना।

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

यह सरल स्विफ्ट 3 माइग्रेशन टिप अधिक अंतर्दृष्टि के साथ एक अधिक व्यापक स्विफ्ट 3 माइग्रेशन गाइड का हिस्सा है (35k लोकेशन / 8-दिन का माइग्रेशन) http://eon.codes/blog/2017/01/12/swift-3-migration /


1
यह A ठीक है, रोचक जानकारी प्रदान करता है और Q. का जवाब देने की कोशिश भी करता है
जकब त्राहाल

3
@ जाकूब त्राहालhl ... यार, Thx। IMO यह मेरा सबसे अच्छा स्विफ्ट 3 माइग्रेशन फिक्स था। विश्वास नहीं कर सकते हैं कि लोगों ने इसे वोट दिया है। मोडुलो एक ऐसी महत्वपूर्ण अवधारणा है और इसे हर कोड बुक में सोचा जाता है जिसमें अंकगणित होता है। इसे क्रिया बनाने से कोई मतलब नहीं है क्योंकि कोड में अंकगणित को यथासंभव कॉम्पैक्ट रूप से लिखा जाना चाहिए। जैसा कि अंकगणित को समझने की हमारी संज्ञानात्मक क्षमता बढ़ जाती है जब आप पूरी तस्वीर को समझने के लिए विरोध के रूप में देख सकते हैं कि व्यक्तिगत चर का मतलब क्या है। IMO व्यापक चर नामकरण व्यापार तर्क में महत्वपूर्ण है, लेकिन अंकगणित नहीं, काफी विपरीत है।
eonist

2
@GitSync मोडुलो एक महत्वपूर्ण अवधारणा है लेकिन यह केवल पूर्णांकों के लिए मौजूद है। आपको फर्क समझना चाहिए।
सुल्तान

5
@GitSync मोड्यूलो ऑपरेशन केवल पूर्णांकों के लिए मौजूद है। आप शेष के बारे में बात कर रहे हैं। दशमलव मानों में दो प्रकार के अवशेष होते हैं। इसलिए स्विफ्ट ने ऑपरेशन को स्पष्ट करने का फैसला किया। दोहरे मानों पर पूर्णांक शेष ( ट्रंक शेष ) की गणना करना बहुत आम नहीं है ।
सुल्तान

1
@GitSync है remainder(dividingBy:)और truncatingRemainder(dividingBy:)आप दोनों के लिए डॉक्स पढ़ना चाह सकते हैं। इसके अलावा, C ++ stackoverflow.com/questions/6102948/…
सुल्तान

2

मैंने पाया कि निम्नलिखित स्विफ्ट 3 में काम करता है:

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

कहाँ totalSecondsहै TimeInterval( Double)


3
मिक्सिंग फ्लोर और राउंड एक अच्छा विचार नहीं है, जैसे totalSeconds = 59.8आपके कोड के लिए 0 मिनट और 0 सेकंड की गणना होती है।
मार्टिन आर

हाँ तुम सही हो। वास्तव में, roundबिल्कुल जरूरत नहीं है।
बेनीवेग जूल

1

फ़्लोटिंग पॉइंट नंबरों के लिए एक अलग मोड्यूलो ऑपरेटर बनाने की कोई आवश्यकता नहीं है, जब तक आपको नहीं लगता कि यह कोड को सुरक्षित बनाता है। आप %फ्लोटिंग पॉइंट नंबरों को स्वीकार करने के लिए ऑपरेटर को ओवरलोड कर सकते हैं :

func %<N: BinaryFloatingPoint>(lhs: N, rhs: N) -> N {
    lhs.truncatingRemainder(dividingBy: rhs)
}

प्रयोग

let a: Float80 = 10
let b: Float80 = 3
print(a % b)

अब आप %एक ही tye के दो फ्लोटिंग पॉइंट नंबरों के साथ उपयोग कर सकते हैं ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.