Seite 3 von 6
					
				
				Verfasst: 11.10.2006 15:57
				von NicTheQuick
				@Kaeru:
Falscher Thread?
@all:
Kann mir jemand sagen, warum ich sogar hier einen bescheuerten Fehler 
bekomme? Ich glaube Purebasic ist bei Doubles und Quads in Procedures noch ziemlich verbugt.
Außerdem funktioniert das hier nicht:
Code: Alles auswählen
unit = 1
Debug PeekS(@"KBMBGBTBPBEBZBYB" + 1 * 2, 2)
Debug PeekS(@"KBMBGBTBPBEBZBYB" + unit * 2, 2)
An diesem Code ist nichts falsch, trotzdem gibt es zwei Bugs...
Code: Alles auswählen
Procedure.s ByteCalc(Bytes.d, NbDecimals.l = 0)
  Protected result.s, unit.l
  
  unit = Round(Log(Bytes) / Log(1024), 0)
  Bytes / Pow(1024, unit)
  
  If unit
    result = StrD(Bytes, NbDecimals) + " " + PeekS(@"KBMBGBTBPBEBZBYB" + unit * 2 - 2, 2)
  Else
    result = StrD(Bytes, 0) + " B"
  EndIf
  
  ProcedureReturn result
EndProcedure
Debug ByteCalc(21456985147)
Debug ByteCalc(21456985147, 1)
Debug ByteCalc(21456985147, 2)
Debug ByteCalc(21456985147, 4)
Debug ByteCalc(1024 * 1024 - 500, 4)
Debug ByteCalc(512, 1)
Wenn es bei irgendjemandem laufen sollte,
dann liegt es wirklich an irgend einer fehlerhaften Konfiguration von mir. 
Aber probiert erstmal aus.
 
			 
			
					
				
				Verfasst: 11.10.2006 16:05
				von ts-soft
				Bist sicher, das dies Korrekt ist:
Illegal Instruction (executing binary data?)  

 
			 
			
					
				
				Verfasst: 11.10.2006 16:12
				von NicTheQuick
				Ja, das ist korrekt. Schonmal meinen ersten Code getestet? Da funktioniert 
der Codeschnipsel mit Konstanten, aber nicht mit Variablen.
			 
			
					
				
				Verfasst: 11.10.2006 16:14
				von ts-soft
				Stimmt, mit Variable bleibts leer, erste Zeile geht, zweite geht mit Konstanten
			 
			
					
				
				Verfasst: 11.10.2006 16:21
				von AND51
				NicTheQuick hat geschrieben:Wenn es bei irgendjemandem laufen sollte,
dann liegt es wirklich an irgend einer fehlerhaften Konfiguration von mir. 
Aber probiert erstmal aus.
Bei mir gibt's nen invalid Memory Access in Zeile 13 (Bei ProcedureReturn).
Aber kannst du nicht einfach mit 
Mid() arbeiten oder hast du's jetzt auf die volle Performance abgesehen? 

 
			 
			
					
				
				Verfasst: 11.10.2006 16:25
				von NicTheQuick
				Ja, stimmt, Mid() gibt es ja auch noch. 
Aber dennoch gibt es hier schon wieder einen Bug:
Code: Alles auswählen
Procedure.s ByteCalc(Bytes.d, NbDecimals.l = 0)
  Protected result.s, unit.l
  Static Suffix.s = "KBMBGBTBPBEBZBYB"
  
  unit = Round(Log(Bytes) / Log(1024), 0)
  Bytes / Pow(1024, unit)
  
  If unit
    Debug unit
    result = StrD(Bytes, NbDecimals) + " " + Mid(Suffix, unit * 2 - 1, 2)
  Else
    result = StrD(Bytes, 0) + " B"
  EndIf
  
  ProcedureReturn result
EndProcedure
Wenn man den Inhalt von Suffix direkt bei Mid() einsetzt, funktioniert es 
wieder.
 
			 
			
					
				
				Verfasst: 11.10.2006 16:33
				von AND51
				Tja... Hätt'ste mich ned, hätt'ste Mid nich... 
 
Tipp: Warum Suffix als Staic deklarieren? 

 Tut es da nicht auch ein Prot... Hm... Aha, Wenn als Static deklariert, muss es nächstes Mal nicht wieder deklariert werden. genial 
 
Aber warum setzt du Suffix nicht trotzdem bei Mid() direkt ein?
 
			 
			
					
				
				Verfasst: 11.10.2006 16:42
				von Kaeru Gaman
				[OT]
NicTheQuick hat geschrieben:@Kaeru:
Falscher Thread?
nö
Kaeru Gaman hat geschrieben:...darum ging es mir. man kann nichts aussagen über die performance von ausdrücken,
solange man nicht weiß, wie sie im endeffekt bei der CPU landen.
ts-soft hat geschrieben:Solange keine Progressbar erforderlich ist  

 , spielt es wohl eher 
eine untergeordnete Rolle
 
Kaeru Gaman hat geschrieben:hä?
was hattn jetzt Radio Eriwan mit der Chinesischen Kulturrevolution zu tun?
[/OT]
 
			 
			
					
				
				Verfasst: 11.10.2006 17:51
				von AND51
				Kleiner und schneller geht es gar nicht mehr! 
 Jetzt sind wir schon im Elite-bereich angelangt.
Von NickTheQuick inspiriert, habe ich die 
Log() Idee übernommen - damit es nicht einfach nur abschreiben/abkupfern ist, habe ich mich hingesetzt und nochmal nachgeschaut, was 
log() bewirkt. Dafür hat NtQ von mir ja auch den Tipp mit 
Mid() bekommen. 
 
Code: Alles auswählen
Procedure.s byterechner(byte.q, NbDecimals.b=0) 
   Protected bytes.d=PeekQ(@byte), unit.b=Round(Log(bytes)/Log(1024), 0) 
   ProcedureReturn StrD(Bytes/Pow(1024, unit), NbDecimals*(unit > 0 And 1))+" "+StringField("Byte,KB,MB,GB,TB,PB,EB", unit+1, ",") 
EndProcedure
 -  Kleine Verbesserung vorgenommen.
 
Nur 4 Zeilen Code! Wahnsinn... Davon hätt ich anfangs nur träumen können... 
  
Procedure vs. Macro
Man kann es natürlich als Einzeiler verpacken - hab ich getan. Dann habe ich jeweils diesen Zweizeiler und den Einzeiler nochmal als Macro notiert und alle 4 Versionen 50.000 und 100.000 Mal durchlaufen lassen.
Nachteil bei dem Zweizeiler-Mackro: Man muss mit einer Variablen arbeiten, die nicht wie bei der Procedure protected werden kann.
- Ergebnisse bei 100.000 Durchläufen auf einem System mit 550 MHz/XP mit der Zahl 5415756379 und 1 nachkommastelle:
Procedure, 2 Zeiler: 2093 ms
Procedure, 1 Zeiler: 2474 ms
Makro, 2 Zeiler: 1722 ms <--- Sieger
Makro, 1 Zeiler: 1833 ms 
Dennoch finde ich die 2 Zeiler Prozedur am besten. Den 2er Makro, der zwar am schnellsten ist, kann nämlich nicht bequem in IF-Abfragen beispielsweise eingebaut werden. Außerdem können Makros generell keine Werte zurückgeben. Makro-Ergebnisse müssen immer in Variablen zwischengespeichert werden. Hingegen vergrößern Procedures nicht den Quellcode und sind einfacherer handzuhaben.
 
			 
			
					
				
				Verfasst: 12.10.2006 09:53
				von NicTheQuick
				Und wieder mein beliebter Fehler:
Debugger hat geschrieben:Line: 3 - Illegal instruction. (executing binary data?)
Warum hab ich den Fehler wieder und sonst keiner?
Bei mir funktionert es nur ohne das PeekQ(). Jetzt hab ich es aber wohl oft
genug gesagt. 
 
@AND51: Wieso hast du deine eigene Idee mit Mid() nicht selbst benutzt? 
Ich wette, damit ist es sogar noch schneller, weil nicht nach Kommas 
gesucht werden muss.
Code: Alles auswählen
Procedure.s byterechner(Byte.q, NbDecimals.l = 0)
   Protected Bytes.d = Byte, unit.l = Round(Log(Bytes) / Log(1024), 0)
   ProcedureReturn StrD(Bytes / Pow(1024, unit), NbDecimals * (unit => 1 And 1)) + " " + Mid("KBMBGBTBPBEB", unit * 2 - 1, 2)
EndProcedure
Debug byterechner(1024 * 1024 - 512, 2)
@all: Und denkt dran. In Doubles passen die Zahlen nicht so genau rein 
wie in Quads.