String zu Long, manuell
-
Ist long ein ganzzahliger Typ? Sonst kann das ein Inpräzisionsfehler wie bei float oder double sein.
-
Gibt mal in dein Testprogramm als String: 34, 345, 3546, 36544 ein.
Strings/Zahlen wurden beliebig gewählt
Meine Vermutung geht in Richtung Präzision der pow-Funktion.
Bist du daran gebunden?MfG f.-th.
-
nein, war mir bloß net mehr sicher, wie 10ner Potenzen gingen.

Die Vermutung mit Ungenauigkeit hatte ich auch schon, aber das Programm gibt mir die pow-Ergebnisse ja mit 1, 10, 100 u.s.w ganz normal aus. Erst die Multiplikation der beiden ganzen Zahlen bringt den Fehler rein.
34 - 34
345 - 342
3546 - 3541
36544 - 36536Deine Zahlen machen das ganze nur noch ungenauer.

-
Du hast einen anderen Compiler mit einer anderen Mathe-Bibliothek

MfG f.-th.
-
Was soll ich dann statt pow benutzen? Versteh trotzdem nicht ganz, wieso er so ins straucheln gerät....
-
pow gibt statt 3 sowas wie 2.99999999 zurück. du konvertierst in ganzzahl (-> 2) und peng.
schreib dir selbst eine potenzfunktion für long
-
Genau sowas wollte ich wissen
Dankehätte halt nicht gedacht das pow da ungenau ist, auch wenn bloß int-Werte eingehen

Jetzt sieht der Quelltext wegen den ganzen Kontrollen zwar ein wenig unhübsch aus, aber es funktioniert. Wegen sowas übt man ja.

-
Du brauchst pow nicht.
-
Hier mal was zu pow:
http://www.cplusplus.com/reference/clibrary/cmath/pow/Pi hat dir ja schon einen anderen Weg gezeigt.
Dein Ansatz ohne #include <cmath> und pow:
for(int i = 0; i < (Eingabe.size()); i++) { int zpotenz = 1; for(int j = 0; j < i; j++) zpotenz = zpotenz * 10; Zahl = Zahl + (Eingabe[Eingabe.size() - 1 - i]-'0') * zpotenz; }Das geht wahrscheinlich noch eleganter.
-
Oder sogar ganz ohne Multiplikationen:
for( int i = 0; i < Eingabe.size(); ++i ) { Zahl = ( Zahl << 3 ) + ( Zahl << 1 ) + Eingabe[i] - '0'; }
-
reano schrieb:
Oder sogar ganz ohne Multiplikationen:
for( int i = 0; i < Eingabe.size(); ++i ) { Zahl = ( Zahl << 3 ) + ( Zahl << 1 ) + Eingabe[i] - '0'; }Das ist allerdings ziemlich unsinnig, weil es deutlich langsamer sein kann. Auf einem AVR atmega16 zum Beispiel kostet eine Multiplikation genau 2 Takte. Ein Shift um 3 Positionen nach links kostet 3 Takte, ein Shift um eine Position nach links 1 Takt und die zusätzliche Addition nochmal 1 Takt. Insgesamt hat man hier also 5 Takte für deine Lösung gegenüber 2 Takte, wenn man einfach direkt mit 10 multipliziert.
Solche Optimierungen überlässt man besser dem Compiler.
-
Natürlich ist das systemabhängig.
int main() { const char* nr = "1336543215"; const int maxNum = 100000000; { StopWatch w; // nutzt den PerformanceCounter w.Start(); for(int i=0;i<maxNum;++i) { int k = atoiReano(nr); if(k!=1336543215) cout << "unmoeglich\n"; } w.Stop(); cout << w.GetTime() << "ms\n"; } { StopWatch w; w.Start(); for(int i=0;i<maxNum;++i) { int k = atoi(nr); if(k!=1336543215) cout << "unmoeglich\n"; } w.Stop(); cout << w.GetTime() << "ms\n"; } }Ausgabe:
1.01927ms 5.02301msFür mein System ist das eindeutig, von Unsinn kann da keine Rede sein.
-
Ah, jetzt habe ich doch glatt Pi vergessen: 1.0830ms.
-
Stellenangebot:
Putzfrau gesucht
10 € / Stunde
-
debugmode?
for(int i=0;i<maxNum;++i) { int k = atoiReano(nr); if(k!=1336543215) cout << "unmoeglich\n"; }das das rausoptimiert werden kann, erkennt auch der unfähigste compiler Oo
-
Aber warum dann nicht bei atoiPi oder atoi standart?
Reano: 20ms Pi: 40ms Standart: 90ms
-
Thorgrim schrieb:
Ausgabe:
1.01927ms 5.02301msFür mein System ist das eindeutig, von Unsinn kann da keine Rede sein.
Hast du im generierten Assembler-Code geprüft, dass deine Schleife nicht einfach komplett rausoptimiert wurde?
-
-
unskilled schrieb:
das das rausoptimiert werden kann, erkennt auch der unfähigste compiler Oo
phyax hat ja schon einen Link gepostet, während ich mir noch den asm-Output angeschaut habe. 20% der Zeit von atoi passt ja auch. Compiler war VC 9, win64 und x64-Code natürlich im Releasemodus, Schleifen nicht rausoptimiert (VC tut sich diesbezüglich immer schwer damit).
Update:
0.770659s Reano 5.03864s atoi 1.17046s Pi 123.285s stringstreamMit dem alten g++ 4.4
1.0659s 5.07371s 1.09504s 105.263sIch hatte erwähnt, Zeichenfolgen zufällig zusammenzustellen, aber auch bei statischen Zeichenketten optimieren die Compiler nichts weg.
-
Nimm mal den Range-Check raus, dann dürfte meine genau gleich schnell sein, wenn nicht sogar schneller.