Saya belajar dengan cepat baru-baru ini, tetapi saya memiliki masalah dasar yang tidak dapat menemukan jawabannya
Saya ingin mendapatkan sesuatu seperti
var a:Int = 3
var b:Int = 3
println( pow(a,b) ) // 27
tetapi fungsi pow hanya dapat bekerja dengan angka ganda, tidak bekerja dengan integer, dan saya bahkan tidak dapat mengubah int menjadi dua kali lipat dengan sesuatu seperti Double (a) atau a.double () ...
Mengapa tidak memasok kekuatan integer? itu pasti akan mengembalikan integer tanpa ambiguitas! dan Mengapa saya tidak bisa mentransmisikan integer menjadi double? itu hanya mengubah 3 menjadi 3.0 (atau 3.00000 ... terserah)
jika saya mendapat dua bilangan bulat dan saya ingin melakukan operasi daya, bagaimana saya bisa melakukannya dengan lancar?
Terima kasih!
Jawaban:
Jika Anda suka, Anda dapat menyatakan
infix
operator
untuk melakukannya.Saya menggunakan dua tanda sisipan jadi Anda masih bisa menggunakan operator XOR .
Pembaruan untuk Swift 3
Di Swift 3, "angka ajaib"
precedence
diganti denganprecedencegroups
:sumber
infix operator ^^ { precedence 160 } func ^^
... dan seterusnyafunc p(_ b: Bool) -> Double { return b?-1:1 }
?Selain itu, deklarasi variabel Anda memiliki kesalahan sintaksis, ini berfungsi persis seperti yang Anda harapkan. Yang harus Anda lakukan adalah melemparkan
a
danb
Menggandakan dan meneruskan nilainya kepow
. Kemudian, jika Anda bekerja dengan 2 Ints dan Anda menginginkan Int kembali di sisi lain operasi, cukup putar kembali ke Int.sumber
3 ** 3
. Terkadang, saya perlu menyelesaikan masalah algoritma menggunakan Swift, sangat menyakitkan dibandingkan menggunakan Python.Terkadang, mentransmisikan
Int
ke aDouble
bukanlah solusi yang layak. Pada skala tertentu ada kehilangan ketepatan dalam konversi ini. Misalnya, kode berikut tidak mengembalikan apa yang mungkin Anda harapkan secara intuitif.Jika Anda membutuhkan ketepatan pada besaran yang tinggi dan tidak perlu khawatir tentang eksponen negatif - yang umumnya tidak dapat diselesaikan dengan bilangan bulat - maka penerapan algoritme eksponen-demi-kuadrat rekursif-rekursif ini adalah taruhan terbaik Anda. Menurut jawaban SO ini , ini adalah "metode standar untuk melakukan eksponensial modular untuk bilangan besar dalam kriptografi asimetris."
Catatan: dalam contoh ini saya telah menggunakan file generik
T: BinaryInteger
. Ini agar Anda dapat menggunakanInt
atauUInt
jenis bilangan bulat lainnya.sumber
Int
atau Anda dapat meminta hal-hal itu memanggil fungsi gratis ini - apa pun yang diinginkan hati Anda.Jika Anda benar-benar menginginkan implementasi 'Int only' dan tidak ingin memaksa ke / dari
Double
, Anda harus menerapkannya. Berikut adalah implementasi yang sepele; ada algoritma yang lebih cepat tetapi ini akan berhasil:Dalam implementasi nyata, Anda mungkin menginginkan pemeriksaan kesalahan.
sumber
Double(Int.max - 1) < Double(Int.max)
Swift 3 REPL dan Anda mungkin akan terkejut.reduce
panggilan.return (2...power).reduce(base) { result, _ in result * base }
sedikit detail lagi
swift - Ekspresi Biner
sumber
Jika Anda tidak suka membebani operator (meskipun
^^
solusinya mungkin jelas bagi seseorang yang membaca kode Anda), Anda dapat melakukan implementasi cepat:sumber
mklbtz benar tentang eksponen dengan mengkuadratkan menjadi algoritma standar untuk menghitung kekuatan integer, tetapi implementasi algoritma rekursif-ekor tampaknya agak membingungkan. Lihat http://www.programminglogic.com/fast-exponentiation-algorithms/ untuk implementasi eksponen non-rekursif dengan mengkuadratkan di C. Saya telah mencoba menerjemahkannya ke Swift di sini:
Tentu saja, ini bisa dibayangkan dengan membuat operator yang kelebihan beban untuk memanggilnya dan bisa ditulis ulang untuk membuatnya lebih umum sehingga bekerja pada apa pun yang mengimplementasikan
IntegerType
protokol. Untuk membuatnya umum, saya mungkin akan mulai dengan sesuatu sepertiTapi, itu mungkin terbawa suasana.
sumber
BinaryInteger
.IntegerType
sudah tidak digunakan lagi.Atau hanya :
sumber
Menggabungkan jawaban menjadi sekumpulan fungsi yang kelebihan beban (dan menggunakan "**" alih-alih "^^" seperti yang digunakan beberapa bahasa lain - lebih jelas bagi saya):
Saat menggunakan Float, Anda mungkin kehilangan presisi. Jika menggunakan literal numerik dan campuran bilangan bulat dan non-bilangan bulat, Anda akan mendapatkan Double secara default. Saya pribadi menyukai kemampuan untuk menggunakan ekspresi matematika daripada fungsi seperti pow (a, b) karena alasan gaya / keterbacaan, tapi itu hanya saya.
Setiap operator yang akan menyebabkan pow () melakukan kesalahan juga akan menyebabkan fungsi-fungsi ini melakukan kesalahan, sehingga beban pemeriksaan kesalahan tetap terletak pada kode yang menggunakan fungsi daya. KISS, IMHO.
Menggunakan fungsi native pow () memungkinkan untuk misalnya mengambil akar kuadrat (2 ** 0,5) atau invers (2 ** -3 = 1/8). Karena kemungkinan untuk menggunakan eksponen invers atau pecahan, saya menulis semua kode saya untuk mengembalikan tipe ganda default fungsi pow (), yang akan mengembalikan presisi paling tinggi (jika saya mengingat dokumentasi dengan benar). Jika perlu, ini bisa diketikkan ke Int atau Float atau apa pun, mungkin dengan hilangnya presisi.
sumber
Ternyata Anda juga bisa menggunakan
pow()
. Misalnya, Anda dapat menggunakan berikut ini untuk mengekspresikan 10 hingga 9.Seiring dengan
pow
,powf()
mengembalikan a,float
bukandouble
. Saya hanya menguji ini di Swift 4 dan macOS 10.13.sumber
Untuk menghitung
power(2, n)
, cukup gunakan:sumber
Versi Swift 4.x.
sumber
Di Swift 5:
Gunakan seperti ini
Terima kasih atas jawaban @Paul Buis.
sumber
Array (mengulangi: a, count: b) .reduce (1, *)
sumber
Fungsi pow berbasis Int yang menghitung nilai secara langsung melalui bit shift untuk basis 2 di Swift 5:
(Pastikan hasilnya berada dalam kisaran Int - ini tidak memeriksa kasus di luar batas)
sumber
Jawaban lainnya bagus, tetapi jika diinginkan, Anda juga dapat melakukannya dengan
Int
ekstensi selama eksponennya positif.sumber
Mencoba menggabungkan overloading, saya mencoba menggunakan obat generik tetapi tidak berhasil. Saya akhirnya berpikir untuk menggunakan NSNumber daripada mencoba membebani atau menggunakan obat generik. Ini menyederhanakan menjadi berikut:
Kode berikut adalah fungsi yang sama seperti di atas tetapi mengimplementasikan pemeriksaan kesalahan untuk melihat apakah parameter berhasil diubah menjadi Ganda.
sumber
Cepat 5
Saya terkejut, tetapi saya tidak menemukan solusi yang tepat di sini.
Ini adalah milikku:
Contoh:
sumber
Saya lebih suka ini
sumber
Contoh:
sumber