Länge eines long wertes

Status
Nicht offen für weitere Antworten.

Jenny

Mitglied
Hallo,

ich würde gern die "Länge" von long-Werten ermitteln. Mit Länge meine ich die Anzahl der Dezimalstellen. Gibt es da eine performantere Lösung als den Long in einen String umzuwandeln und dann die Länge zu ermitteln?

schönen gruss
 
DU könntest ganz viele if-else-Abfragen machen (also [c]if (l<10) return 1; else if (l<100) return 2; ...[/c]) oder du castest den long-Wert in ein double und berechnest den 10er-Logarithmus. Keine Ahnung, was am schnellsten ist.
 
also da eher

Java:
long zahl;
int stellen=1;
while(zahl>10)
{
stellen+=1;
zahl=zahl/10;
}

/edit
oh das mit der performance hab ich nicht gesehen....
da ist meines schlechter.....
 
oder so eine Bastelei:
Java:
int c = 1;
while ((l = l / 10.0) > 1.0) {
    c++:
}

Edit: ach B4RC0D3 war schneller 😉
 
Die einfachste Lösung:
Java:
Math.ceil(Math.log10(x)) // ab 1.5
Math.ceil(Math.log(x) / Math.log(10)) // bis vor 1.5
Für Zahlen kleiner oder gleich 0 muss man aber etwas tricksen.

Ark
 
Zuletzt bearbeitet:
Will auch noch eine Schleife einwerfen 🙂

Java:
long zahl;
int stellen = 0;
		
do {
	stellen++;
} while((zahl = zahl / 10) != 0);

Oder wenns einfach gehen soll:

Java:
String.valueOf(zahl).length();

Wobei du bei negativen Zahlen entscheiden müsstest, ob das Minus-Zeichen mitgezählt wird oder nicht.
 
Danke für die vielen und schnellen Antworten! Werte unter Null kommen bei mir nicht vor (sind zeiten). Ich werde mal eine simple messung machen und euch berichten!
 
Also, für diejenigen, die es interessiert. B4RC0D3 hatte mit seiner einschätzung recht. Die Schleifen-Lösung ist eindeutig am langsamsten (ca. Faktor 2). length() und Logarithmus nehmen sich kaum was (bei meiner messung war length() ein bißchen schneller.

Nochmals Danke, und schönen gruß!
 
Mag sich mal Jemand diese Lösung anschauen?

Java:
stellen = 0;
		
long a = 1, b, c;
		
do {
	stellen++;
	b = a << 3;
	c = a << 1;
	a = b+c;
}
while(a <= zahl && a>0);

Ich hab sie mal bei mir getestet und wenn ich mich nicht mit meiner Zeitmessung vertan habe müsste diese Lösung noch schneller sein. (Sogar schneller als wenn man a immer mit 10 multiplizieren würde). In dem anderen Thread stand ja auch dass Dividieren sehr "teuer" ist, daher dieser Ansatz...

Edit:

Falls es jemanden interessiert sind hier die Ergebnisse mit dem TestProgramm aus dem anderen Thread:

sum: 69000000, time: 1672
sum: 69000000, time: 1069
sum: 69000000, time: 212 //if-else
sum: 69000000, time: 1698
sum: 69000000, time: 635 //shift-operator
sum: 69000000, time: 1751
sum: 69000000, time: 1102
sum: 69000000, time: 206 //if-else
sum: 69000000, time: 1687
sum: 69000000, time: 736 //shift

und hier die Shift-Lösung nochmal etwas schöner ohne b und c:
Java:
stellen = 0;		
long a = 1;
		
do {
	stellen++;
	a = ((a << 3) + (a << 1));
}
while(a <= zahl && a>0);

Edit2: Hab gerade noch festgestellt, dass die if-else Anweisung bei richtigen Longs explodiert. Hier die Ergebnisse:

sum: 204000000, time: 7933
sum: 204000000, time: 4845
sum: 204000000, time: 21205 //if-else
sum: 204000000, time: 7791
sum: 204000000, time: 4650 //shift
sum: 204000000, time: 7939
sum: 204000000, time: 4854
sum: 204000000, time: 21123 //if-else
sum: 204000000, time: 7819
sum: 204000000, time: 4753 //shift

Dazu habe ich noch folgende Test-Fälle aufgerufen:
sum += worker.calc(new Long("10000000000000"));
sum += worker.calc(new Long("100000000000000"));
sum += worker.calc(new Long("1000000000000000"));
 
Zuletzt bearbeitet:
Das sieht bisher sehr schnell aus. Genial. oO

Ob man da noch etwas rausholen kann, indem man vorpartitioniert?
Java:
if(zahl<1000000000){
	if(zahl<10000){
		// 0 bis <10000
	}
	else{
		// 10000 bis <1000000000
	}
}
else{
	if(zahl<10000000000000){
		// 1000000000 bis <10000000000000
	}
	else{
		// 10000000000000 bis MAX_VALUE
	}
}
Ark
 
Kleine Korrektur noch ... if-else bleibt auch bei den longs schneller, allerdings musste ich in dem Test dafür sowas noch anlegen:
Java:
    static long a = new Long("10000000000");
    static long b = new Long("100000000000");
    static long c = new Long("1000000000000");
    static long d = new Long("10000000000000");
    static long e = new Long("100000000000000");
    static long f = new Long("1000000000000000");
    static long g = new Long("10000000000000000");
    static long h = new Long("100000000000000000");
    static long j = new Long("1000000000000000000");
und anschließend if(i < a) etc abfragen... sieht insgesamt hässlich aus, aber scheint die schnellste Lösung zu sein.

@Ark Das (Durchschnitts-)Ergebnis von if-else könnte man bestimmt noch durch "divide & conquer" verbessern, kannst es ja mal ausprobieren 🙂
 
Sowas wie
static long a = new Long("10000000000");
sollte nicht notwendig sein.
static long a = 10000000000L;
sollte gehen (das "L" am Ende ist das wichtige - ansonsten kommt die Meldung "...constant too large", was du vermutlich mit dem "new Long" zu vermeiden versucht hast)
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben