Sorununuz yetersiz, geri çekilmeli ve bazı sorular sormalısınız.
- Girdileriniz nelerdir?
- Çıktılarınız için ne tür (ler) istiyorsun?
- 1'den küçük sonuçlar için tam olarak neye dönmek istiyorsunuz? 10'luk gerçek güçler mi, yoksa 10'luk güçlerin kayan nokta yaklaşımı mı istiyorsunuz? 10'luk negatif güçlerin kayan noktada tam olarak ifade edilemeyeceğinin farkındasınız değil mi? Şimdilik 10 kuvvetin kayan nokta yaklaşımını istediğinizi varsayalım.
- Giriş tam olarak 10'luk bir güçse (veya 10'luk bir gücün en yakın kayan nokta yaklaşımı), çıkış girişle aynı mı olmalıdır? Yoksa 10'luk bir sonraki güç mü olmalı? "10 -> 10" veya "10 -> 100"? Şimdilik ilkini varsayalım.
- Girdi değerleriniz söz konusu türlerin olası herhangi bir değeri olabilir mi? yoksa daha kısıtlılar mı?
Başka bir cevapta logaritmanın alınması, daha sonra yuvarlanması (tavan fonksiyonu) ve daha sonra üssel hale getirilmesi önerildi.
def nextpow10(n):
return 10 ** math.ceil(math.log10(n))
Ne yazık ki bu yuvarlama hatalarından muzdarip. Her şeyden önce n, sahip olduğu veri türünden çift hassasiyetli kayan nokta numarasına dönüştürülür ve potansiyel olarak yuvarlama hataları getirir, ardından logaritma, hem dahili hesaplamalarında hem de sonuçta potansiyel olarak daha fazla yuvarlama hatası getirerek hesaplanır.
Bu nedenle, yanlış bir sonuç verdiği bir örnek bulmak uzun sürmedi.
>>> import math
>>> from numpy import nextafter
>>> n = 1
>>> while (10 ** math.ceil(math.log10(nextafter(n,math.inf)))) > n:
... n *= 10
...
>>> n
10
>>> nextafter(n,math.inf)
10.000000000000002
>>> 10 ** math.ceil(math.log10(10.000000000000002))
10
Teorik olarak diğer yönde başarısız olması da mümkündür, ancak bu provoke etmek çok daha zor görünmektedir.
Dolayısıyla, şamandıralar ve ints için sağlam bir çözüm için logaritmamızın değerinin sadece yaklaşık olduğunu varsaymalıyız ve bu nedenle birkaç olasılığı test etmeliyiz. Çizgisinde bir şey
def nextpow10(n):
p = round(math.log10(n))
r = 10 ** p
if r < n:
r = 10 ** (p+1)
return r;
Bu kodun, makul bir gerçek dünya büyüklüğündeki tüm argümanlar için doğru sonuçlar vermesi gerektiğine inanıyorum. Çok küçük veya çok sayıda tamsayı olmayan ve kayan nokta tipi için kayan noktaya dönüştürülen sorunlar nedeniyle kırılacaktır. Python özel durumları taşmayı önlemek amacıyla log10 işlevine tamsayı bağımsız değişkenleri sağlar, ancak yine de yeterince büyük bir tamsayı ile yuvarlama hataları nedeniyle yanlış sonuçları zorlamak mümkün olabilir.
İki uygulamayı test etmek için aşağıdaki test programını kullandım.
n = -323 # 10**-324 == 0
while n < 1000:
v = 10 ** n
if v != nextpow10(v): print(str(v)+" bad")
try:
v = min(nextafter(v,math.inf),v+1)
except:
v += 1
if v > nextpow10(v): print(str(v)+" bad")
n += 1
Bu, saf uygulamada çok sayıda hata bulur, ancak geliştirilmiş uygulamada hiçbir hata yoktur.
10
yukarıdan çalışıyor gibi görünüyor , bunun örneğin bir şeye ihtiyacı olacaklog10
.