Tausendertrennzeichen für (große) Zahlen

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Jungs, wo bleibt denn bei euch das frei wählbare Tausendertrennzeichen? Oder habe ich das Bild umsonst gepostet? Ich finde, das ist schon ein Bestandteil des "Wettbewerbs" :wink:

Ich werd nochmal meinen Code überarbeiten.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
#NULL
Beiträge: 2237
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

>>...wo bleibt denn...

man füge ein

Code: Alles auswählen

, sep.s="."
ein, und ändere ein in ein :praise:
my pb stuff..
Bild..jedenfalls war das mal so.
Hellhound66
Beiträge: 476
Registriert: 23.03.2005 23:19

Beitrag von Hellhound66 »

Gehts hier um Speed oder um Kompaktheit?
Optimismus ist ein Mangel an Information.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Hellhound66 hat geschrieben:Gehts hier um Speed oder um Kompaktheit?
AND51 gehts um Effizienz
Das er oftmals davon ausgeht, das, je kürzer, je schneller, weiß ich auch nicht :lol:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
al90
Beiträge: 1101
Registriert: 06.01.2005 23:15
Kontaktdaten:

Beitrag von al90 »

Hier nochmal eine optimiertere routine. Diese ist jetzt ca. doppelt so schnell
wie mein erster vorschlag. :D

Code: Alles auswählen

Procedure.s FormatByteSize(zahl.q)

Protected l.l, y.l, i.l, x.l, z.l, buff$, num$

num$=StrQ(zahl)
buff$=Space(30)
l=Len(num$)
y=l-(l/3)*3

For i=y To l-1
  PokeB(@buff$+z,PeekB(@num$+i))
  z+1 : x+1
  If x=3
    x=0
    If i<>l
      PokeB(@buff$+z,32)
      z+1
    EndIf
  EndIf
Next

ProcedureReturn ReplaceString(Trim(Left(num$,y)+" "+buff$)," ",".")

EndProcedure 

Debug FormatByteSize(1) 
Debug FormatByteSize(12) 
Debug FormatByteSize(123) 
Debug FormatByteSize(1234) 
Debug FormatByteSize(12345) 
Debug FormatByteSize(123456) 
Debug FormatByteSize(1234567) 
Debug FormatByteSize(12345678) 
Debug FormatByteSize(123456789) 
Debug FormatByteSize(1234567890) 
Debug FormatByteSize(4294967295) 
Gehts hier um Speed oder um Kompaktheit?
Nicht nur. Vielmehr auch um Fehlerfreiheit und das ist wohl auch erstmal das wichtigste.
Jungs, wo bleibt denn bei euch das frei wählbare Tausendertrennzeichen?
Oder habe ich das Bild umsonst gepostet? Ich finde, das ist schon ein
Bestandteil des "Wettbewerbs"
Wat jibbet denn zu jewinnen? :lol:
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

al90 hat geschrieben:Wat jibbet denn zu jewinnen? :lol:
Genügt dir mein Respekt etwa nicht? :twisted: ... :lol:
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

ts-soft hat geschrieben:
Hellhound66 hat geschrieben:Gehts hier um Speed oder um Kompaktheit?
AND51 gehts um Effizienz
Das Stimmt! :D
ts-soft hat geschrieben: Das er oftmals davon ausgeht, das, je kürzer, je schneller, weiß ich auch nicht :lol:
Grrr, das stimmt nicht! :twisted:

_____________________________________________________________


Hier meine optimierte Prozedur:

Code: Alles auswählen

Procedure.s tausendertrennzeichen(zahl.q, separator.s=".")
	Protected zahl$=StrQ(zahl), start.l=Len(zahl$)%3, res.s=PeekS(@zahl$, start), n.l
	For n=start To Len(zahl$)-start-1 Step 3
		res+separator+PeekS(@zahl$+n, 3)
	Next
	ProcedureReturn LTrim(RemoveString(" "+res, " "+separator))
EndProcedure

Debug tausendertrennzeichen(12345678)
Wie gesagt, ich finde, der frei wählbare Separator ist ein unabdingbarer Bestandteil der Prozedur; die drei gängisten Arten, Tausendertrennzeichen zu verwenden sind diese:
Punkt: 123.456.789
Komma: 123,456,789
Hochkomma: 123'456'789
Oder einfach nur L e e r z e i c h e n: 123 456 789


_____________________________________________________________


Ich habe übrigens meine neue Prozedur mit deiner Verglichen, al90.
Ohne Debugger, 3 Mio. durchläufe, pro Durchlauf die Zahlen 123 und 123456789.

AND51: ~20,6 Sek.
al90: ~28,0 Sek.
Zuletzt geändert von AND51 am 19.11.2006 01:07, insgesamt 1-mal geändert.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
#NULL
Beiträge: 2237
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

[@al90]

Bild jetzt auch mit unicode support :) :

Code: Alles auswählen

Procedure.s FormatByteSize(zahl.q)

Protected l.l, y.l, i.l, x.l, z.l, buff$, num$
Protected size=SizeOf(Character)

num$=StrQ(zahl)
buff$=Space(30)
l=Len(num$)
y=l-(l/3)*3

For i=y To l-1
  PokeC(@buff$+z*size,PeekC(@num$+i*size))
  z+1 : x+1
  If x=3
    x=0
    If i<>l
      PokeC(@buff$+z*size,32)
      z+1
    EndIf
  EndIf
Next

ProcedureReturn ReplaceString(Trim(Left(num$,y)+" "+buff$)," ",".")

EndProcedure 
my pb stuff..
Bild..jedenfalls war das mal so.
Hellhound66
Beiträge: 476
Registriert: 23.03.2005 23:19

Beitrag von Hellhound66 »

Also wenn es um Speed geht, dann würde ich nicht Poke() nutzen, sondern direkt über Pointer arbeiten oder gleich ASM nutzen.

Code: Alles auswählen

i*size
ist auch nicht so toll, warum nicht ne Extravariable, die ich pro Iteration um Size erhöhe?

/Nachtrag:

Code: Alles auswählen

Procedure.s FormatByteSize(zahl.q,ch.s)
    
    Protected l.l, y.l, i.l, x.l, z.l, buff$, num$
    Protected Size=SizeOf(Character)
    
    num$=StrQ(zahl)
    buff$=Space(30)
    l=Len(num$)
    y=l-(l/3)*3
    
    For i=y To l-1
        PokeC(@buff$+z*Size,PeekC(@num$+i*Size))
        z+1 : x+1
        If x=3
            x=0
            If i<>l
                PokeC(@buff$+z*Size,32)
                z+1
            EndIf
        EndIf
    Next
    
    ProcedureReturn ReplaceString(Trim(Left(num$,y)+" "+buff$)," ",ch)
    
EndProcedure    

Procedure.s FormatByteSize2(zahl.q,ch.c)
    Protected l.l, y.l, i.l, x.l, z.l, buff$, num$
    Size=SizeOf(Character)
    
    num$    = StrQ(zahl)
    l       = Len(num$)
    y       = (l-1)/3
    buff$   = Space(l+y+1)
    *BuffPTR.Character = @buff$+(l+y)*Size
    *NumPtr.Character  = @num$+l*Size
    For i=0 To l
        *BuffPTR\C = *NumPtr\C  ;PokeC(@buff$+z*Size,PeekC(@num$+i*Size))
        *BuffPTR - Size
        *NumPtr - Size
        If(x=3)
            If(i=l)
                Break
            EndIf 
            x=0
            *BuffPTR\C = ch     ;PokeC(@buff$+z*Size,32)
            *BuffPTR - Size
        EndIf
        x+1
    Next
    ProcedureReturn buff$
EndProcedure



Delay(500)
#Iterations = 1000000

time.l = ElapsedMilliseconds()
For i = 1 To #Iterations
    FormatByteSize(12345678901234,".")
Next
OldFunc.l = ElapsedMilliseconds()-time

time.l = ElapsedMilliseconds()
For i = 1 To #Iterations
    FormatByteSize2(12345678901234,'.')
Next
NewFunc.l = ElapsedMilliseconds()-time

MessageRequester("SpeedTest","Alte Funktion : "+Str(OldFunc)+#CRLF$+"Neue Funktion : "+Str(NewFunc),#PB_MessageRequester_Ok)
So in der Art meinte ich das.
Optimismus ist ein Mangel an Information.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Meine Prozedur unterstützt auch Unicode... :o
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Antworten