Seite 1 von 1

Floats & Doubles in- und dekrementieren

Verfasst: 20.10.2010 04:32
von Regenduft
Mit den folgenden Prozeduren kann man den Wert einer Float- oder Doublevariable auf den nächstmöglichen Wert inkrementieren oder dekrementieren. Ich habe mal zwei Varianten gepostet: Bei der ersten werden die veränderten Werte rückgegeben und bei der zweiten werden die Variablen direkt manipuliert.

1. Variante (mit Rückgabewerten):

Code: Alles auswählen

Procedure.f IncF(Value.f)
  Protected *l.Long = @Value
  
  If *l\l & $7F800000 <> $7F800000 Or *l\l & $7FFFFF = 0 ; IsNAN(Value)=0 <- Geschwindigkeitsoptimierung
    
    ; positive Float inkrementieren
    If Value > 0
      If *l\l < $7F800000 ; IsInfinity(Value)=0 <- Geschwindigkeitsoptimierung
        *l\l + 1
      EndIf
    
    ; negative Float inkrementieren
    ElseIf Value < 0
      *l\l - 1
    
    ; Null-Float inkrementieren
    Else
      *l\l = 1
    EndIf
    
  EndIf
  
  ProcedureReturn Value
EndProcedure


Procedure.d IncD(Value.d)
  Protected *q.Quad = @Value
  
  If *q\q & $7FF0000000000000 <> $7FF0000000000000 Or *q\q & $000FFFFFFFFFFFFF = 0 ; IsNAN(Value)=0 <- Geschwindigkeitsoptimierung
    
    ; positive Float inkrementieren
    If Value > 0
      If *q\q < $7FF0000000000000 ; IsInfinity(Value)=0  <- Geschwindigkeitsoptimierung
        *q\q + 1
      EndIf
    
    ; negative Float inkrementieren
    ElseIf Value < 0
      *q\q - 1
    
    ; Null-Float inkrementieren
    Else
      *q\q = 1
    EndIf
    
  EndIf

  ProcedureReturn Value
EndProcedure


Procedure.f DecF(Value.f)
  Protected *l.Long = @Value
  
  If *l\l & $7F800000 <> $7F800000 Or *l\l & $7FFFFF = 0 ; IsNAN(Value)=0 <- Geschwindigkeitsoptimierung
    
    ; positive Float dekrementieren
    If Value > 0
      *l\l - 1
    
    ; negative Float dekrementieren
    ElseIf Value < 0
      If *l\l < $FF800000 ; Value > -Infinity() <- Geschwindigkeitsoptimierung
        *l\l + 1
      EndIf
    
    ; Null-Float dekrementieren
    Else
      *l\l = $80000001 ; <- kleinstmöglicher negativer Wert vor -0
    EndIf
    
  EndIf
  
  ProcedureReturn Value
EndProcedure


Procedure.d DecD(Value.d)
  Protected *q.Quad = @Value
  
  If *q\q & $7FF0000000000000 <> $7FF0000000000000 Or *q\q & $000FFFFFFFFFFFFF = 0 ; IsNAN(Value)=0 <- Geschwindigkeitsoptimierung
    
    ; positive Float dekrementieren
    If Value > 0
      *q\q - 1
    
    ; negative Float dekrementieren
    ElseIf Value < 0
      If *q\q < $FFF0000000000000 ; Value > -Infinity() <- Geschwindigkeitsoptimierung
        *q\q + 1
      EndIf
    
    ; Null-Float dekrementieren
    Else
      *q\q = $8000000000000001 ; <- kleinstmöglicher negativer Wert vor -0
    EndIf
    
  EndIf
  
  ProcedureReturn Value
EndProcedure
2. Variante (direkte Manipulation):

Code: Alles auswählen

Procedure IncF(*Value.Float)
  Protected *l.Long = *Value
  
  If *l\l & $7F800000 <> $7F800000 Or *l\l & $7FFFFF = 0 ; IsNAN(Value)=0 <- Geschwindigkeitsoptimierung
    
    ; positive Float inkrementieren
    If *Value\f > 0
      If *l\l < $7F800000 ; IsInfinity(Value)=0 <- Geschwindigkeitsoptimierung
        *l\l + 1
      EndIf
    
    ; negative Float inkrementieren
    ElseIf *Value\f < 0
      *l\l - 1
    
    ; Null-Float inkrementieren
    Else
      *l\l = 1
    EndIf
    
  EndIf
  
EndProcedure


Procedure IncD(*Value.Double)
  Protected *q.Quad = *Value
  
  If *q\q & $7FF0000000000000 <> $7FF0000000000000 Or *q\q & $000FFFFFFFFFFFFF = 0 ; IsNAN(Value)=0 <- Geschwindigkeitsoptimierung
    
    ; positive Float inkrementieren
    If *Value\d > 0
      If *q\q < $7FF0000000000000 ; IsInfinity(Value)=0  <- Geschwindigkeitsoptimierung
        *q\q + 1
      EndIf
    
    ; negative Float inkrementieren
    ElseIf *Value\d < 0
      *q\q - 1
    
    ; Null-Float inkrementieren
    Else
      *q\q = 1
    EndIf
    
  EndIf

EndProcedure


Procedure DecF(*Value.Float)
  Protected *l.Long = *Value
  
  If *l\l & $7F800000 <> $7F800000 Or *l\l & $7FFFFF = 0 ; IsNAN(Value)=0 <- Geschwindigkeitsoptimierung
    
    ; positive Float dekrementieren
    If *Value\f > 0
      *l\l - 1
    
    ; negative Float dekrementieren
    ElseIf *Value\f < 0
      If *l\l < $FF800000 ; Value > -Infinity() <- Geschwindigkeitsoptimierung
        *l\l + 1
      EndIf
    
    ; Null-Float dekrementieren
    Else
      *l\l = $80000001 ; <- kleinstmöglicher negativer Wert vor -0
    EndIf
    
  EndIf
  
EndProcedure


Procedure DecD(*Value.Double)
  Protected *q.Quad = *Value
  
  If *q\q & $7FF0000000000000 <> $7FF0000000000000 Or *q\q & $000FFFFFFFFFFFFF = 0 ; IsNAN(Value)=0 <- Geschwindigkeitsoptimierung
    
    ; positive Float dekrementieren
    If *Value\d > 0
      *q\q - 1
    
    ; negative Float dekrementieren
    ElseIf *Value\d < 0
      If *q\q < $FFF0000000000000 ; Value > -Infinity() <- Geschwindigkeitsoptimierung
        *q\q + 1
      EndIf
    
    ; Null-Float dekrementieren
    Else
      *q\q = $8000000000000001 ; <- kleinstmöglicher negativer Wert vor -0
    EndIf
    
  EndIf
  
EndProcedure
Hab' das für ein Projekt benötigt und dachte andere könnten es vielleicht nützlich finden. Ich hoffe mal, dass ich (a) keine Denk- oder Schreibfehler begangen habe und (b) der Code dieses Forums würdig ist (im Zweifelsfall plädiere ich auf "einfach cool"). <)