Pow () işlevinin değişken olmayan bir alternatifi var mı?


9

Arduino web sitesinde LANGUAGE REFERENCE'ı araştırdım ve pow() büyük bir şeyi kaçırmam gereken Float olmayan bir eşdeğeri bulamıyorum , ama benim hayatım için üzüldüm! pow()Matematik başlığı altındaki FUNCTIONS sütununda buldum (beklediğim gibi), ancak her iki parametrenin de [base] ve [exponent] 'in (float) olduğunu söylüyor. Ve Matematik başlığı altında sadece altı giriş daha var; hiçbiri tamsayı gibi görünmüyor. Tek yapmak istediğim 0'dan 10'a kadar üsleri kullanarak 2'nin güçlerini üretmek. 2 ^ 0 = 1 sonra 2 ^ 1 = 2 sonra 2 ^ 2 = 4 sonra 2 ^ 3 = 8 sonra 2 ^ 4 = 16 sonra 2 ^ 5 = 32 sonra 2 ^ 6 = 64 sonra 2 ^ 7 = 128 sonra 2 ^ 8 = 256 sonra 2 ^ 9 = 512 sonra 2 ^ 10 1024

Bunu yapabilmemin tek yolu şamandıralar mı? Gerçekle çelişiyormuşum gibi hissetmeye başladım ve aslında ilacımı saydım, ama olmam gereken yerdeyim. İzin verdiğiniz bu berbat gözetim için şimdiden özür dilerim, ancak 9 sayfalık etiketlerin tümünü inceledim ve aklıma gelen her şeyi yaptım. Bu kadar zaman harcamadığımı itiraf edeceğim, ama bunun sadece beş dakikalık bir şey gibi olacağından emindim!


2
Genel tamsayı pow () için, bkz. Stackoverflow.com/questions/101439/… . 2 güç için, sadece vardiya kullanın.
Peter Cordes

Yanıtlar:


8

Genel durum için, @dat_ha'nın cevabı doğrudur, ancak çok özel bir durum istediğinizi belirtmek gerekir ... ikisinin gücü. Bilgisayarlar ikili aritmetik kullandığından, ikisinin gücünü içeren işlemlerde genellikle bazı kısayollar bulunur.

Bir sayıyı iki güçle çarpmak <<, sayının (yani bitlerin) ikili gösteriminin rakamlarını sola doğru değiştiren sola kaydırma işlemi ( ) ile gerçekleştirilebilir . İkinci aşamada, bitleri bir yere sola kaydırmak, 2 ile çarpmakla aynıdır, tıpkı 10'da yer değiştiren basamaklar, sola doğru bir yeri 10'la çarpmakla aynıdır. C ++ 'da sol kaydırma operatörünün tam açıklaması için , Stack Overflow ile ilgili bu cevaba bakınız .

Sola kaymanın bilgi kaybedebileceğini unutmamak önemlidir; Sondan kaydırılan bitler kaybolur. 2'den 10'a kadar güçlere ihtiyacınız olduğu için 2^15-1, Arduino Uno'da maksimum değeri olan işaretli tamsayılarla çalışırken güvende olursunuz .

Bu uyarılar göz önüne alındığında, işte bu kısıtlamalar içindeki ikisinin güçlerini hesaplamak için bir işlev. Bu çok hızlı bir koddur, çünkü sol kaydırma işlemi çok düşük seviyeli bir işlemdir ve aslında çarpma işlemi gerçekleştirilmez.

int pow2(int p){
    return 1 << p;
}

Hata: Bir kullanırsanız 2 ^ 32 - 1'e kadar çıkabilir unsigned long.
Dat Ha

@DatHa teşekkürler, düzenleme sırasında "imzalı" kelimesini kaybettim. Sabit.
Jason Clark

1
Rasgele hassas tamsayı aritmetiği uygulamasını kullanırsanız 2 ^ 32 - 1 geçebilir
Dat Han Bag

Özellikle, pow () sonuçları üzerinde bir tamsayı dönüşümünün sonuçlarının neden 2 gücü için işe yaramadığını bilmek istiyorum. Benim için pow (2,3) 8.00, ancak int (8.00) 8 döndürür , int (pow (2,3)) 7 döndürür!
KDM

1

O çalışır int, double, longve float. unsigned longve unsigned intayrıca çalışmalı. SADECE şamandıra kullanmanıza gerek yoktur.

Umarım yardımcı olmuştur!


Cevabın yukarıdaki cevabın işe yaramasının nedeni, gerçek sayılar kümesinin (şamandıralar içeren) tamsayılar kümesini içermesidir
Dat Han Bag

@DatHanBag: Ve daha da önemlisi, her 32 bitlik tam sayı a double. Aslında, IEEE kayan noktası ikili bir mantis / üssü temsile dayandığından, 2'nin her gücü 2 ^ 53'ün ötesinde bile tam olarak temsil edilebilir olmalıdır ( doubleher keyfi tamsayıyı temsil edemeyen nokta , Mantis 1.0'dan büyüktür).
Peter Cordes

@PeterCordes Evet bunu biliyordum. Belki de arduino için şamandıra ve tamsayı setlerine atıfta bulunarak "sınırlı setler" demeliydim
Dat Han Bag

4
Bu, pow()tamsayılar için genel soruya biraz geçerli bir cevaptır , ancak AFAICT arduino'nun donanım kayan noktası bile yoktur, bu yüzden korkunç bir cevaptır. Log2 (n) zaman çarpımında ve bir sonucu biriktirmek için ekleyerek çalışan bunun gibi bir tamsayı pow()uygulaması , muhtemelen kesinlikle daha iyi performans gösterecektir ve bit kaymalarının 2 güçleri için işe yaradığından bahsetmemek, bunu sadece bu soruya korkunç bir cevap haline getirir.
Peter Cordes

1
@PeterCordes "çok korkunç bir cevap". - bu düşük kaliteli basit bir cevap olduğunu kabul etti. pow () log2 (n) 'de kesinlikle hesaplanabilir - okulda öğrenilen basit yöntem (sayıyı güce tek başına çarpmak o kadar verimli değildir). Örneğin, gerçekten büyük tamsayılar için bir Fourier dönüşümü ile daha iyi yapabilirsiniz. Ama belki OP kabul edecek ve beğenecek.
Dat Han Bag
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.