Apakah ada alternatif non-float untuk pow ()?

9

Saya telah menjelajahi REFERENSI LANGUAGE di situs web Arduino , dan saya tidak dapat menemukan padanan non-Float dengan pow() saya harus kehilangan sesuatu yang besar, tetapi untuk kehidupan saya, saya bingung! Saya menemukan pow()di kolom FUNGSI di bawah judul Matematika (seperti yang saya harapkan), tetapi dikatakan bahwa kedua parameter, [basis] dan [eksponen] keduanya (float). Dan hanya ada enam entri lainnya di bawah judul Matematika; tidak satupun dari mereka tampaknya menjadi versi integer. Yang ingin saya lakukan adalah menghasilkan kekuatan 2 menggunakan eksponen dari 0 hingga 10. Seperti 2 ^ 0 = 1 lalu 2 ^ 1 = 2 lalu 2 ^ 2 = 4 lalu 2 ^ 3 = 8 lalu 2 ^ 4 = 16 lalu 2 ^ 5 = 32 lalu 2 ^ 6 = 64 lalu 2 ^ 7 = 128 lalu 2 ^ 8 = 256 lalu 2 ^ 9 = 512 lalu 2 ^ 10 adalah 1024

Apakah menggunakan pelampung adalah satu-satunya cara saya bisa melakukan ini? Saya mulai merasa seperti berselisih dengan kenyataan, dan telah benar-benar menghitung obat saya, tetapi saya berada di tempat yang seharusnya. Izinkan saya meminta maaf sebelumnya atas pengawasan mengerikan yang telah saya buang-buang waktu, tetapi saya telah melewati semua 9 halaman tag dan telah melakukan pencarian yang pernah saya pikirkan. Saya akui bahwa saya tidak menghabiskan banyak waktu, tapi saya yakin ini hanya akan seperti lima menit!

Bence Kaulics
sumber
2
Untuk kasus umum bilangan bulat integer (), lihat stackoverflow.com/questions/101439/… . Untuk kekuatan 2, cukup gunakan shift.
Peter Cordes

Jawaban:

8

Untuk kasus umum, jawaban @dat_ha benar, tetapi perlu dicatat bahwa Anda menginginkan kasus yang sangat spesial ... kekuatan dua. Karena komputer menggunakan aritmatika biner, operasi yang melibatkan kekuatan dua sering memiliki beberapa pintasan yang tersedia.

Mengalikan angka dengan kekuatan dua dapat dilakukan dengan operasi shift kiri ( <<), yang secara harfiah menggeser digit representasi biner dari angka (yaitu, bit) ke kiri. Dalam basis dua, menggeser bit satu tempat ke kiri sama dengan mengalikan 2, sama seperti pada basis 10 menggeser digit satu tempat ke kiri sama dengan mengalikan dengan 10. Untuk penjelasan lengkap tentang operator shift kiri di C ++ , lihat jawaban ini di Stack Overflow .

Penting untuk dicatat bahwa pergeseran kiri dapat kehilangan informasi; bit bergeser dari ujungnya hilang. Karena Anda membutuhkan kekuatan 2 hingga 10, Anda aman saat bekerja dengan bilangan bulat yang ditandatangani, yang memiliki nilai maksimum 2^15-1pada Arduino Uno .

Mengingat peringatan itu, berikut adalah fungsi untuk menghitung kekuatan dua dalam batasan ini. Ini adalah kode yang sangat cepat karena operasi shift kiri adalah operasi level yang sangat rendah, dan tidak ada multiplikasi yang benar-benar dilakukan.

int pow2(int p){
    return 1 << p;
}
Jason Clark
sumber
Kesalahan: Ini bisa naik hingga 2 ^ 32 - 1 jika Anda menggunakan unsigned long.
Dat Ha
@DATHa terima kasih, sepertinya saya kehilangan kata "tanda tangan" saat mengedit. Tetap.
Jason Clark
1
Itu bisa melewati 2 ^ 32 - 1 jika Anda menggunakan implementasi aritmatika integer presisi sewenang-wenang
Dat Han Bag
Saya ingin, khususnya untuk mengetahui mengapa hasil konversi bilangan bulat pada hasil pow () TIDAK bekerja untuk kekuatan 2. Bagi saya, pow (2,3) mengembalikan 8,00, tetapi sementara int (8,00) mengembalikan 8 , int (pow (2,3)) mengembalikan 7!
KDM
1

Ia bekerja dengan int, double, longdan float. unsigned longdan unsigned intjuga harus bekerja. Anda tidak diharuskan menggunakan mengapung HANYA.

Semoga ini bisa membantu!

Dat Ha
sumber
Alasan jawaban di atas bekerja adalah karena himpunan bilangan real (yang berisi pelampung) berisi himpunan bilangan bulat
Dat Han Bag
@DatHanBag: Dan yang lebih penting, setiap 32-bit integer adalah persis representable oleh double. Sebenarnya, karena floating point IEEE didasarkan pada representasi biner / eksponen biner, setiap kekuatan 2 harus persis dapat diwakili bahkan di luar 2 ^ 53 (titik di mana doubletidak dapat mewakili setiap bilangan bulat sembarang, 1 unit di tempat terakhir dari mantissa lebih besar dari 1,0).
Peter Cordes
@PeterCordes Ya saya memang tahu itu. Mungkin saya seharusnya mengatakan "set terikat" ketika merujuk pada set float dan integer untuk arduino dalam komentar saya tentang jawaban
Dat Han Bag
4
Ini adalah jawaban yang agak valid untuk pertanyaan umum penggunaan pow()integer, tetapi Arduino AFAICT bahkan tidak memiliki floating point perangkat keras, jadi ini adalah jawaban yang mengerikan. pow()Implementasi integer seperti ini yang berjalan dalam log2 (n) penggandaan waktu dan penambahan untuk mengakumulasikan hasil hampir pasti akan berkinerja lebih baik, dan gagal menyebutkan bahwa bit shift bekerja untuk power 2 hanya menjadikan ini jawaban yang mengerikan untuk pertanyaan ini.
Peter Cordes
1
@PeterCordes "jadi itu jawaban yang mengerikan". -menyetujui bahwa itu adalah semacam jawaban sederhana berkualitas rendah. pow () tentu dapat dihitung dalam log2 (n) - metode sederhana yang dipelajari di sekolah (mengalikan angka dengan dirinya sendiri dengan kekuatan tidak begitu efisien). Anda dapat melakukannya dengan lebih baik dengan transformasi Fourier untuk bilangan bulat yang sangat besar - misalnya. Tapi mungkin OP akan menerima dan menyukainya.
Dat Han Bag