स्विफ्ट में निकटतम इंट से दोगुना गोल कैसे करें?


170

मैं विकास दर ( Double) का एक कैलकुलेटर बनाने की कोशिश कर रहा हूं जो परिणाम को निकटतम पूर्णांक तक ले जाएगा और वहां से पुनर्गणना करेगा, जैसे कि:

let firstUsers = 10.0
let growth = 0.1
var users = firstUsers
var week = 0


while users < 14 {
    println("week \(week) has \(users) users")
    users += users * growth
    week += 1
}

लेकिन मैं अब तक असमर्थ रहा हूं।

EDIT I थोड़े ने इसे पसंद किया:

var firstUsers = 10.0
let growth = 0.1
var users:Int = Int(firstUsers)
var week = 0


while users <= 14 {
    println("week \(week) has \(users) users")
    firstUsers += firstUsers * growth
    users = Int(firstUsers)
    week += 1
}

हालांकि मुझे कोई आपत्ति नहीं है कि यह हमेशा गोल होता है, मुझे यह पसंद नहीं है क्योंकि इसे firstUsersएक चर बनना था और पूरे कार्यक्रम (अगली गणना करने के लिए) में बदलना था, जो मैं ऐसा नहीं करना चाहता।

जवाबों:


253

वहाँ एक है roundमें उपलब्ध Foundationपुस्तकालय (यह वास्तव में में है Darwin, लेकिन Foundationआयात Darwinऔर ज्यादातर समय आप का उपयोग करना चाहेंगे Foundationउपयोग करने के बजाय Darwinसीधे)

import Foundation

users = round(users)

खेल के मैदान में अपना कोड चलाना और फिर कॉल करना:

print(round(users))

आउटपुट:

15.0

round()दशमलव स्थान के >= .5नीचे और नीचे होने पर हमेशा गोल होता है < .5(मानक गोलाई)। आप floor()राउंडिंग ceil()को बल देने के लिए , और राउंडिंग को बल देने के लिए उपयोग कर सकते हैं ।

आप दौर के लिए एक विशिष्ट जगह पर है, तो आप से गुणा की जरूरत है pow(10.0, number of places), roundहै, और फिर से विभाजित pow(10, number of places):

2 दशमलव स्थानों पर गोल:

let numberOfPlaces = 2.0
let multiplier = pow(10.0, numberOfPlaces)
let num = 10.12345
let rounded = round(num * multiplier) / multiplier
print(rounded)

आउटपुट:

10.12

नोट: फ्लोटिंग पॉइंट गणित के काम करने के तरीके के कारण, roundedहमेशा पूरी तरह से सटीक नहीं हो सकते हैं। राउंडिंग के अधिक सन्निकटन के बारे में सोचना सबसे अच्छा है। यदि आप प्रदर्शन उद्देश्यों के लिए ऐसा कर रहे हैं, तो इसे राउंड करने के लिए गणित का उपयोग करने के बजाय संख्या को प्रारूपित करने के लिए स्ट्रिंग स्वरूपण का उपयोग करना बेहतर है।


हम्म pow()दुर्भाग्य से एक खेल के मैदान में उपलब्ध नहीं है
MrBr

1
@MrBr, pow()डार्विन पुस्तकालय में परिभाषित किया गया है, इसलिए आपको import Darwinसबसे पहले ( import Foundationया import Cocoaया import UIKit, जो अंत में डार्विन के आयात को समाप्त करना होगा) की आवश्यकता है।
माइक एस

54
वहाँ भी है lround()जो एक रिटर्न Int
मार्टिन आर

1
" round()दशमलव स्थान> = = .5 और नीचे होने पर हमेशा गोल होता है जब <.5 (मानक गोलाई) होता है।" सिवाय जब यह नहीं है। round(-16.5)रिटर्न -17, नहीं -16। क्या यह एक बग है?
डैनियल टी।

1
@DanielT। - बग नहीं। यह निकटतम बड़ी ऋणात्मक संख्या तक चक्कर लगा रहा है। इसके बारे में इस तरह सोचें, +16.5 से +17 शून्य से 0.5 आगे बढ़ रहा है। इसका मतलब है कि -16.5 से -17 भी शून्य से 0.5 अधिक दूर है। छत विपरीत होगी, +16.5 से +16 शून्य के करीब 0.5 और -16.5 से -16 भी शून्य के करीब 0.5 है
adougies

139

निकटतम पूर्णांक के लिए एक डबल चक्कर लगाने के लिए, बस का उपयोग करें round()

var x = 3.7
x.round() // x = 4.0

यदि आप मूल मूल्य को संशोधित नहीं करना चाहते हैं, तो उपयोग करें rounded():

let x = 3.7
let y = x.rounded() // y = 4.0. x = 3.7

जैसा कि कोई उम्मीद कर सकता है ( या नहीं कर सकता है ), एक नंबर की तरह 3.5गोल है और एक नंबर की तरह -3.5गोल है। यदि आपको उससे अलग राउंडिंग व्यवहार की आवश्यकता है, तो आप राउंडिंग नियमों में से एक का उपयोग कर सकते हैं । उदाहरण के लिए:

var x = 3.7
x.round(.towardZero) // 3.0

यदि आपको एक वास्तविक की आवश्यकता है, Intतो बस इसे एक को कास्ट करें (लेकिन केवल यदि आप निश्चित हैं कि डबल से अधिक नहीं होगा Int.max):

let myInt = Int(myDouble.rounded())

टिप्पणियाँ

  • यह उत्तर पूरी तरह से फिर से लिखा गया है। मेरा पुराना जवाब सी गणित कार्यों की तरह से निपटा round, lround, floor, और ceil। हालाँकि, अब जब स्विफ्ट में यह कार्यक्षमता है, तो मैं अब उन कार्यों का उपयोग करने की अनुशंसा नहीं कर सकता। यह मुझे इंगित करने के लिए @ डीडी के लिए धन्यवाद। की जाँच करें @ dfri उत्तम जवाब यहाँ । मैं भी के लिए कुछ इसी तरह किया था एक गोलाईCGFloat

Int (myDouble.rounded ()) <--- यह वास्तव में एक अपवाद फेंक सकता है यदि डबल Int फिट नहीं होता है
Toad

@ क्या आप निश्चित हैं? मैं उस दस्तावेज में नहीं देखता ।
सुरगाछ

मैंने बस इस सटीक मुद्दे के साथ उत्पादन में एक दुर्घटना को हल किया। लेकिन अगर मैं गलत था और यह दुर्घटनाग्रस्त नहीं होगा, तब भी यह अभी भी युगल के लिए अप्रत्याशित परिणाम देगा
टॉड

1
@ लोड, सही, अच्छी बात, धन्यवाद। मैंने जवाब में एक नोट जोड़ा।
सुरगाच

85

स्विफ्ट 3 और 4 - प्रोटोकॉल rounded(_:)में ब्लूप्रिंट के रूप में विधि का FloatingPointउपयोग करना

FloatingPointप्रोटोकॉल (जो जैसे को Doubleऔर Floatअनुरूप) ब्लूप्रिंट rounded(_:)विधि

func rounded(_ rule: FloatingPointRoundingRule) -> Self

जहां FloatingPointRoundingRuleकई अलग-अलग गोलाई नियमों की गणना करने वाली एक एनुम है:

case awayFromZero

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

case down

निकटतम अनुमत मान पर गोल जो स्रोत से कम या उसके बराबर है।

case toNearestOrAwayFromZero

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

case toNearestOrEven

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

case towardZero

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

case up

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

हम अभ्यास में इन विभिन्न दौर विकल्पों को दिखाने के लिए @ सुरगच के उत्कृष्ट उत्तर से लोगों के लिए समान उदाहरण का उपयोग करते हैं।

.awayFromZero

निकटतम अनुमत मूल्य का गोल जिसका परिमाण स्रोत से अधिक या उसके बराबर है; कोई सी कार्यों में बराबर प्रत्यक्ष, इस का उपयोग करता है के रूप में, सशर्त के हस्ताक्षर पर self, ceilया floor, के सकारात्मक और नकारात्मक मूल्यों के लिए self, क्रमशः।

3.000.rounded(.awayFromZero) // 3.0
3.001.rounded(.awayFromZero) // 4.0
3.999.rounded(.awayFromZero) // 4.0

(-3.000).rounded(.awayFromZero) // -3.0
(-3.001).rounded(.awayFromZero) // -4.0
(-3.999).rounded(.awayFromZero) // -4.0

.down

C floorफ़ंक्शन के बराबर ।

3.000.rounded(.down) // 3.0
3.001.rounded(.down) // 3.0
3.999.rounded(.down) // 3.0

(-3.000).rounded(.down) // -3.0
(-3.001).rounded(.down) // -4.0
(-3.999).rounded(.down) // -4.0

.toNearestOrAwayFromZero

C roundफ़ंक्शन के बराबर ।

3.000.rounded(.toNearestOrAwayFromZero) // 3.0
3.001.rounded(.toNearestOrAwayFromZero) // 3.0
3.499.rounded(.toNearestOrAwayFromZero) // 3.0
3.500.rounded(.toNearestOrAwayFromZero) // 4.0
3.999.rounded(.toNearestOrAwayFromZero) // 4.0

(-3.000).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.001).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.499).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.500).rounded(.toNearestOrAwayFromZero) // -4.0
(-3.999).rounded(.toNearestOrAwayFromZero) // -4.0

यह तर्क नियम शून्य तर्क rounded()विधि का उपयोग करके भी एक्सेस किया जा सकता है ।

3.000.rounded() // 3.0
// ...

(-3.000).rounded() // -3.0
// ...

.toNearestOrEven

निकटतम अनुमत मूल्य पर गोल; यदि दो मूल्य समान रूप से पास हैं, तो भी एक को चुना जाता है; C rint(/ बहुत समान nearbyint) फ़ंक्शन के बराबर ।

3.499.rounded(.toNearestOrEven) // 3.0
3.500.rounded(.toNearestOrEven) // 4.0 (up to even)
3.501.rounded(.toNearestOrEven) // 4.0

4.499.rounded(.toNearestOrEven) // 4.0
4.500.rounded(.toNearestOrEven) // 4.0 (down to even)
4.501.rounded(.toNearestOrEven) // 5.0 (up to nearest)

.towardZero

C truncफ़ंक्शन के बराबर ।

3.000.rounded(.towardZero) // 3.0
3.001.rounded(.towardZero) // 3.0
3.999.rounded(.towardZero) // 3.0

(-3.000).rounded(.towardZero) // 3.0
(-3.001).rounded(.towardZero) // 3.0
(-3.999).rounded(.towardZero) // 3.0

यदि गोलाई का उद्देश्य पूर्णांक के साथ काम करने के लिए तैयार करना है (जैसे Intकि FloatPointगोलाई के बाद आरंभीकरण द्वारा उपयोग करना), तो हम बस इस तथ्य का उपयोग कर सकते हैं कि जब Intएक Double(या Floatआदि) का उपयोग करते हुए , दशमलव भाग को छोटा कर दिया जाएगा।

Int(3.000) // 3
Int(3.001) // 3
Int(3.999) // 3

Int(-3.000) // -3
Int(-3.001) // -3
Int(-3.999) // -3

.up

C ceilफ़ंक्शन के बराबर ।

3.000.rounded(.up) // 3.0
3.001.rounded(.up) // 4.0
3.999.rounded(.up) // 4.0

(-3.000).rounded(.up) // 3.0
(-3.001).rounded(.up) // 3.0
(-3.999).rounded(.up) // 3.0

परिशिष्ट: FloatingPointविभिन्न FloatingPointRoundingRuleनियमों के लिए सी फ़ंक्शन तुल्यता को सत्यापित करने के लिए स्रोत कोड पर जाकर

यदि हम चाहें, तो हम FloatingPointप्रोटोकॉल के लिए स्रोत कोड पर एक नज़र डाल सकते हैं ताकि सार्वजनिक FloatingPointRoundingRuleनियमों के सी फ़ंक्शन समकक्षों को सीधे देखा जा सके ।

से तेज / stdlib / सार्वजनिक / कोर / FloatingPoint.swift.gyb हम देखते हैं के डिफ़ॉल्ट कार्यान्वयन कि rounded(_:)विधि हमें परिवर्तनशील का बना देता है round(_:)विधि:

public func rounded(_ rule: FloatingPointRoundingRule) -> Self {
    var lhs = self
    lhs.round(rule)
    return lhs
}

से तेज / stdlib / सार्वजनिक / कोर / FloatingPointTypes.swift.gyb हम के डिफ़ॉल्ट कार्यान्वयन लगता है round(_:), जिसमें बीच तुल्यता FloatingPointRoundingRuleनियमों और सी कार्यों गोलाई स्पष्ट है:

public mutating func round(_ rule: FloatingPointRoundingRule) {
    switch rule {
    case .toNearestOrAwayFromZero:
        _value = Builtin.int_round_FPIEEE${bits}(_value)
    case .toNearestOrEven:
        _value = Builtin.int_rint_FPIEEE${bits}(_value)
    case .towardZero:
        _value = Builtin.int_trunc_FPIEEE${bits}(_value)
    case .awayFromZero:
        if sign == .minus {
            _value = Builtin.int_floor_FPIEEE${bits}(_value)
        }
        else {
            _value = Builtin.int_ceil_FPIEEE${bits}(_value)
        }
    case .up:
        _value = Builtin.int_ceil_FPIEEE${bits}(_value)
    case .down:
        _value = Builtin.int_floor_FPIEEE${bits}(_value)
    }
}

प्रॉम्प्ट के लिए @iosMentalist धन्यवाद, मैंने उत्तर का शीर्षक अपडेट कर दिया है।
डॉग

अगर मुझे कोई समीकरण चाहिए, जैसे 3.0 = 3, 3.1 = 3.5, 3.4 = 3.5, 3.6 = 4, 3.9 - 4
PJR

6
**In Swift**

var a = 14.123456789
var b = 14.123456789
var c = 14.123456789
var d = 14.123456789
var e = 14.123456789
var f = 14.123456789

a.rounded(.up)                      //15
b.rounded(.down)                    //14
c.rounded(.awayFromZero)            //15
d.rounded(.towardZero)              //14
e.rounded(.toNearestOrAwayFromZero) //14
f.rounded(.toNearestOrEven)         //14

6

स्विफ्ट 3: यदि आप एक निश्चित अंकों की संख्या के लिए राउंड करना चाहते हैं जैसे 5.678434 -> 5.68 आप गुणा के साथ केवल राउंड () या राउंडफ () फ़ंक्शन को जोड़ सकते हैं:

let value:Float = 5.678434
let roundedValue = roundf(value * 100) / 100
print(roundedValue) //5.68

4

आप स्विफ्ट 3 में फ्लोटिंगपॉइंट का विस्तार भी कर सकते हैं:

extension FloatingPoint {
    func rounded(to n: Int) -> Self {
        let n = Self(n)
        return (self / n).rounded() * n

    }
}

324.0.rounded(to: 5)   // 325

क्या आप इसे समझा सकते हैं? क्या Selfमतलब है?
JZAU

@ जैकी सेल्फ क्लास फ्लोटिंगपॉइंट को संदर्भित करता है जबकि सेल्फ उस क्लास के उदाहरण को संदर्भित करता है।
जॉर्ज याकूब

@GeorgeYacoub Self उस प्रकार को संदर्भित करता है जो फ़्लोटिंग पॉइंट के अनुरूप होता है जिसे बढ़ाया जा रहा है (उस नमूना उपयोग में एक डबल है) लेकिन वे संरचनाएं हैं, न कि कक्षाएं
लियो डबस

2

स्विफ्ट 3

var myNum = 8.09
myNum.rounded() // result = 8 and leaves myNum unmodified

अच्छा लगा। मैं इसके बारे में पहले नहीं जानता था। एक नोट: myNum.rounded()नहीं बदलता है myNum, लेकिन myNum.round()करता है।
सूर्याग

@ अनुराग, मैंने आपकी टिप्पणी को दर्शाने के लिए उत्तर संपादित किया है।
आदिल हुसैन

0

आप यह भी जांच सकते हैं कि किसी मान को इंट में बदलने की कोशिश करने से पहले डबल अधिकतम मान से अधिक है या नहीं।

let number = Double.infinity
if number >= Double(integerLiteral: Int64.max) {
  let rounded = Int.max
} else {
  let rounded = Int(number.rounded())
}

-1

एक बहुत ही आसान समाधान मेरे लिए काम किया:

  if (62 % 50 != 0) {
      var number = 62 / 50 + 1 // adding 1 is doing the actual "round up"
  }

संख्या में मान 2 होता है

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