führende Nullen ermitteln.
-
Hi,
mir fehlt im Moment der ansatz wie ich die Anzahl der führenden Nullen bei einer Gleitkommazahl ermitteln kann.Ich wollte es jetzt so versuchen, aber es ist recht umständlich.
- wandle die Zahl in einen String um
- suche das Komma
- zähle ab dem Komma alle Elemente die 0 sind, bis das erste != 0 istDer erste Ansatz in C++ sieht so aus
char s_Zahl[200]; double zahl=0.00004103 bool start_cnt=0; //flag, ob ma schon hinter dem Komma ist int count; sprintf(s_Zahl,"%d",zahl); for(int i=0; i<200; i++) { if(s_Zahl[i]=='.') { start_cnt=1; i++; //gleich mit nächstem Element weitermachen } if(start_cnt) if(is_digit(s_Zahl[i]) && s_Zahl[i]=='0') //Probe ob Element eine Zahl und 0 count++; else return; }
-
Wie wärs mit nem std::string und dann find_first_not_of("0")? Macht das Leben deutlich einfacher...
-
Ne, ist mir zu einfach
DANKE
-
Hallo,
wie wäre es einfach mal ohne Strings?int leadingZeros(double d) { int res = 0; int fak = 10; for (int t; (t = d * fak) == 0 ; fak *= 10) ++res; return res; }
Achtung: Nicht getestet!
-
Danke, die Idee ist einfach genial einfach.
-
Na also, wenn das nicht dem Logarithmus zu knacken ist...
Irgendwie mal den 10er Logarithmus andwenden. Da ein Minus davor dürfte schonmal ziemlich in die richtige Richtung gehen, oder täusche ich mich da?
MfG Jester
-
@Jester
Wäre Möglich, ist aber vom Rechenaufwand sehr aufwendig.Ich hab jetzt ne tolle Lösung auf der Idee von HumeSikkins.
Damit werden alle Nullen nach dem Komma ausgegeben, bis einen andere Ziffer kommt.int leading_zero(double d) { int cnt=0; d=d-(long)d; //Abtrennen der Ziffern vor dem Komma while(true) { d=d*10; if(d<1) cnt++; else return cnt; } return cnt; }
Wie ich finde einfach, genial einfach.
-
Bist Du sicher, daß der log langsamer ist als die Schleife?
Das würde mich wundern.MfG Jester
-
Ich hab es mal probiert, log10 ist langsamer als *
double klein=0.004; start = clock(); for(i=0; i<10000000;i++) log10(klein); finish=clock(); duration = (double)(finish - start) / CLOCKS_PER_SEC; cout<<duration<<" Sekunden"<<endl; printf("\n"); start = clock(); for(i=0; i<10000000;i++) klein=klein*10; finish=clock(); duration = (double)(finish - start) / CLOCKS_PER_SEC; cout<<duration<<" Sekunden"<<endl;
Als Ergebnis kommt bei mir:
2.553 Sekunden für log10
2.364 Sekunden für *Ist aber in dem Fall egal, da wohl nie versuchen werde mehr als 10E7 Nullen zu erfragen.
Oder siehst Du das anders?
cu
-
@daishi
Dein Test ist ein Milchmädchen-Test. Wenn dann müsstest du schon das klein = klein * 10 in eine Funktion packen. Sinnvoller wäre aber gleich ein Vergleich der beiden fertigen Lösungen.Wie auch immer: die Geschwindigkeit ist imo ersteinmal zweitrangig. Wichtig ist die Lesbarkeit (bzw. Verständlichkeit) der Lösung.
@Jester
Wie sähe die Funktion unter Anwendung des Logs aus? Ich habe eben ein klein bischen rumgespielt, bin aber leider zu keiner schönen Lösung gekommen.
-
@HumeSikkins
Du hattest recht, es war ein schlechtes Beispiel.
Wenn ich eine Funktion verwende ist log noch langsamerdouble funktion(double x) { return x*10; }
2.553 Sekunden
gegen
1.252 Sekunden
-
Ich glaube hier misst jemand die Geschwindigkeit im Debug.