সুইফট ভাষায় কিছু পূর্ণসংখ্যার পাওয়ার কীভাবে পাবেন?


105

আমি সম্প্রতি দ্রুত শিখছি, তবে আমার একটি প্রাথমিক সমস্যা আছে যা উত্তর খুঁজে পাচ্ছে না

আমি কিছু পেতে চাই

var a:Int = 3
var b:Int = 3 
println( pow(a,b) ) // 27

তবে পাউ ফাংশনটি কেবল ডাবল সংখ্যার সাথেই কাজ করতে পারে, এটি পূর্ণসংখ্যার সাথে কাজ করে না, এবং আমি ডাবল (ক) বা অ্যাডাবল () এর মতো কোনও কিছুর দ্বারা ডাবল ইনটও দিতে পারি না ...

কেন এটি পূর্ণসংখ্যার শক্তি সরবরাহ করে না? এটি অবশ্যই অস্পষ্টতা ছাড়াই একটি পূর্ণসংখ্যা ফেরত দেবে! এবং কেন আমি কোনও সংখ্যার দ্বিগুণ করতে পারি না? এটি কেবল 3 থেকে 3.0 (বা 3.00000 ... যাই হোক না কেন) পরিবর্তন করে

যদি আমি দুটি পূর্ণসংখ্যা পেয়েছি এবং আমি পাওয়ার অপারেশন করতে চাই, আমি কীভাবে এটি সাবলীলভাবে করতে পারি?

ধন্যবাদ!


এই ধরণের ঘোষণাগুলি ভুল
এডগার অ্যার্টিওনিয়ান

বেশিরভাগ ভাষায় এই
ফুক্লভ

4
@ ফুকলভের নোট এই বিষয়ের উপর একটি দুর্দান্ত আলোচনার দিকে ইঙ্গিত করে। আমি এই কারণগুলিতে লিঙ্কটির পাঠ্যটি পরিবর্তন করবো
eharo2

উত্তর:


80

আপনি যদি চান, আপনি এটি করতে একটি ঘোষণা করতে পারে infix operator

// Put this at file level anywhere in your project
infix operator ^^ { associativity left precedence 160 }
func ^^ (radix: Int, power: Int) -> Int {
    return Int(pow(Double(radix), Double(power)))
}

// ...
// Then you can do this...
let i = 2 ^^ 3
// ... or
println("2³ = \(2 ^^ 3)") // Prints 2³ = 8

আমি দুটি কেরেট ব্যবহার করেছি যাতে আপনি এখনও এক্সওআর অপারেটরটি ব্যবহার করতে পারেন ।

সুইফট 3 এর জন্য আপডেট

সুইফ্ট 3 এ "ম্যাজিক নম্বর" precedenceপ্রতিস্থাপন করা হয়েছে precedencegroups:

precedencegroup PowerPrecedence { higherThan: MultiplicationPrecedence }
infix operator ^^ : PowerPrecedence
func ^^ (radix: Int, power: Int) -> Int {
    return Int(pow(Double(radix), Double(power)))
}

// ...
// Then you can do this...
let i2 = 2 ^^ 3
// ... or
print("2³ = \(2 ^^ 3)") // Prints 2³ = 8

সুতরাং আপনি যদি ফ্লোটগুলির জন্য এটি করতে চান, আপনি কি এটি করবেন: ইনফিক্স অপারেটর {}} ফানক ^^ (মূলা: ফ্লোট, পাওয়ার: ফ্লোট) -> ফ্লোট {রিটার্ন ফ্লোট (পাও (ডাবল (রেডিক্স), ডাবল (শক্তি) )))}
পদপা

ফানক ^^ (মূলা: দ্বিগুণ, শক্তি: দ্বিগুণ) -> ডাবল {ফেরত ডাবল (পাও (ডাবল (মূল), ডাবল (শক্তি)))}
পদাপ

4
আমি দেখতে পেয়েছি এটি যেমনটি প্রত্যাশা করেছিল তেমন আচরণ করে না কারণ নজিরটি বন্ধ ছিল। কোনও ক্ষতিকারক অপারেটরের জন্য 160 (যেমন ডেভেলপার.অ্যাপল. com/ লাইব্রেরি / আইস / ডকুমেন্টেশন / সুইফট / কনসেপ্টুয়াল / দেখুন এবং ডেভেলপার.অ্যাপল. com/ লাইবারি / আইওএস / ডকুমেন্টেশন / সুইট / কনসেপ্টুয়াল /…) তে অগ্রাধিকার সেট করুন : infix operator ^^ { precedence 160 } func ^^... এবং আরও
টিম আর্নল্ড

আমি এই সমাধানটি সত্যিই পছন্দ করি তবে সুইফট 3 এর সাথে এটি কার্যকর হয় না। কোন ধারণা কীভাবে এটি কাজ করবে?
ভানিয়া

4
func p(_ b: Bool) -> Double { return b?-1:1 }?
গ্রিমেক্সন

61

আপনার পরিবর্তনশীল ঘোষণাপত্রের সিনট্যাক্স ত্রুটিগুলি ছাড়া অন্যটি, আপনি এটি কীভাবে প্রত্যাশা করেছিলেন ঠিক এটি কাজ করে। সকল আপনাকে যা করতে হবে নিক্ষিপ্ত হবে aএবং bডাবল প্রয়োজন এবং মান পাস pow। তারপরে, আপনি যদি 2 টি ইনট নিয়ে কাজ করছেন এবং আপনি অপারেশনের অন্য দিকে কোনও ফিরে চান, কেবল ইনট এ ফিরে যান।

import Darwin 

let a: Int = 3
let b: Int = 3

let x: Int = Int(pow(Double(a),Double(b)))

এই উত্তরটি ডাবল এবং ইন্টার টাইপের সাথে সবচেয়ে পরিষ্কার।
মিডটাউনগুরু

ধন্যবাদ আমি তাই চাই। পাইথনে, ঠিক 3 ** 3। কখনও কখনও, আমি সুইফ্ট ব্যবহার করে অ্যালগরিদম সমস্যাটি সমাধান করতে হবে, পাইথন ব্যবহারের সাথে তুলনা করা সত্যিই বেদনাদায়ক।
চকজেডবিবি

13

কখনও কখনও, একটি ভোটদান Intএকটি থেকে Doubleএকটি টেকসই সমাধান নয়। কিছু মাত্রায় এই রূপান্তরটিতে নির্ভুলতার ক্ষতি হয়। উদাহরণস্বরূপ, নিম্নলিখিত কোডটি স্বজ্ঞাতভাবে আপনি প্রত্যাশা করতে পারেন তা ফেরত দেয় না।

Double(Int.max - 1) < Double(Int.max) // false!

যদি আপনার উচ্চ মাত্রায় নির্ভুলতার প্রয়োজন হয় এবং নেতিবাচক উদ্বেগকারীদের সম্পর্কে চিন্তা করার দরকার নেই - যা সাধারণত কোনওভাবে পূর্ণসংখ্যার সাথে সমাধান করা যায় না - তবে লেজ-পুনরাবৃত্তির পরিমাণ অনুসারে স্কোয়ারিং-এ-স্কোয়ারিং অ্যালগরিদমের এই প্রয়োগটি আপনার সেরা বাজি। এই এসও উত্তর অনুসারে , এটি "অসম্পূর্ণ ক্রিপ্টোগ্রাফিতে বিশাল সংখ্যার জন্য মডুলার এক্সপেনসিয়েশন করার মানক পদ্ধতি"।

// using Swift 5.0
func pow<T: BinaryInteger>(_ base: T, _ power: T) -> T {
    func expBySq(_ y: T, _ x: T, _ n: T) -> T {
        precondition(n >= 0)
        if n == 0 {
            return y
        } else if n == 1 {
            return y * x
        } else if n.isMultiple(of: 2) {
            return expBySq(y, x * x, n / 2)
        } else { // n is odd
            return expBySq(y * x, x * x, (n - 1) / 2)
        }
    }

    return expBySq(1, base, power) 
}

দ্রষ্টব্য: এই উদাহরণে আমি একটি জেনেরিক ব্যবহার করেছি T: BinaryInteger। এই যাতে আপনি ব্যবহার করতে পারেন Intবা UIntবা অন্য কোন পূর্ণসংখ্যা মত প্রকার।


এবং অবশ্যই আপনি সর্বদা এটি অপারেটর হিসাবে সংজ্ঞায়িত করতে পারেন (আরও জনপ্রিয় উত্তরগুলি হিসাবে বোঝা যায়) বা একটি এক্সটেনশান Intবা আপনি এই জিনিসগুলিকে এই ফ্রি ফাংশন হিসাবে কল করতে পারেন - যা আপনার হৃদয় যা ইচ্ছা তা করে।
mklbtz

দেখে মনে হচ্ছে, এই সমাধানটি স্ট্যাকওভারফ্লো ব্যতিক্রমের দিকে পরিচালিত করে
ভায়াচ্লাভ

11

আপনি যদি সত্যিই 'কেবলমাত্র' কেবলমাত্রায় প্রয়োগ করতে চান এবং / থেকে বাধ্য করতে চান নাDouble , আপনাকে এটি বাস্তবায়ন করতে হবে। এখানে একটি তুচ্ছ বাস্তবায়ন; দ্রুত অ্যালগরিদম আছে তবে এটি কাজ করবে:

func pow (_ base:Int, _ power:UInt) -> Int {
  var answer : Int = 1
  for _ in 0..<power { answer *= base }
  return answer
}

> pow (2, 4)
$R3: Int = 16
> pow (2, 8)
$R4: Int = 256
> pow (3,3)
$R5: Int = 27

বাস্তব বাস্তবায়নে আপনি সম্ভবত কিছু ত্রুটি পরীক্ষা করতে চান।


এটি সম্পূর্ণ বৈধ উত্তর is কিছু উদাহরণ রয়েছে যেখানে ইনসকে ডাবলসে রূপান্তর করা যথাযথতা হারাতে পারে এবং তাই এটি ইন পাও এর পক্ষে একটি কার্যকর সমাধান নয়। কেবল Double(Int.max - 1) < Double(Int.max)একটি সুইফ্ট 3 আরপিএল চালানোর চেষ্টা করুন এবং আপনি অবাক হতে পারেন।
mklbtz

4
এটি সংক্ষিপ্ত করতে, আপনি একটি reduceকল দিয়ে এটি বাস্তবায়ন করতে পারেন । return (2...power).reduce(base) { result, _ in result * base }
mklbtz

4
সম্ভবত আপনি শক্তি UInt করে পূর্বশর্ত পরিত্রাণ পেতে পারেন
হাশেমি


4

আপনি যদি অপারেটর ওভারলোডিংয়ের দিকে স্বতন্ত্র হন (তবে ^^সমাধানটি আপনার কোডটি পড়ার জন্য কারও কাছে সম্ভবত পরিষ্কার) আপনি দ্রুত প্রয়োগ করতে পারেন:

let pwrInt:(Int,Int)->Int = { a,b in return Int(pow(Double(a),Double(b))) }
pwrInt(3,4) // 81

4

এমকিএলবিটিজ পূর্ণসংখ্যা শক্তির গণনা করার জন্য স্ট্যান্ডার্ড অ্যালগরিদম হিসাবে স্কোয়ারিং দ্বারা ক্ষয়ক্ষতির সম্পর্কে সঠিক, তবে অ্যালগরিদমের পুচ্ছ-পুনরাবৃত্তি বাস্তবায়নটি কিছুটা বিভ্রান্তিকর বলে মনে হচ্ছে। সিতে স্কোয়ারিং করে এক্সপেনসিয়েশনের অ-পুনরাবৃত্তিমূলক বাস্তবায়নের জন্য http://www.programminglogic.com/ ব্রেকফাস্ট- exponentiation-algorithms / দেখুন I've আমি এটি এখানে সুইফটে অনুবাদ করার চেষ্টা করেছি:

func expo(_ base: Int, _ power: Int) -> Int {
    var result = 1

    while (power != 0){
        if (power%2 == 1){
            result *= base
        }
        power /= 2
        base *= base
    }
    return result
}

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

    func expo<T:IntegerType>(_ base: T, _ power: T) -> T {
    var result : T = 1

কিন্তু, সম্ভবত এটি বহন করা হয়।


4
খুব সুন্দর! সুইফট> ৪.০ (এক্সকোড ৯.০) এ সাধারণভাবে এটি করার জন্য, আপনি ব্যবহার করতে চান BinaryIntegerIntegerTypeঅবচয় ছিল।
mklbtz


3

উত্তরগুলি একটি ওভারলোডেড ফাংশনগুলির সংমিশ্রণে (এবং "instead" পরিবর্তে "**" ব্যবহার করে অন্য কিছু ভাষা ব্যবহার করে - আমার কাছে আরও পরিষ্কার হয়):

// http://stackoverflow.com/questions/24196689/how-to-get-the-power-of-some-integer-in-swift-language
// Put this at file level anywhere in your project
infix operator ** { associativity left precedence 160 }
func ** (radix: Double, power: Double) -> Double { return pow(radix, power) }
func ** (radix: Int,    power: Int   ) -> Double { return pow(Double(radix), Double(power)) }
func ** (radix: Float,  power: Float ) -> Double { return pow(Double(radix), Double(power)) }

ফ্লোট ব্যবহার করার সময়, আপনি নির্ভুলতা হারাতে পারেন। যদি সংখ্যাযুক্ত আক্ষরিক এবং পূর্ণসংখ্যার এবং অ-পূর্ণসংখ্যার মিশ্রণ ব্যবহার করা হয়, আপনি ডিফল্ট হিসাবে ডাবলটি দিয়ে শেষ করবেন। আমি ব্যক্তিগতভাবে স্টাইলিস্টিক / পঠনযোগ্যতার কারণে পা (ক, খ) এর মতো ফাংশনের পরিবর্তে গাণিতিক ভাবটি ব্যবহার করার দক্ষতা পছন্দ করি তবে এটি কেবল আমারই।

যে কোনও অপারেটর যা পাও () এর ত্রুটি ঘটায় তা ঘটায় এবং এই ফাংশনগুলিকে একটি ত্রুটি ছুঁড়ে ফেলবে, সুতরাং ত্রুটি পরীক্ষার বোঝা এখনও যে কোনওভাবে পাওয়ার ফাংশন ব্যবহার করে কোডের সাথেই রয়েছে। কিআইএসএস, আইএমএইচও।

নেটিভ পাউ () ফাংশন ব্যবহার করে উদাহরণস্বরূপ বর্গমূল (2 ** 0.5) বা বিপরীত (2 ** -3 = 1/8) নিতে পারবেন। বিপরীতমুখী বা ভগ্নাংশের ব্যবহারকারীর ব্যবহারের সম্ভাবনার কারণে, আমি আমার সমস্ত কোড লিখেছিলাম ডিফল্ট ডাবল প্রকারের পা () ফাংশনটি ফিরিয়ে দিতে, যা সর্বাধিক নির্ভুলতা ফিরে আসে (যদি আমি ডকুমেন্টেশন সঠিকভাবে মনে করি)। যদি প্রয়োজন হয় তবে এটি ইনট বা ফ্লোট বা যেকোনো কিছুতে টাইপ-কাস্ট করা যেতে পারে, সম্ভবত নির্ভুলতার ক্ষতি সহ।

2 ** -3  = 0.125
2 ** 0.5 = 1.4142135623731
2 ** 3   = 8

পাউ () বৃহত গণনার জন্য উপযুক্ত নয় যেখানে ভগ্নাংশের অংশটিও খুব গুরুত্বপূর্ণ। আমার জন্য আপনার উত্তর একটি ইঙ্গিত দেয়। ধন্যবাদ :)
মহেন্দ্র

3

দেখা যাচ্ছে আপনি ব্যবহার করতে পারেন pow()। উদাহরণস্বরূপ, আপনি 9 থেকে 10 পর্যন্ত প্রকাশের জন্য নিম্নলিখিতগুলি ব্যবহার করতে পারেন।

pow(10, 9)

পাশাপাশি pow, powf()একটি floatপরিবর্তে একটি ফেরত দেয় double। আমি এটি কেবল সুইফ্ট 4 এবং ম্যাকোস 10.13 এ পরীক্ষা করেছি।


4
পাও (ক, খ) বি এন যদি 0 <ফেরায়; যাতে আপনি এটির জন্য একটি পরীক্ষা যুক্ত করতে পারেন: যাক পাওয়ার = (বি> = 0)? পাও (ক, খ): 1 / পাও (এ,-বি); নোট করুন যে একটি অবশ্যই দশমিক হিসাবে ঘোষণা করা উচিত একটি: দশমিক = 2; যাক বি = -3
ক্লড 31


1

সুইফট 4.x সংস্করণ

precedencegroup ExponentiationPrecedence {
  associativity: right
  higherThan: MultiplicationPrecedence
}

infix operator ^^: ExponentiationPrecedence
public func ^^ (radix: Float, power: Float) -> Float {
  return pow((radix), (power))
}

public func ^^ (radix: Double, power: Double) -> Double {
  return pow((radix), (power))
}

public func ^^ (radix: Int, power: Int) -> Int {
  return NSDecimalNumber(decimal: pow(Decimal(radix), power)).intValue
}

1

সুইফ্ট 5 এ:

extension Int{
    func expo(_ power: Int) -> Int {
        var result = 1
        var powerNum = power
        var tempExpo = self
        while (powerNum != 0){
        if (powerNum%2 == 1){
            result *= tempExpo
        }
        powerNum /= 2
        tempExpo *= tempExpo
        }
        return result
    }
}

এই মত ব্যবহার করুন

2.expo(5) // pow(2, 5)

@ পল বুইস এর উত্তর ধন্যবাদ।



1

সুইট 5-তে বেস 2 এর বিট শিফটের মাধ্যমে মানটি সরাসরি গণনা করে এমন একটি আন্ত-ভিত্তিক পা ফাংশন:

func pow(base: Int, power: UInt) -> Int {
    if power == 0 { return 1 }
    // for base 2, use a bit shift to compute the value directly
    if base == 2 { return 2 << Int(power - 1) }
    // otherwise multiply base repeatedly to compute the value
    return repeatElement(base, count: Int(power)).reduce(1, *)
}

(ফলাফলটি আন্তের সীমার মধ্যে রয়েছে তা নিশ্চিত করুন - এটি সীমাবদ্ধতার বাইরে পরীক্ষা করে না)


1

অন্যান্য উত্তরগুলি দুর্দান্ত তবে যদি পছন্দ হয় তবে আপনি এটির Intএক্সটেনশন দিয়ে এটি এতক্ষণ করতে পারবেন যতক্ষন ধনাত্মক হয়।

extension Int {   
    func pow(toPower: Int) -> Int {
        guard toPower > 0 else { return 0 }
        return Array(repeating: self, count: toPower).reduce(1, *)
    }
}

2.pow(toPower: 8) // returns 256

0

ওভারলোডিং একত্রিত করার চেষ্টা করে, আমি জেনারিকগুলি ব্যবহার করার চেষ্টা করেছি কিন্তু এটি কার্যকর করতে পারেনি। অবশেষে আমি জেনেরিকগুলি ওভারলোড বা ব্যবহারের চেষ্টা করার পরিবর্তে এনএসএনम्बरটি ব্যবহার করতে পেরেছি। এটি নিম্নলিখিতগুলিতে সরল করে:

typealias Dbl = Double // Shorter form
infix operator ** {associativity left precedence 160}
func ** (lhs: NSNumber, rhs: NSNumber) -> Dbl {return pow(Dbl(lhs), Dbl(rhs))}

নিম্নলিখিত কোডটি উপরের মতো একই ফাংশন তবে পরামিতিগুলি সফলভাবে ডাবলসে রূপান্তরিত হতে পারে কিনা তা পরীক্ষা করে ত্রুটি পরীক্ষা করে প্রয়োগ করে।

func ** (lhs: NSNumber, rhs: NSNumber) -> Dbl {
    // Added (probably unnecessary) check that the numbers converted to Doubles
    if (Dbl(lhs) ?? Dbl.NaN) != Dbl.NaN && (Dbl(rhs) ?? Dbl.NaN) != Dbl.NaN {
        return pow(Dbl(lhs), Dbl(rhs))
    } else {
        return Double.NaN
    }
}

-1

সুইফট 5

আমি অবাক হয়েছি, তবে আমি এখানে সঠিক কোনও সঠিক সমাধান খুঁজে পাইনি।

এটা আমার:

enum CustomMath<T: BinaryInteger> {

    static func pow(_ base: T, _ power: T) -> T {
        var tempBase = base
        var tempPower = power
        var result: T = 1

        while (power != 0) {
            if (power % 2 == 1) {
                result *= base
            }
            tempPower = tempPower >> 1
            tempBase *= tempBase
        }
        return result
    }
}

উদাহরণ:

CustomMath.pow(1,1)

-3

আমি এটি আরও ভাল পছন্দ

func ^ (left:NSNumber, right: NSNumber) -> NSNumber {
    return pow(left.doubleValue,right.doubleValue)
}
var a:NSNumber = 3
var b:NSNumber = 3 
println( a^b ) // 27

4
এটি স্ট্যান্ডার্ড জোর অপারেটরকে প্রতিস্থাপন করে। এটি ব্যবহার করা আপনার কোডটিকে খুব অপ্রত্যাশিতভাবে এমন আচরণ করবে যাতে যে জানে না যে আপনি একক ক্যারেটকে ওভাররাইড করছেন।
wjl

হ্যাঁ সম্মত হন, এটি স্ট্যান্ডার্ড xorঅপারেটরের পরিবর্তে
Binh Le

-4
func calc (base:Int, number:Int) -> Int {
    var answer : Int = base
    for _ in 2...number {answer *= base } 
    return answer
}

উদাহরণ:

calc (2,2)

4
আপনার কোড কেন একটি উত্তরের মধ্যে কোড ডাম্পিংয়ের পরিবর্তে সমাধান দেয় কেন তা বোঝানো ভাল অনুশীলন।
রুডি কারশওয়া

4
এবং এটি একটি সঠিক পাওয়ার ফাংশন থেকে অনেক দূরে। একটি ব্যয়কারী বা কোনও নেতিবাচক মান হিসাবে 0 সম্পর্কে কী।
ম্যাকবার্ডি

এছাড়াও, 'ক্যালক' নামটি যেমন একটি নির্দিষ্ট ক্রিয়াকলাপে ব্যবহার করা খুব জেনেরিক .. ক্যাল (2,2) অর্থ আপনি 2 সংখ্যায় প্রয়োগ করতে চান এমন কোনও সম্ভাব্য গণনা ... 2 + 2, 2-2, 2 * 2, 2/2, 2 পাউ 2, 2 রুট 2, ইত্যাদি
এহারো 2

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