Bagaimana saya bisa melakukan eksponen di clojure? Untuk saat ini saya hanya membutuhkan eksponen bilangan bulat, tetapi pertanyaannya juga berlaku untuk pecahan.
clojure
exponentiation
Peter
sumber
sumber
Jawaban:
rekursi klasik (lihat ini, meniup tumpukan)
rekursi ekor
fungsional
licik (juga menumpuk, tapi tidak begitu mudah)
Perpustakaan
sumber
Clojure memiliki fungsi daya yang berfungsi dengan baik: Saya merekomendasikan penggunaan ini daripada melalui interop Java karena ini menangani semua tipe angka presisi arbitrer dengan benar. Itu ada di namespace clojure.math.numeric-tower .
Ini disebut
expt
untuk exponentiation daripadapower
ataupow
yang mungkin menjelaskan mengapa itu agak sulit untuk menemukan ... anyway inilah contoh kecil (catatan bahwause
karya tetapi lebih baik menggunakanrequire
):Pengingat tentang penginstalan paket
Anda harus menginstal paket Java terlebih dahulu
org.clojure.math.numeric-tower
agar namespace Clojureclojure.math.numeric-tower
dapat diakses!Di baris perintah:
Kemudian edit
project.clj
dan tambahkan[org.clojure/math.numeric-tower "0.0.4"]
ke vektor dependensi.Mulai REPL lein (bukan REPL clojure)
Sekarang:
atau
sumber
Anda dapat menggunakan java
Math.pow
atauBigInteger.pow
metode:sumber
Math/pow
lebih rumit darimath-pow
atau apapun namanya jika ada padanan jubah. Jika sudah ada metode java sederhana yang melakukan apa yang Anda inginkan, tidak ada alasan untuk membuat ulang fungsionalitas di clojure. Interop Java tidak berbahaya secara inheren.Ketika pertanyaan ini pertama kali diajukan, clojure.contrib.math / expt adalah fungsi perpustakaan resmi untuk melakukan ini. Sejak itu, telah dipindahkan ke menara clojure.math.numeric
sumber
sumber
(.pow 2M 100)
(Math/pow Math/E x)
melakukan trik (menggantiMath/E
dengan alas pilihan Anda).Jika Anda benar-benar membutuhkan suatu fungsi dan bukan metode, Anda dapat membungkusnya:
Dan dalam fungsi ini Anda dapat mentransmisikannya
int
atau serupa. Fungsi seringkali lebih berguna daripada metode karena Anda dapat meneruskannya sebagai parameter ke fungsi lain - dalam hal inimap
terlintas di benak saya.Jika Anda benar-benar perlu menghindari interop Java, Anda dapat menulis fungsi daya Anda sendiri. Misalnya, ini adalah fungsi sederhana:
Itu menghitung pangkat untuk eksponen integer (yaitu tidak ada akar).
Juga, jika Anda berurusan dengan besar angka, Anda mungkin ingin menggunakan
BigInteger
bukanint
.Dan jika Anda berurusan dengan angka yang sangat besar , Anda mungkin ingin mengekspresikannya sebagai daftar digit, dan menulis fungsi aritmatika Anda sendiri untuk mengalirkannya saat mereka menghitung hasil dan mengeluarkan hasilnya ke aliran lain.
sumber
Saya pikir ini juga akan berhasil:
sumber
SICP menginspirasi versi cepat iteratif penuh dari implementasi 'licik' di atas.
sumber
Gunakan
clojure.math.numeric-tower
, sebelumnyaclojure.contrib.math
.Dokumentasi API
sumber
Penerapan metode "licik" dengan rekursi ekor dan mendukung eksponen negatif:
sumber
Satu baris sederhana menggunakan pengurangan:
sumber
Mencoba
untuk solusi tail-recursive O (log n), jika Anda ingin menerapkannya sendiri (hanya mendukung bilangan bulat positif). Jelas, solusi yang lebih baik adalah dengan menggunakan fungsi perpustakaan yang telah ditunjukkan oleh orang lain.
sumber
Bagaimana dengan clojure.contrib.genric.math-functions
Ada fungsi pow di pustaka clojure.contrib.generic.math-functions. Ini hanyalah makro untuk Math.pow dan lebih merupakan cara "clojureish" untuk memanggil fungsi matematika Java.
http://clojure.github.com/clojure-contrib/generic.math-functions-api.html#clojure.contrib.generic.math-functions/pow
sumber