Größte Zahl von unsigned long double



  • Hallo,
    kann mir jemand sagen, wie ich herausfinde, welche die Größte positive (negativ gibts ja auch nicht^^) Zahl eines unsigned long double gibt?

    vielen dank


  • Mod

    Das kann man bestimmt mit dem limits Header herausfinden, aber:
    1. Gibts keinen unsigned double
    2. Weiß ich den Maximalwert für double (und long double und float) auswendig: Unendlich.

    edit: Ok, streng genommen braucht der Maximalwert nach Standard nicht unendlich zu sein. Das kann man aber prüfen mit has_infinity aus dem limits header. Und auf 99,9999% aller computer ist das true.



  • sizeof(long double) * 8 und in einer Dualzahlentabelle nachschauen heisst die Devise^^



  • Das Problem ist nämlich, dass ich riesige Fakultäten ausrechnen möchte. Bis jetzt habe ich das:

    unsigned long double fak(int i)
    {
    	if(i == 0)
            return 1;
          return i * fak(i-1);
    }
    

    Doch bereits bei 100! kommen fragwürde Zahlen heraus und bei 200! kommen undefinierte Zahlen. Ist es klug hier noch rekursiv zu arbeiten? Mit welchem Typ oder wie könnte ich den beispielsweise 1000! ausrechnen?

    Danke





  • Ok danke das ist schonmal gut. Ich habe oben mal das ursprüngliche Problem gepostet.

    Danke


  • Mod

    double ist für Fakultäten total ungeeignet, da du große Ganzzahlen benötigst. Daher auch deine Fehler. Das musst du dir entweder selber Programmieren oder eine externe Bibliothek nehmen. Suchmal nach 'bigint'.



  • Je nachdem unterstützt dein Compiler auch unsigned long long , eine vorzeichenlose 64-Bit-Zahl.


  • Mod

    Nexus schrieb:

    Je nachdem unterstützt dein Compiler auch unsigned long long , eine vorzeichenlose 64-Bit-Zahl.

    Damit kommt man aber auch bloß bis ca. 21!



  • Es stellt sich sowieso die Frage, wozu man so grosse Fakultäten braucht.

    Aber du hast natürlich Recht, wenn man mehr als nur herumexperimentieren will und tatsächlich riesige Zahlen benötigt, kommt man um eine externe Bibliothek nicht herum. Die Fakultätsfunktion würde ich persönlich dennoch iterativ implementieren.



  • Ich arbeite mit Taylorpolynomen. Da brauche ich so große Fakultäten. Mit der obigen Version kann ich aber locker 69! ausrechnen. Leider nicht genug 😞

    Ich suche mal nach bigint.

    danke



  • BinIchOrhan? schrieb:

    Ich arbeite mit Taylorpolynomen. Da brauche ich so große Fakultäten. Mit der obigen Version kann ich aber locker 69! ausrechnen. Leider nicht genug 😞

    Ich suche mal nach bigint.

    Wie wäre es mit einem double, der nur so tut als ob er 'Big' wäre. Das ist relativ einfach:

    #include <iostream>
    
    template< typename T >
    T fac( unsigned n )
    {
        T erg(1);
        for( ; n > 1; --n )
            erg *= T(n);
        return erg;
    }
    
    int main() 
    {
        using namespace std;
        for( unsigned n; cout << "> ", cin >> n; )
            cout << n << "! = " << fac< Biggy >( n ) << endl;
        return 0;
    }
    

    Das wäre z.B. eine Ausgabe dieses Programms:

    > 10
    10! = 3.6288E+6
    > 20
    20! = 2.432902E+18
    > 100
    100! = 9.332622E+157
    > 200
    200! = 7.886579E+374
    > 1000
    1000! = 4.023873E+2567
    > 1000000
    1000000! = 8.263933E+5565708
    

    also auch die Fakultät von einer Million ist kein Problem .. und das ist 'Biggy'

    #include <iostream>
    #include <iomanip>
    #include <cmath>
    
    class Biggy
    {
    public:
        Biggy( double x = 1.0 )
            : m_x( std::log10( x ) )
        {}
        Biggy& operator*=( const Biggy& b )
        {
            m_x += b.m_x;
            return *this;
        }
        friend std::ostream& operator<<( std::ostream& out, const Biggy& b )
        {
            const double g = std::floor( b.m_x );
            const std::streamsize prec = out.precision();
            out << std::pow( 10., b.m_x - g ) << "E" << (g>0?"+":"") << std::fixed << std::setprecision(0) << g;
            out.precision( prec );
            return out;
        }
    
    private:
        double m_x;
    };
    

    Das Hinzufügen von Division oder Wurzelziehen ist auch ziemlich einfach - oder.

    Gruß
    Werner



  • Kóyaánasqatsi schrieb:

    sizeof(long double) * 8 und in einer Dualzahlentabelle nachschauen heisst die Devise^^

    double ist ein Gleitkommatyp. Die grösste darstellbare Zahl ist daher viel höher als das.

    FYI: http://en.wikipedia.org/wiki/IEEE_754-1985



  • Nur das man mit Gleitkommaarithmetik fuer Ganzzahlprobleme sich boese Ungenauigkeiten einheimst. Besser ist, gmp zu benutzen. Aber ich glaube kaum, dass man bei der Taylorentwicklung das 69 Glied benoetigt. In der Physik wird bei den Gliedern schon sehr zeitig abgebrochen. Auch sollte man sich ueberlegen, wieviel Genauigkeit man durch zusaetzliche Terme gewinnt. Wahrscheinlich ist sie so gering, dass sie durch Verwendung von double sowieso weggerundet wird.


Anmelden zum Antworten