स्विफ्ट में दशमलव स्थानों के x संख्या के लिए एक डबल मान राउंडिंग


395

क्या कोई मुझे बता सकता है कि स्विफ्ट में दशमलव स्थानों के x संख्या के दोहरे मूल्य को कैसे गोल किया जाए?

मेरे पास है:

var totalWorkTimeInHours = (totalWorkTime/60/60)

totalWorkTimeदूसरे में NSTimeInterval (डबल) होने के साथ ।

totalWorkTimeInHours मुझे घंटे देगा, लेकिन यह मुझे इतने लंबे समय तक सटीक संख्या में समय देता है जैसे 1.543240952039 ......

जब मैं प्रिंट करता हूं, तो इसे 1.543 तक कैसे पूरा किया जाता है totalWorkTimeInHours?


1
देखें मेरा उत्तर एक डबल डार्विन का उपयोग कर पूर्णांक बनाना अप करने के लिए 9 विभिन्न तरीके खोजने के लिए round(_:), Double round(), NSStringप्रारंभकर्ता, Stringप्रारंभकर्ता, NumberFormatter, डबल विस्तार या यहां तक कि NSDecimalNumberऔर Decimal
इमानौ पेटिट

: @Rounded, एक तेज 5.1 संपत्ति आवरण gist.github.com/abhijithpp/1cc41b41a5d1c8f007da90f20bc0c65f
अभिजित

जवाबों:


389

roundइसे पूरा करने के लिए आप स्विफ्ट के फ़ंक्शन का उपयोग कर सकते हैं ।

Double3 अंकों की परिशुद्धता के साथ गोल करने के लिए , पहले इसे 1000 से गुणा करें, इसे गोल करें और 1000 से गोल परिणाम को विभाजित करें:

let x = 1.23556789
let y = Double(round(1000*x)/1000)
print(y)  // 1.236

किसी भी प्रकार printf(...)या String(format: ...)समाधान के अलावा, इस ऑपरेशन का परिणाम अभी भी प्रकार का है Double

संपादित करें:
टिप्पणियों के बारे में कि यह कभी-कभी काम नहीं करता है, कृपया इसे पढ़ें:

फ्लोटिंग-पॉइंट अंकगणित के बारे में हर प्रोग्रामर को क्या जानना चाहिए


कुछ कारणों से यह मदद नहीं करता है .. मैं इसे निम्नलिखित मामले में उपयोग कर रहा हूं ट्रांसफॉर्मऑफ <डबल, स्ट्रिंग> (fromJSON: {डबल (राउंड ($ 0! NSString के रूप में)) .DoubleValue * 100) / 100)}, toJSON: {($ 0) "})
फॉक्स

29
खेल के मैदान में मेरे लिए काम नहीं करता है: let rate = 9.94999999999; Double(round(rate * 100) / 100);आउटपुट: 9.94999999999, 9.949999999999999केवल प्रिंट के लिए काम करता है लेकिन मैं इसे चर में कैसे निर्दिष्ट कर सकता हूं?
अलेक्जेंडर याकोवलेव

आपको इसके लिए दशमलव का उपयोग करना चाहिए, न कि सादे डबल्स का।
csotiriou

13
"हर कंप्यूटर वैज्ञानिक को फ्लोटिंग-पॉइंट अंकगणित के बारे में क्या जानना चाहिए" 73 पृष्ठ लंबा है। उस पर टीएल, डीआर क्या है? :)
जेरेडएच

1
@HardikDG मुझे याद नहीं है, क्षमा करें :-)
अलेक्जेंडर

430

स्विफ्ट 2 के लिए विस्तार

एक अधिक सामान्य समाधान निम्नलिखित विस्तार है, जो स्विफ्ट 2 और आईओएस 9 के साथ काम करता है:

extension Double {
    /// Rounds the double to decimal places value
    func roundToPlaces(places:Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return round(self * divisor) / divisor
    }
}


स्विफ्ट 3 के लिए विस्तार

स्विफ्ट 3 roundमें प्रतिस्थापित किया गया है rounded:

extension Double {
    /// Rounds the double to decimal places value
    func rounded(toPlaces places:Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return (self * divisor).rounded() / divisor
    }
}


उदाहरण जो 4 दशमलव स्थानों पर डबल राउंड देता है:

let x = Double(0.123456789).roundToPlaces(4)  // x becomes 0.1235 under Swift 2
let x = Double(0.123456789).rounded(toPlaces: 4)  // Swift 3 version

17
स्विफ्ट के डबल की प्रकृति यह प्रतीत होती है कि यह इंक्रिसेज़ हो सकता है - जिस तरह से इसे बाइनरी में संग्रहीत / एक्सेस किया जाता है, यहां तक ​​कि इस राउंडिंग फ़ंक्शन का उपयोग करने से 3 दशमलव स्थानों पर गोल संख्या वापस नहीं आएगी: जैसे, round(8.46 * pow(10.0, 3.0)) / pow(10.0, 3.0)रिटर्न 8.460000000000001। फ्लोट के साथ कम से कम इस परिदृश्य में , वास्तव में काम करने लगता है: round(Float(8.46) * pow(10.0, 3.0)) / pow(10.0, 3.0)पैदावार8.46 । बस ध्यान देने योग्य कुछ है।
बेन सूफले

2
दुर्भाग्य से, यह अब स्विफ्ट 3 में काम नहीं करता है, मुझे यह त्रुटि मिल रही है No '*' candidates produce the expected contextual result type 'FloatingPointRoundingRule'
koi

2
मैंने समाधान को अद्यतन किया और स्विफ्ट 3 के लिए एक एक्सटेंशन जोड़ा।
सेबेस्टियन

2
अधिक तेज़ होने के लिए 3 ... आपको फंक राउंड के लिए बदलना चाहिए (tollaces स्थान: Int) -> डबल
FouZ

2
@BenSaufley लेकिन 98.68 दर्ज करने पर भी यह काम नहीं करता है। इस मामले में, मुझे 98.6800003
अलेक्जेंडर खितेव

340

जब मैं प्रिंट करता हूं, तो मैं 1.543 पर इसे कैसे राउंड करूं totalWorkTimeInHours?

दौर के लिए totalWorkTimeInHoursमुद्रण के लिए 3 अंक के लिए, का उपयोग Stringनिर्माता है जो एक लेता हैformat स्ट्रिंग:

print(String(format: "%.3f", totalWorkTimeInHours))

24
वह छंटनी है, गोलाई नहीं
नेत्रदान

33
@ ईयबॉल: वास्तव में, यह दौर है। यह सी प्रिंटफ कार्यक्षमता के समान व्यवहार है, जो अनुरोधित अंकों के लिए गोल है। तो String(format: "%.3f", 1.23489)प्रिंट करता है1.235
zisoft

6
मूल पोस्टर उपयोग करने के लिए एक संख्यात्मक मान की तलाश कर रहा है, न कि प्रदर्शित करने के लिए एक स्ट्रिंग।
pr1001

17
@ pr1001, शायद ऐसा है, लेकिन उस समय स्पष्ट नहीं था और 46 अन्य लोगों ने मेरे उत्तर को उपयोगी पाया है। स्टैक ओवरफ्लो केवल ओपी की मदद करने से ज्यादा है।
टीका

3
अजीब है, यह हर बार 0.00 लौट रहा है।
एरिक एच

254

अपनी आवश्यकताओं के अनुसार, स्विफ्ट 5 के साथ, आप 9 में से एक शैली का चयन कर सकते हैं ताकि एक से एक गोल परिणाम हो सके Double


# 1। का उपयोग करते हुएFloatingPoint rounded()विधि

सबसे सरल मामले में, आप Double rounded()विधि का उपयोग कर सकते हैं ।

let roundedValue1 = (0.6844 * 1000).rounded() / 1000
let roundedValue2 = (0.6849 * 1000).rounded() / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 2। FloatingPoint rounded(_:)विधि का उपयोग करना

let roundedValue1 = (0.6844 * 1000).rounded(.toNearestOrEven) / 1000
let roundedValue2 = (0.6849 * 1000).rounded(.toNearestOrEven) / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 3। डार्विन का उपयोग करनाround फ़ंक्शन

roundडार्विन के माध्यम से फाउंडेशन एक समारोह प्रदान करता है ।

import Foundation

let roundedValue1 = round(0.6844 * 1000) / 1000
let roundedValue2 = round(0.6849 * 1000) / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 4। Doubleडार्विन roundऔर powकार्यों के साथ निर्मित एक विस्तार कस्टम विधि का उपयोग करना

यदि आप पिछले ऑपरेशन को कई बार दोहराना चाहते हैं, तो अपने कोड को फिर से भरना एक अच्छा विचार हो सकता है।

import Foundation

extension Double {
    func roundToDecimal(_ fractionDigits: Int) -> Double {
        let multiplier = pow(10, Double(fractionDigits))
        return Darwin.round(self * multiplier) / multiplier
    }
}

let roundedValue1 = 0.6844.roundToDecimal(3)
let roundedValue2 = 0.6849.roundToDecimal(3)
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 5। NSDecimalNumber rounding(accordingToBehavior:)विधि का उपयोग करना

यदि आवश्यक हो, तो NSDecimalNumberदशमलव संख्याओं को गोल करने के लिए एक क्रिया लेकिन शक्तिशाली समाधान प्रदान करता है।

import Foundation

let scale: Int16 = 3

let behavior = NSDecimalNumberHandler(roundingMode: .plain, scale: scale, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: true)

let roundedValue1 = NSDecimalNumber(value: 0.6844).rounding(accordingToBehavior: behavior)
let roundedValue2 = NSDecimalNumber(value: 0.6849).rounding(accordingToBehavior: behavior)

print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 6। NSDecimalRound(_:_:_:_:)फ़ंक्शन का उपयोग करना

import Foundation

let scale = 3

var value1 = Decimal(0.6844)
var value2 = Decimal(0.6849)

var roundedValue1 = Decimal()
var roundedValue2 = Decimal()

NSDecimalRound(&roundedValue1, &value1, scale, NSDecimalNumber.RoundingMode.plain)
NSDecimalRound(&roundedValue2, &value2, scale, NSDecimalNumber.RoundingMode.plain)

print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 7। का उपयोग करते हुएNSString init(format:arguments:)इनिशियलाइज़र करना

यदि आप NSStringअपने राउंडिंग ऑपरेशन से लौटना चाहते हैं , तो NSStringइनिशलाइज़र का उपयोग करना एक सरल लेकिन कुशल उपाय है।

import Foundation

let roundedValue1 = NSString(format: "%.3f", 0.6844)
let roundedValue2 = NSString(format: "%.3f", 0.6849)
print(roundedValue1) // prints 0.684
print(roundedValue2) // prints 0.685

# 8। String init(format:_:)इनिशियलाइज़र का उपयोग करना

स्विफ्ट के Stringप्रकार को फाउंडेशन की NSStringकक्षा के साथ जोड़ा जाता है । इसलिए, आप Stringअपने राउंडिंग ऑपरेशन से लौटने के लिए निम्नलिखित कोड का उपयोग कर सकते हैं :

import Foundation

let roundedValue1 = String(format: "%.3f", 0.6844)
let roundedValue2 = String(format: "%.3f", 0.6849)
print(roundedValue1) // prints 0.684
print(roundedValue2) // prints 0.685

# 9। का उपयोग करते हुएNumberFormatter

यदि आप String?अपने गोल संचालन से प्राप्त करने की अपेक्षा करते हैं , तो NumberFormatterएक उच्च अनुकूलन समाधान प्रदान करता है।

import Foundation

let formatter = NumberFormatter()
formatter.numberStyle = NumberFormatter.Style.decimal
formatter.roundingMode = NumberFormatter.RoundingMode.halfUp
formatter.maximumFractionDigits = 3

let roundedValue1 = formatter.string(from: 0.6844)
let roundedValue2 = formatter.string(from: 0.6849)
print(String(describing: roundedValue1)) // prints Optional("0.684")
print(String(describing: roundedValue2)) // prints Optional("0.685")

1
बहुत बढ़िया जवाब। मैं # 5 पर सुझाव दे सकता हूं जिसे आप उपयोग करने पर विचार कर सकते हैं Decimal, जो टोल फ्री ब्रिजिड है NSDecimalNumberDecimalकी तरह देशी ऑपरेटरों के लिए स्विफ्ट देशी प्रकार और प्रस्तावों और अधिक सुरुचिपूर्ण समर्थन है +, -आदि
रोब

@Rob मैंने NSDecimalRound(_:_:_:_:)फ़ंक्शन के साथ अपना उत्तर अपडेट किया है। धन्यवाद।
इमानौ पेटिट

# 9 विकल्प का उपयोग करने की गारंटी होगी कि आप निश्चित अंश (सटीक अंकों की संख्या) की उम्मीद करेंगे, दशमलव संख्या 43.12345 और अंश = 6 बताते हैं, आपको 43.123450
अल्मास आदिलबेक

1
@ImanouPetit इसे पोस्ट करने के लिए धन्यवाद। मैं एक-दो एक्सटेंशन कर सकता हूं।
एड्रियन

मैं दुखी हूं NumberFormatterअंतिम विकल्प है जबकि यह उपयोगकर्ताओं के लिए नंबर पेश करने वाला पहला होना चाहिए। कोई अन्य विधि ठीक से स्थानीयकृत संख्या उत्पन्न नहीं करती है।
सुल्तान


50

यह पूरी तरह से काम करने वाला कोड है

स्विफ्ट 3.0 / 4.0 / 5.0, एक्सकोड 9.0 जीएम / 9.2 और उससे अधिक

let doubleValue : Double = 123.32565254455
self.lblValue.text = String(format:"%.f", doubleValue)
print(self.lblValue.text)

आउटपुट - 123

let doubleValue : Double = 123.32565254455
self.lblValue_1.text = String(format:"%.1f", doubleValue)
print(self.lblValue_1.text)

आउटपुट - 123.3

let doubleValue : Double = 123.32565254455
self.lblValue_2.text = String(format:"%.2f", doubleValue)
print(self.lblValue_2.text)

आउटपुट - 123.33

let doubleValue : Double = 123.32565254455
self.lblValue_3.text = String(format:"%.3f", doubleValue)
print(self.lblValue_3.text)

आउटपुट - 123.326


1
एक लाइन?, 3 लाइनों की तरह लगता है;)
पेट्टर फ्रीबर्ग

आप स्ट्रिंग्स का उपयोग करके चीजों की गणना नहीं कर सकते हैं, मुझे इसका सही उत्तर नहीं लगता क्योंकि इसकी केवल प्रदर्शित करने के लिए है।
JBarros35

25

योगी के जवाब पर, यहाँ एक स्विफ्ट फ़ंक्शन है जो काम करता है:

func roundToPlaces(value:Double, places:Int) -> Double {
    let divisor = pow(10.0, Double(places))
    return round(value * divisor) / divisor
}

20

स्विफ्ट 3.0 और एक्सकोड 8.0 में:

extension Double {
    func roundTo(places: Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return (self * divisor).rounded() / divisor
    }
}

इस तरह इस एक्सटेंशन का उपयोग करें:

let doubleValue = 3.567
let roundedValue = doubleValue.roundTo(places: 2)
print(roundedValue) // prints 3.56

19

स्विफ्ट 4, एक्सकोड 10

yourLabel.text =  String(format:"%.2f", yourDecimalValue)

1
मैं नीचे नहीं गया, लेकिन मुझे लगता है कि इसका कारण यह हो सकता है क्योंकि यह एक संख्या का एक स्ट्रिंग प्रतिनिधित्व कर रहा है, न कि संख्या। जो ठीक है अगर आपको इसकी आवश्यकता है, लेकिन आप आगे के उपयोग के लिए संख्या को स्वयं बंद कर सकते हैं। ओपी ने कहा "जब मैं प्रिंट करता हूं" तो मुझे लगता है कि यह इस मामले में एक स्वीकार्य, आसान और साफ समाधान है।
बेन स्टाहल

1
उत्तम। एक लाइन समाधान। मुझे अपने लेबल में दशमलव मानों को स्ट्रिंग्स के रूप में दिखाने की आवश्यकता थी।
जीशान

18

दशमलव के बाद विशिष्ट अंकों के लिए कोड है:

var a = 1.543240952039
var roundedString = String(format: "%.3f", a)

यहां% .3f इस नंबर को 3 दशमलव स्थानों पर गोल करने के लिए स्विफ्ट बताता है। और यदि आप डबल नंबर चाहते हैं, तो आप इस कोड को देख सकते हैं:

// स्ट्रिंग टू डबल

var roundedString = Double(String(format: "%.3f", b))


14

फाउंडेशन डार्विन पुस्तकालय में बनाया का उपयोग करें

स्विफ्ट 3

extension Double {
    func round(to places: Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return Darwin.round(self * divisor) / divisor
    }
}

उपयोग:

let number:Double = 12.987654321
print(number.round(to: 3)) 

आउटपुट: 12.988


9

एक आसान तरीका टाइप डबल के विस्तार का उपयोग हो सकता है

extension Double {
    var roundTo2f: Double {return Double(round(100 *self)/100)  }
    var roundTo3f: Double {return Double(round(1000*self)/1000) }
}

उपयोग:

let regularPie:  Double = 3.14159
var smallerPie:  Double = regularPie.roundTo3f  // results 3.142
var smallestPie: Double = regularPie.roundTo2f  // results 3.14

9

यदि आप Doubleमानों को गोल करना चाहते हैं, Decimalतो आप स्विफ्ट का उपयोग करना चाह सकते हैं ताकि आप इन गोल मानों के साथ गणित करने का प्रयास करते समय कोई त्रुटि न प्रस्तुत कर सकें। यदि आप उपयोग करते हैं Decimal, तो यह उस गोल फ़्लोटिंग पॉइंट मान के दशमलव मानों का सही प्रतिनिधित्व कर सकता है।

तो आप कर सकते हैं:

extension Double {
    /// Convert `Double` to `Decimal`, rounding it to `scale` decimal places.
    ///
    /// - Parameters:
    ///   - scale: How many decimal places to round to. Defaults to `0`.
    ///   - mode:  The preferred rounding mode. Defaults to `.plain`.
    /// - Returns: The rounded `Decimal` value.

    func roundedDecimal(to scale: Int = 0, mode: NSDecimalNumber.RoundingMode = .plain) -> Decimal {
        var decimalValue = Decimal(self)
        var result = Decimal()
        NSDecimalRound(&result, &decimalValue, scale, mode)
        return result
    }
}

फिर, आप इस Decimalतरह गोल मूल्य प्राप्त कर सकते हैं :

let foo = 427.3000000002
let value = foo.roundedDecimal(to: 2) // results in 427.30

और यदि आप इसे निर्दिष्ट स्थानों की संख्या के साथ प्रदर्शित करना चाहते हैं (साथ ही उपयोगकर्ता के वर्तमान लोकेल के लिए स्ट्रिंग को स्थानीय करें), तो आप इसका उपयोग कर सकते हैं NumberFormatter:

let formatter = NumberFormatter()
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2

if let string = formatter.string(for: value) {
    print(string)
}

2
अब तक का सबसे अच्छा जवाब।
कोडेटर्ड

(4.81).roundedDecimal(to: 2, mode: .down)Decimal(string: self.description)!decimalValue
४. --१ के

1
@ vk.edward.li - हां, किसी को दशमलव को ऊपर / नीचे गोल करने के बारे में सावधान रहना चाहिए, क्योंकि 4.81 जैसे मूल्यों का सही प्रतिनिधित्व नहीं किया जा सकता है Double(यह बन जाता है 4.8099999999999996)। लेकिन मैं उपयोग करने के खिलाफ सलाह descriptionदूंगा (क्योंकि यह जिस दौर में काम करता है वह दस्तावेज नहीं है और परिवर्तन के अधीन है)। क्या तुम सच में दशमलव सटीक गणित कर रही किया जाना चाहते हैं, तो आप से बचना चाहिए Doubleपूरी तरह से और बदले का उपयोग करना चाहिए Decimalसीधे (जैसे Decimal(sign: .plus, exponent: -2, significand: 481)या Decimal(string: "4.81")लेकिन उपयोग नहीं करते। description
रोब

@ रब आमतौर पर "4.81" का स्ट्रिंग मान प्राप्त करना असंभव है यदि इसे डबल के रूप में संग्रहीत किया जाता है, तो आपको पहले से खोई हुई परिशुद्धता को ठीक करने के लिए स्वयं (स्वनिर्धारित Grisu2 एल्गोरिथ्म) का उपयोग करना होगा
vk.edward .li

मैं आपकी बात समझता हूं। मैं सिर्फ आपके समाधान से असहमत हूं। descriptionविधि का गोल व्यवहार न तो प्रलेखित है और न ही गारंटी है। इसके अलावा, यह स्थानीयकृत नहीं है। IMHO, यह descriptionलॉगिंग उद्देश्यों के अलावा और कुछ के लिए उपयोग करने के लिए एक गलती है। मैं या तो पूरी तरह Decimalसे उपयोग करने Doubleसे बचता हूं , या केवल एक अलग गोलाई मोड का उपयोग करता हूं । या, यदि आपको अपनी स्थानीय विधि का उपयोग करना है जो ग्रिसू-शैली एल्गोरिथ्म का उपयोग करता है (लेकिन यह अनावश्यक लगता है जब आपको पता है कि आप कितने दशमलव स्थानों को गोल करना चाहते हैं)। लेकिन मैं इस सहायक व्यवहार पर भरोसा करने से बचता हूँ description
रोब

8

यह एक प्रकार का एक लंबा हल है, जो आपकी ज़रूरतों के अधिक जटिल होने पर काम आ सकता है। आप स्विफ्ट में एक नंबर फॉर्मेटर का उपयोग कर सकते हैं।

let numberFormatter: NSNumberFormatter = {
    let nf = NSNumberFormatter()
    nf.numberStyle = .DecimalStyle
    nf.minimumFractionDigits = 0
    nf.maximumFractionDigits = 1
    return nf
}()

मान लीजिए कि आपका वेरिएबल आप प्रिंट करना चाहते हैं

var printVar = 3.567

यह सुनिश्चित करेगा कि यह वांछित प्रारूप में लौटा है:

numberFormatter.StringFromNumber(printVar)

यहाँ परिणाम इस प्रकार "3.6" (गोल) होगा। हालांकि यह सबसे अधिक आर्थिक समाधान नहीं है, मैं इसे देता हूं क्योंकि ओपी ने मुद्रण का उल्लेख किया है (जिस स्थिति में स्ट्रिंग अवांछनीय नहीं है), और क्योंकि यह वर्ग कई मापदंडों को सेट करने की अनुमति देता है।


1
एक त्वरित ध्यान दें कि कोई भी फॉर्मेट प्रोग्रामर रूप से महंगा है, जिससे यह उन कार्यों के लिए बीमार हो जाता है जिन्हें जल्दी या दोहराए जाने की आवश्यकता होती है।
जोनाथन थॉर्नटन

7

मै इस्तेमाल करूंगा

print(String(format: "%.3f", totalWorkTimeInHours))

और .3f किसी भी संख्या में दशमलव संख्या की जरूरत है


वह 3 अंकों के साथ प्रिंट करना चाहता था, इसे NSTimeInterval में प्राप्त नहीं करना था
मोहसिन होसैन ने

7

कोई एक:

  1. का उपयोग कर String(format:):

    • प्रारूप विनिर्देशक के साथ टाइपकास्ट Doubleकरें और फिर वापस जाएंString%.3fDouble

      Double(String(format: "%.3f", 10.123546789))!
    • या DoubleN- दशमलव स्थानों को संभालने के लिए विस्तारित करें:

      extension Double {
          func rounded(toDecimalPlaces n: Int) -> Double {
              return Double(String(format: "%.\(n)f", self))!
          }
      }
  2. गणना द्वारा

    • 10 ^ 3 के साथ गुणा करें, इसे गोल करें और फिर 10 ^ 3 से विभाजित करें ...

      (1000 * 10.123546789).rounded()/1000
    • या DoubleN- दशमलव स्थानों को संभालने के लिए विस्तारित करें:

      extension Double {    
          func rounded(toDecimalPlaces n: Int) -> Double {
              let multiplier = pow(10, Double(n))
              return (multiplier * self).rounded()/multiplier
          }
      }

6

यह एन महत्वपूर्ण अंकों के लिए गोलाई का अधिक लचीला एल्गोरिथ्म है

स्विफ्ट 3 समाधान

extension Double {
// Rounds the double to 'places' significant digits
  func roundTo(places:Int) -> Double {
    guard self != 0.0 else {
        return 0
    }
    let divisor = pow(10.0, Double(places) - ceil(log10(fabs(self))))
    return (self * divisor).rounded() / divisor
  }
}


// Double(0.123456789).roundTo(places: 2) = 0.12
// Double(1.23456789).roundTo(places: 2) = 1.2
// Double(1234.56789).roundTo(places: 2) = 1200

6

दोहरी संपत्ति को प्रारूपित करने का सबसे अच्छा तरीका Apple पूर्वनिर्धारित तरीकों का उपयोग करना है।

mutating func round(_ rule: FloatingPointRoundingRule)

FloatingPointRoundingRule एक एनम है जिसमें निम्नलिखित संभावनाएँ हैं

गणना के मामले:

मामला दूर निकटतम निकटतम मूल्य के लिए गोल जिसका परिमाण स्रोत के बराबर या उससे अधिक है।

केस नीचे निकटतम निकटतम मान के लिए जो स्रोत से कम या बराबर है।

मामले में toNearestOrAwayFromZero निकटतम अनुमत मूल्य पर गोल; यदि दो मूल्य समान रूप से पास हैं, तो अधिक परिमाण वाले व्यक्ति को चुना जाता है।

निकटतम अप्रत्यक्ष मान के मामले में toNearestOrEven राउंड; यदि दो मूल्य समान रूप से पास हैं, तो भी एक को चुना जाता है।

मामला राउंड की ओर निकटतम अनुमत मान के जिसका परिमाण स्रोत से कम या उसके बराबर है।

स्रोत के बराबर या उससे अधिक के निकटतम अनुमत मान के लिए राउंड अप केस

var aNumber : Double = 5.2
aNumber.rounded(.up) // 6.0

6

दशमलव
सं। की x संख्या के लिए एक डबल मान राउंड । दशमलव के बाद अंकों का

var x = 1.5657676754
var y = (x*10000).rounded()/10000
print(y)  // 1.5658 

var x = 1.5657676754 
var y = (x*100).rounded()/100
print(y)  // 1.57 

var x = 1.5657676754
var y = (x*10).rounded()/10
print(y)  // 1.6

इस कोड में क्या हो रहा है? तीन उदाहरण क्या प्रदर्शित करते हैं?
रेने

कोड केवल उत्तर सहायक नहीं हैं, कृपया यह समझाने का प्रयास करें कि इनमें से प्रत्येक उदाहरण क्या करता है।
मोए

5

स्विफ्ट नहीं, लेकिन मुझे यकीन है कि आपको यह विचार मिलेगा।

pow10np = pow(10,num_places);
val = round(val*pow10np) / pow10np;

4

यह स्विफ्ट 5 में काम करने लगता है।

काफी आश्चर्य की बात है कि पहले से ही इसके लिए कोई मानक कार्य नहीं है।

// गोलाई के साथ डबल-एन-दशमलव स्थानों का ट्रंकेशन

extension Double {

    func truncate(to places: Int) -> Double {
    return Double(Int((pow(10, Double(places)) * self).rounded())) / pow(10, Double(places))
    }

}

2

आप इस एक्सटेंशन को जोड़ सकते हैं:

extension Double {
    var clean: String {
        return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(format: "%.2f", self)
    }
}

और इसे इस तरह से कॉल करें:

let ex: Double = 10.123546789
print(ex.clean) // 10.12

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

2

फ्लोट अपूर्णताओं से बचने के लिए दशमलव का उपयोग करें

extension Float {
    func rounded(rule: NSDecimalNumber.RoundingMode, scale: Int) -> Float {
        var result: Decimal = 0
        var decimalSelf = NSNumber(value: self).decimalValue
        NSDecimalRound(&result, &decimalSelf, scale, rule)
        return (result as NSNumber).floatValue
    }
}

पूर्व।
स्केल के साथ फ्लोट का उपयोग करते समय 1075.58 राउंड से 1075.57 और स्केल के साथ
डेसीमल का उपयोग करते समय 1075.58 के लिए 1075.58 राउंड: 2 और।


1

मैंने यह सोचकर पाया कि क्या उपयोगकर्ता के इनपुट को सही करना संभव है। यह है कि अगर वे एक डॉलर की राशि के लिए दो के बजाय तीन दशमलव में प्रवेश करते हैं। 1.11 के बजाय 1.111 कह सकते हैं कि आप इसे गोल करके ठीक कर सकते हैं? कई कारणों का जवाब नहीं है! कुछ भी पैसे के साथ यानी 0.001 पर अंततः एक वास्तविक चेकबुक में समस्या पैदा होगी।

अवधि के बाद बहुत अधिक मूल्यों के लिए उपयोगकर्ताओं के इनपुट की जांच करने के लिए यहां एक फ़ंक्शन है। लेकिन जो 1., 1.1 और 1.11 की अनुमति देगा।

यह माना जाता है कि एक स्ट्रिंग से डबल में सफल रूपांतरण के लिए मूल्य पहले ही जांचा जा चुका है।

//func need to be where transactionAmount.text is in scope

func checkDoublesForOnlyTwoDecimalsOrLess()->Bool{


    var theTransactionCharacterMinusThree: Character = "A"
    var theTransactionCharacterMinusTwo: Character = "A"
    var theTransactionCharacterMinusOne: Character = "A"

    var result = false

    var periodCharacter:Character = "."


    var myCopyString = transactionAmount.text!

    if myCopyString.containsString(".") {

         if( myCopyString.characters.count >= 3){
                        theTransactionCharacterMinusThree = myCopyString[myCopyString.endIndex.advancedBy(-3)]
         }

        if( myCopyString.characters.count >= 2){
            theTransactionCharacterMinusTwo = myCopyString[myCopyString.endIndex.advancedBy(-2)]
        }

        if( myCopyString.characters.count > 1){
            theTransactionCharacterMinusOne = myCopyString[myCopyString.endIndex.advancedBy(-1)]
        }


          if  theTransactionCharacterMinusThree  == periodCharacter {

                            result = true
          }


        if theTransactionCharacterMinusTwo == periodCharacter {

            result = true
        }



        if theTransactionCharacterMinusOne == periodCharacter {

            result = true
        }

    }else {

        //if there is no period and it is a valid double it is good          
        result = true

    }

    return result


}

1
//find the distance between two points
let coordinateSource = CLLocation(latitude: 30.7717625, longitude:76.5741449 )
let coordinateDestination = CLLocation(latitude: 29.9810859, longitude: 76.5663599)
let distanceInMeters = coordinateSource.distance(from: coordinateDestination)
let valueInKms = distanceInMeters/1000
let preciseValueUptoThreeDigit = Double(round(1000*valueInKms)/1000)
self.lblTotalDistance.text = "Distance is : \(preciseValueUptoThreeDigit) kms"


1

यहां स्विफ्टयूआई के लिए एक है यदि आपको संख्या मूल्य के साथ एक पाठ तत्व की आवश्यकता है।

struct RoundedDigitText : View {
    let digits : Int
    let number : Double

    var body : some View {
        Text(String(format: "%.\(digits)f", number))
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.