2016-04-11 30 views
0

Sadece C++ (ve verimli) iyi bir sigmoid işlevini hesaplamaya çalışıyorum. Yani ben böyle bir şey yapmak zorunda:
1/(1 + exp(-x))C++ Çok küçük sayıya 1 ekleniyor mu?

X, 1 + e sonucu döner büyük (hatta küçük) olduğunda sorundur, 0 veya Örneğin

1,
1 + exp(-30) = 1
Ancak bu yanlış ...

Çok küçük (veya büyük) sayıları nasıl kolayca ve verimli ekleyebiliriz? Ben kullanıyorum

Datatype:

double Quaternion::sigmoidReal(double v){ 
    return 1.0/(1.0 + exp(-v)) ; 
} 

Teşekkür: Burada çift

kod parçacığı olduğunu!

+1

Hangi veri türlerini kullanıyorsunuz? – NathanOliver

+0

double, sorry ... –

+0

Kesin bir cevap için kodunuzu gösterin. –

cevap

9

Sana cout kesinliğini ayarlamak gerekir düşünüyorum:

#include <iostream> 
#include <iomanip> 

int main() 
{ 
    std::cout << std::fixed; 
    std::cout << std::setprecision(30); 
    std::cout << (1 + exp(-30)) << std::endl; 
    getchar(); 
    return 0; 
} 

Çıktı: Not

1.000000000000093480778673438181 

: Açıklamalarda belirttiği insanlar gibi, çıkış parçası gürültüsü (ise o zaman, ben düşünmedim). Çoğunlukla sadece setprecision'a rasgele bir sayı koyabileceğinizi göstermeye çalışıyordum.

Bu, 1 çifte kaydedilebilecek maksimum bilgi miktarı ile ilgilidir. Bitlerin bir kısmı, üs için ve gerçek rakamlar için kullanılır. Daha doğru yolu (hassasiyet ayarı olmadan) böyle numarayı yazdırmak olacaktır:

std::cout << 1 << "+" << exp(-30) << std::endl; 

Çıktı:

1+9.35762e-14 

hala o gerçek değeri ile çift tasarruf sorununu bırakır . Ancak, mümkün ve wikipedia, bu konuda yardımcı olan kütüphanelerin bir listesini içerir: Link. İlgili makalede ayrıca daha fazla açıklama var.

+0

Tamam, çalışıyordu, ancak standart kesinlik kullanarak göremedim? ^^ Teşekkürler –

+1

Eğer gerçekten kayan nokta anlamak istiyorsanız, en azından makine epsilon anlayarak başlamalıdır. Wikipedia bak, bir çift 1.11e-16 makine epsilon var. –

+2

Bu çıktıdaki rakamlar çoğunlukla gürültüdür. 15 basamağın ötesine geçtiğinizde gürültü görüyorsunuz. –

İlgili konular