String zu Long, manuell
-
Thuruk: Macht aus einer ASCII-Ziffer die entsprechende Zahl.
ruhig_brauner: Hast du Zahl mit 0 initialisiert?
-
Zahl = atoi(eingabe);
-
long atol(char const* s) { long r = 0; while(*s && *s >= '0' && *s <= '9') (r *= 10) += *s++ - '0'; return r; }*gähn
-
@Videonauth, ich habe gehofft, nicht schreiben zu müssen, dass ne fertige atoi für Übungszwecke nicht hilfreich ist.

Ganz vorbildlich mit 0 initialisiert. Der String enthält auch nur Zahlen, wird vorher kontrolliert.
PS. Mir gings darum, meinen Fehler zu finden.
thx trozdem
-
Das komische dabei ist folgendes.
Ich hab die beiden Teile mal geteilt. Die Ziffer und die Potenz.
Jetzt wird in der Schleife ausgegeben, was die aktuelle Ziffer und was die aktuelle Potenz ist, dabei entsteht kein Fehler. Alles ist richtig.Sobald aber die Zahl berechnet wird, schlieft sich irgendwo ein Fehler ein.
Bsp:
im String ist 1234
Ziffer = 4, Potenz = 1
Ziffer = 3, Potenz = 10
Ziffer = 2, Potenz = 100
Ziffer = 1, Potenz = 1000Zahl += Ziffer * Potenz
Zahl = 1232
Wenn ich nun stück für stück gucke, was zur Zahl hinzuaddiert wird, kommt manchmal son quatsch raus:
4
29 (Anstatt 30)
200
999 (Anstatt 1000)versteht das jemand?
-
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