Seite 1 von 1

4. StructureUnion und Cent in Euro umwandeln

Verfasst: 11.05.2008 21:46
von hjbremer
Ein weiteres Beispiel mit meinem aktuellen Lieblingsspielzeug StructureUnion.

Hier nun das Gegenstück von Euro in Cent umwandeln.
Limitiert auf 10 Stellen da eine Longzahl halt nicht mehr hergibt. Wer mehr braucht muß eine DoubleZahl nehmen, aber leider ist die PB Funktion StrD sehr lahmarschig. siehe Speedtest im Code.

Code: Alles auswählen

;Vergleich von 3 Prozeduren die Cent Beträge in Euro$ umwandeln
; es wurde also in cent addiert/subtrahiert, diese Zahl wird 2stellig hinterm Komma
; eignet sich nicht für cent * cent (diese sind 4 stellig hinterm Komma) 
;HJBremer Mai 2008

;der String der zurückgegeben wird ist nicht formatiert

;die Prozedure UsingEuro2 wird um ca 30% schneller, 
; wenn auf ProcedureReturn *z\s verzichtet wird.
; man muß dann mit z\s weiterarbeiten, dieser String ist nullterminiert, 
; wenn s.s{} groß genug ist. LongWerte haben max 10 Stellen, glaube ich

;wem das nicht reicht muß UsingEuroD nehmen, leider so sehr langsam

Structure Zahlenformat1
  StructureUnion
    s.s{15}  ;sollte mindestens 13 sein
    c.c[0]
    l.l
  EndStructureUnion
EndStructure    

Procedure.s UsingEuro(cent)  

;diese VergleichsProzedur macht bei kleinen negativen Zahlen Mist, hab jetzt keine Lust dies zu ändern

x$=Str(cent):lg=MemoryStringLength(@x$)

      Select lg
        Case 1: x$="0.0"+x$
        Case 2: x$="0."+x$
        Case 3 To 10: x$=Left(x$,lg-2)+"."+Right(x$,2)
      EndSelect

ProcedureReturn x$

EndProcedure

Procedure.s UsingEuroD(cent.d)  

ProcedureReturn StrD(cent.d / 100, 2)

EndProcedure

Procedure.s UsingEuro2(*z.Zahlenformat1)

;mit StructureUnion

Protected null  = '0'  ;48
Protected punkt = '.'  ;46
Protected komma = ','  ;44
Protected minus = '-'  ;45

Protected lg           ;Länge
Protected offset       ;für Zeiger verschieben
                             
*z\s = Str(*z\l)
lg   = MemoryStringLength(@*z\s)

;wenn negative Zahl, Zeiger verschieben
offset = 0
If *z\c[0] = minus
  offset = 1
  *z + offset
  lg - offset
EndIf

;1stellige Zahl
If lg = 1   ;oder *z\c[1] = 0
   
   *z\c[3] = *z\c[0]
   *z\c[2] = null 
   *z\c[1] = punkt 
   *z\c[0] = null 

;2stellige Zahl
ElseIf lg = 2   ;oder *z\c[2] = 0
   
   *z\c[3] = *z\c[1]
   *z\c[2] = *z\c[0]
   *z\c[1] = punkt 
   *z\c[0] = null 

Else
  
  ;ab 3stellige Zahl
     
  *z\c[lg-0] = *z\c[lg-1]
  *z\c[lg-1] = *z\c[lg-2]
  *z\c[lg-2] = punkt 
  
EndIf

*z - offset

ProcedureReturn *z\s 

EndProcedure

;Demo=================================================

Debug UsingEuro(1)
Debug UsingEuro(12)
Debug UsingEuro(123)
Debug UsingEuro(1234)
Debug UsingEuro(-1234)
Debug UsingEuro(-123)
Debug UsingEuro(-12)
Debug UsingEuro(-1)

Debug "---"

Debug UsingEuroD(1)
Debug UsingEuroD(12)
Debug UsingEuroD(123)
Debug UsingEuroD(1234)
Debug UsingEuroD(-1234)
Debug UsingEuroD(-123)
Debug UsingEuroD(-12)
Debug UsingEuroD(-1)

Debug "---"

z.Zahlenformat1

z\l = 1: Debug UsingEuro2(z)
z\l = 12: Debug UsingEuro2(z)
z\l = 123: Debug UsingEuro2(z)
z\l = 1234: Debug UsingEuro2(z)
z\l = -1234: Debug UsingEuro2(z)
z\l = -123: Debug UsingEuro2(z)
z\l = -12: Debug UsingEuro2(z)
z\l = -1: Debug UsingEuro2(z)


;Speedtest=Debugger ausschalten========================

max = 100000

a=GetTickCount_()

  For j = 1 To max
     
   cent = 3456789
   euro$ = UsingEuro(cent)
   
  Next 

b=GetTickCount_()-a

a=GetTickCount_()

  For j = 1 To max
   
   z\l = 3456789
   euro2$ = UsingEuro2(z)
   
  Next 

c=GetTickCount_()-a

a=GetTickCount_()

  For j = 1 To max
   
   cent = 3456789
   euro3$ = UsingEuroD(cent)
   
  Next 

d=GetTickCount_()-a


MessageRequester("",euro$+"="+Str(b)+#LF$+euro2$+"="+Str(c)+#LF$+euro3$+"="+Str(d))