Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Datentyp und Geschwindigkeit

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
29.01.2007, 18:32 Uhr
Suba Esel



Ich habe eine Sache, die mich sehr wundert:


C++:
#include <iostream>

inline bool isprime(unsigned long long int n)
{
    if(n==2)
        return 1;
    if(n<3||n%2==0)
        return 0;
    for(int i=3;i*i<=n;i+=2) // unsigned long long int i=3
        if(n%i==0)
            return 0;
    return 1;
}

int main()
{
    unsigned long long int zahl;
    std::cout << "Bei welcher Zahl soll ueberprueft werden, ob sie eine Primzahl ist?" << std::endl;
    std::cin >> zahl;
    int alt = time(0);
    if (isprime(zahl))
        std::cout << zahl << " ist eine Primzahl." << std::endl;
    else
        std::cout << zahl << " ist keine Primzahl." << std::endl;
    int neu = time(0);
    std::cout << neu - alt << " Sekunden.";
    std::cin.sync();
    std::cin.get();
}



Wenn ich int i = 3 nehme, braucht das Programm bei 1234567898765432111 ~0 Sekunden. Wenn ich dagegen unsigned long long int i = 3 nehme, etwa 30.
Woran liegt das? Und warum funktioniert das Programm auch mit int, dann müsste es doch eigentlich einen Buffer overrung geben, sodass es falsche Ergebnisse gibt, oder?

Ok, waren doch zwei Sachen
--
Simon
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
29.01.2007, 18:57 Uhr
Blubber2063



Es gibt keinen Bufferoverrun, aber es gibt einen Overlow, da der Int ja nicht so breit ist, das wird im Zweifel dazu führen das dass Programm nicht terminiert, da es niemals <= einer Zahl sein wird die Größer ist.

Aber Grundsätzlich gilt für dich das gleiche wie Tobias, compiliere mal mit dem Compilerschlater "- Wall " (kann auch anders heissen, ist aber das Anschalten aller Warnungen).

Dann wird dir auffallen das du einen unsigned Wert(n) mit einem signed Wert(i) vergleichst, was meistens nicht gut gehen kann.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
29.01.2007, 19:32 Uhr
Suba Esel



mmh, gibt keine Warnung...
--
Simon
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
29.01.2007, 19:36 Uhr
tobias
hmm....


sagte ich doch... bei mir gabs anfangs auch keine warnungen, sobald ich die for schleife in eine funktion mit wxwidgets haue habe ich eine warnung.
--
Danke
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
29.01.2007, 19:57 Uhr
0xdeadbeef
Gott
(Operator)


Auf x86 bist long long 64 bit breit, also doppelt so breit wie ein Register. Das bedeutet, um damit überhaupt rechnen zu können, muss der Compiler einige ziemlich wilde stunts ziehen, und die Zahl immer hin- und herswappen. Dass das dann um mehrere Größenordnungen langsamer ist, verwundert mich nicht.

Dass das Programm immer noch funktioniert, liegt daran, dass

C++:
    for(int i = 3; i * i <= n; i += 2)


i*i hier eine Breite von 2*sizeof(int) annimmt, was in diesem Fall zufällig sizeof(long long) ist.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 29.01.2007 um 19:57 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
29.01.2007, 20:09 Uhr
Suba Esel



Ah, das erklärt einiges. Also hab ich im Prinzip durch Zufall was gefunden, was die Geschwindigkeit erhöht?
--
Simon
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
29.01.2007, 20:29 Uhr
0xdeadbeef
Gott
(Operator)


Naja, du checkst immer noch anderthalb mal so viele Teiler wie notwendig.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
29.01.2007, 20:38 Uhr
Suba Esel



Wieso das denn?
--
Simon
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
29.01.2007, 21:00 Uhr
0xdeadbeef
Gott
(Operator)


Du kannst locker jede dritte überspringen. Das sieht bei mir so aus:

C++:
for(i = 5, j = 4; i * i <= x; i += (j = 6 - j))


Damit wird i immer abwechselnd um 2 und 4 erhöht. Der Hintergrund ist, startend mit 9 wird jede sechste Zahl übersprungen, zusätzlich zu jeder zweiten. 9 + 6 * x ist immer durch drei teilbar, muss also nicht überprüft werden.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: