কীভাবে দ্রুততম নিকটতম আইটি থেকে একটি ডাবলকে গোল করবেন?


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
}

তবে আমি এতক্ষণ অক্ষম হয়েছি

আমি এটিকে সম্পাদনা করুন এটিকে পছন্দ করুন:

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উপলভ্য রয়েছে (এটি আসলে রয়েছে তবে আমদানি হয় এবং বেশিরভাগ সময় আপনি সরাসরি ব্যবহারের পরিবর্তে ব্যবহার করতে চান )FoundationDarwinFoundationDarwinFoundationDarwin

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()দুর্ভাগ্যক্রমে হুম কোনও খেলার মাঠে উপলভ্য নয়
মিঃবিআর

1
@MrBr, pow()ডারউইন গ্রন্থাগার সংজ্ঞায়িত তাই আপনি প্রয়োজন import Darwinপ্রথম (বা import Foundationবা import Cocoaবা import UIKit, যার মধ্যে সব অভ্যন্তরীণভাবে ডারউইন আমদানি শেষ)।
মাইক এস

54
এছাড়াও lround()একটি যা ফিরে আসে Int
মার্টিন আর

1
" round()দশমিক স্থানটি যখন = = .5 থাকে এবং নীচে <.5 (স্ট্যান্ডার্ড রাউন্ডিং) হয় তখন সর্বদা গোল হয়।" যখন এটি না করে বাদে। round(-16.5)-১ returns, নয় -১ returns প্রদান করে। এটি কি বাগ?
ড্যানিয়েল টি।

1
@DanielT। - একটি বাগ না। এটি নিকটতম বৃহত্তর negativeণাত্মক সংখ্যার উপরে গোলাকার। এভাবে চিন্তা করুন, +16.5 থেকে +17 শূন্য থেকে 0.5 আরও দূরে চলেছে। তার মানে -16.5 থেকে -17 এছাড়াও শূন্য থেকে 0.5 আরও দূরে। সিল বিপরীত হবে, +16.5 থেকে +16 0.5 শূন্যের কাছাকাছি এবং -16.5 থেকে -16 এছাড়াও 0.5-এর সাথে শূন্যের কাছাকাছি
1919

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 মাপসই করা হবে না
ব্যাঙের

@ টাড, আপনি কি নিশ্চিত? আমি নথিতে এটি দেখতে পাচ্ছি না ।
সুরগাচ

আমি ঠিক এই সঠিক সমস্যাটি নিয়ে উত্পাদনের ক্র্যাশ সমাধান করেছি। কিন্তু এমন কি যদি আমি ভুল ছিল এবং তা বিপর্যস্ত না, তারপর এখনও এটি এখনও ডাবলস জন্য অপ্রত্যাশিত ফলাফল দেবে> maxint
ব্যাঙের

1
@ টাড, ডান, ভাল পয়েন্ট, ধন্যবাদ। আমি উত্তরে একটি নোট যুক্ত করেছি।
সুরগাচ

83

সুইফট 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

সি 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

সি 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

নিকটতম অনুমোদিত মান পর্যন্ত বৃত্তাকার; যদি দুটি মান সমানভাবে নিকটে থাকে তবে একটিকেও বেছে নেওয়া হয়; সি 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

সি 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

সি 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বিধিগুলির সাথে সরাসরি সি ফাংশন সমতুল্য দেখতে প্রোটোকলের জন্য উত্স কোডটি একবার দেখতে পারি ।

সুইফ্ট / স্টিডলিব / পাবলিক / কোর / ফ্লোটিংপয়েন্ট.সুইফট.জিবি থেকে আমরা দেখতে পাচ্ছি যে rounded(_:)পদ্ধতির ডিফল্ট প্রয়োগটি আমাদের পরিবর্তনীয় round(_:)পদ্ধতিতে পরিণত করে:

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

সুইফ্ট / স্টিডলিব / পাবলিক / কোর / ফ্লোটিংপয়েন্টটাইপস.সুইফট.জিবি থেকে আমরা এর ডিফল্ট বাস্তবায়ন পাই 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)
    }
}

@ আইওমেনটালিস্ট প্রম্পটের জন্য ধন্যবাদ, আমি উত্তরের শিরোনাম আপডেট করেছি।
dfri

যদি আমি কোনও সমীকরণ চাই, 3.0.০ = 3, 3.1 = 3.5, 3.4 = 3.5, 3.6 = 4, 3.9 - 4
পিজেআর

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মানে কি ?
জেজেডিইউ

@ জ্যাকি সেলফ ক্লাস ফ্লোটিংপয়েন্টকে বোঝায় যেখানে স্ব শ্রেণিটির উদাহরণটিকে বোঝায়।
জর্জি ইয়াকুব

@ জর্জি ইয়াকুব সেল্ফ সেই প্রকারটিকে বোঝায় যেটি ফ্লোটিংপয়েন্টের সাথে সামঞ্জস্য হয় যা বাড়ানো হচ্ছে (সেই নমুনায় ব্যবহারটি দ্বিগুণ) তবে সেগুলি কাঠামো, শ্রেণি নয়
লিও ডাবাস

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 থাকে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.