INT PTR zu FLOAT[]?

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

 

sinjin

Betreff: INT PTR zu FLOAT[]?

BeitragMo, Mai 08, 2023 4:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo. Ich habe ein Float Array das ich aber als Int Ptr bearbeiten möchte, bzw während des Vorgangs könnte sich das ganze Array ändern. Wie mache ich aus nem Int Ptr ein Float Array?
Code: [AUSKLAPPEN]

function test:float[](floatarray#[])
  local farr1:int ptr=int ptr varptr floatarray[0]
  local farr2:int ptr=int ptr memalloc(floatarray.length*4)
' do something here
  return float[] varptr farr2 '?????
endfunction

Midimaster

BeitragMo, Mai 08, 2023 8:55
Antworten mit Zitat
Benutzer-Profile anzeigen
was genau möchtest du erreichen? in welchen Kontext sollte dies Sinn machen?

was meinst du mit: "... bzw während des Vorgangs könnte sich das ganze Array ändern..."?
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe
 

sinjin

BeitragDi, Mai 09, 2023 16:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich will eine Radixsort-Funktion für Floats schreiben. Bei Radixsort wird von einem Array in ein anderes geschrieben. Wenn ich nun das Floatarray zu einem Int Pointer mache... Ich weiß das ist die direkte Adresse, kann man irgendwie den Pointer zurück in ein Floatarray schreiben? Ich dachte halt umgekehrt: floatarray#[]=float ptr varptr farr2
Bzw als Lösung habe ich es ungefähr so:
Code: [AUSKLAPPEN]

function radixsortfloat#[](floatarray#[])
  local floatarray2#[floatarray.length]
  local farr3%ptr=int ptr varptr floatarray[0]
  local farr4%ptr=int ptr varptr floatarray2[0]
'  ...
  ret farr2

Ich dachte halt es geht iwie eleganter.

Midimaster

BeitragMi, Mai 10, 2023 2:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Kann man denn RADIX-SORT überhaupt auf FLOATs anwenden? Da werden doch Ziffern verglichen. Und ein 4Byte FLOAT-Speicherbereich besteht doch aus Mantisse und Exponent?

Hast du vorab das Problem schon theoretisch mit einem ARRAY gelöst?

Und jetzt geht es um Geschwindigkeitsoptimierung?

Benötigst Du die PTRs nur um zu versuchen das Verschieben im RAM zu beschleunigen?

Es gibt doch auch direkt FLOAT PTRs. Warum der Umweg über INT PTR?

Wäre nicht auch mit CreateStaticBank() und anschließendem PeekFloat ->>> PokeFloat ähnliches zu bewerkstelligen? oder gleich mehrere Variablen mit CopyBank() verschieben?
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe
 

sinjin

BeitragDo, Mai 11, 2023 17:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, Radix funktioniert sogar mit Strings. Bei Floats muss man manchnal ein oder 2 Bits Xor'n dann läufts wunderbar. Danke für die Ideen, werd ich mal testen obs schneller ist.
Hier mein Code:
Code: [AUSKLAPPEN]

extern "C"
  function memset(m:byte ptr,val%,sz%)
endextern

function radixsortfloat#[](arr#[])
  local pos%
  local arr2#[arr.length]',swp#[]
  local arr3%ptr=int ptr varptr arr[0]
  local arr4%ptr=int ptr varptr arr2[0]
  local cnt%[256]
  repeat
    for local a%=0 until arr.length
      local m%=(arr3[a]~$80000000) shr pos&255 ~$7f shr (~arr3[a] shr 28&$8) 'adjust negative numbers
'      local m%=(arr3[a]~$80000000) shr pos&255 ~$7f*(arr3[a]<0) 'adjust negative numbers
      cnt[m]:+1
    next

    for local a%=1 until 256
      cnt[a]:+cnt[a-1]
    next

    for local a%=arr.length-1 to 0 step-1
      local m%=(arr3[a]~$80000000) shr pos&255 ~$7f shr (~arr3[a] shr 28&$8) 'adjust negative numbers
'      local m%=(arr3[a]~$80000000) shr pos&255 ~$7f*(arr3[a]<0) 'adjust negative numbers
      cnt[m]:-1
      arr4[cnt[m]]=arr3[a]
    next
    pos:+8
    if (pos>=32) then return arr2
    local swp2#[]=arr
    arr=arr2
    arr2=swp2
    arr3=int ptr varptr arr[0]
    arr4=int ptr varptr arr2[0]
'    local swp%ptr=arr3
'    arr3=arr4
'    arr4=swp

    setmem byte ptr cnt,0,256*4
  forever
endfunction

Midimaster

BeitragDo, Mai 11, 2023 19:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Dass RADIX mit Strings funktioniert ist ja klar. Dafür wurde er ja erfunden. Dass er mit UNSIGNED INT funktioniert liegt ja wohl auch nur daran, dass man die Zahlen dabei wie STRINGS betrachtet: Du musst führende Nullen einführen, damit alle Werte gleichlang sind.

Aber wie es mit FLOAT gehen soll ist mir echt schleierhaft....

Ich seh da zwei Probleme:

Eine FLOAT besteht ja aus 2 Elementen: MANTISSE und EXPONENT

Eine FLOAT kann auch negativ sein. Wie willst Du da die Ziffern vergleichen? 5 ist größer als 3 aber bei einer negativen Zahl ist die 3 größer als die 5.

Ich werde mal dein Code-Beispiel studieren. Vielleicht kapier ichs dann. Danke für den Code.


UPDATE
Hab deine Code getestet... So kann das aber nicht funktionieren.

1.Du verweist auf eine C-Funktion... der C-Code fehlt aber.
2. Deine C-Funktion heißt memset(), Deine Aufruf heißt aber setmem() ?
und ohne diesen Aufruf stürtzt RadixSortFloat() ab.

Hast Du denn schon eine rein auf BlitzMax basierende funktionierende Lösung. Egal, ob die langsm ist.
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe
 

sinjin

BeitragDo, Mai 11, 2023 21:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Also bei mir gets einfach mit MEMSET (sry, ich hab mich einfach verschrieben lol). Ich habe meine eigene Memset in ASM geschrieben, ist noch ein Tick schneller, aber nicht viel. MEMSET füllt ja Bytes, meine Funktion füllt mit ints, ist echt nicht viel schneller und alternativ kannste auch
Code: [AUSKLAPPEN]

For local a%=0 until 256
  cnt[a]=0
next

schreiben. Geht denn MEMCLEAR bei dir? Beide sind C-Funktionen nur das Memset nicht als extern deklariert ist. Im Grunde kann man alle C-Funktionen einbinden Smile
Und Radix wurde für Strings gemacht? Das ist mir Neu, für unsigned ints ja. Also war gar nicht so einfach mit den Strings weil die ja verschiedene Längen haben und nein, da muss man nix füllen.
Das es mit Floats geht liegt daran das die im IEEE Standard Format sind, habs eben noch ein bisschen schneller gemacht, kommt jetzt fast an Quicksort ran, allerdings nur wenn die Liste schon sortiert ist, ansonsten ist Qsort halb so schnell. Und Qsort ist langsamer bei Strings und Ints, komischerweise. Bin schon am überlegen ob ich die ganze Funktion in Asm mache...naja ist ja auch schnell genug jetzt.
Ich poste mal alle Funktionen die ich habe.
Code: [AUSKLAPPEN]

;Radix.s

format MS COFF
section "code" code align 4
;in esp+4 int ptr
;in esp+8 val
;in esp+12 size
public _fillint
_fillint:
  mov ecx,[esp+12] ;size
  or ecx,ecx
 jz .out
  mov eax,[esp+8] ;val
   push edi
  mov edi,[esp+4+4] ;data
  rep stosd
   pop edi
.out:
ret



Code: [AUSKLAPPEN]

import "radix.s"
extern
  function fillint(iarr%ptr,val%,sz%)
endextern

function radixsortint%[](arr%[])
  local pos%
  local arr2%[arr.length]
  local cnt%[256]
  repeat
    for local a%=0 until arr.length
      local m%=(arr[a]) shr pos&255 ~$80 'adjust negative numbers
      cnt[m]:+1
    next

    for local a%=1 until 256
      cnt[a]:+cnt[a-1]
    next

    for local a%=arr.length-1 to 0 step-1
      local m%=(arr[a]) shr pos&255 ~$80 'adjust negative numbers
      cnt[m]:-1
      arr2[cnt[m]]=arr[a]
    next
    pos:+8
    if (pos>=32) then return arr2
    local swp%[]=arr
    arr=arr2
    arr2=swp

    fillint int ptr cnt,0,256
  forever
endfunction

function radixsortfloat#[](arr#[])
  local pos%
  local arr2#[arr.length]',swp#[]
  local arr3%ptr=int ptr varptr arr[0]
  local arr4%ptr=int ptr varptr arr2[0]
  local cnt%[256]
  repeat
    for local a%=0 until arr.length
      local m%=-arr3[a] shr pos&255 ~$7f shr (arr3[a] shr 28&$8) 'adjust negative numbers
      cnt[m]:+1
    next

    for local a%=1 until 256
      cnt[a]:+cnt[a-1]
    next

    for local a%=0 until arr.length
      local m%=-arr3[a] shr pos&255 ~$7f shr (arr3[a] shr 28&$8) 'adjust negative numbers
      cnt[m]:-1
      arr4[cnt[m]]=arr3[a]
    next
    pos:+8
    if (pos>=32) then return arr2
    local swp2#[]=arr
    arr=arr2
    arr2=swp2
    arr3=int ptr varptr arr[0]
    arr4=int ptr varptr arr2[0]

    fillint int ptr cnt,0,256
  forever
endfunction

function radixsortstr$[](arr$[],maxlen%=-1)
  if (maxlen<0) then for local a%=0 until arr.length
    if (maxlen<arr[a].length) then maxlen=arr[a].length
  next
  if not maxlen then return arr
  maxlen:-1
  local arr2$[arr.length]
  local cnt%[256]
  repeat
    for local a%=0 until arr.length
      local m%
      if arr[a] then
        m=arr[a][min(maxlen,arr[a].length-1)]&255
        if (m>=asc"A") and (m<=asc"Z") then m:+asc"a"-asc"A"
      endif
      cnt[m]:+1
    next

    for local a%=1 until 256
      cnt[a]:+cnt[a-1]
    next

    for local a%=0 until arr.length
      local m%
      if arr[a] then
        m=arr[a][min(maxlen,arr[a].length-1)]&255
        if (m>=asc"A") and (m<=asc"Z") then m:+asc"a"-asc"A"
      endif
      cnt[m]:-1
      arr2[cnt[m]]=arr[a]
    next
    maxlen:-1
    if (maxlen<0) then return arr2
    local swp$[]=arr
    arr=arr2
    arr2=swp

    fillint int ptr cnt,0,256
  forever
endfunction

 

sinjin

BeitragDo, Mai 11, 2023 22:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Hier noch eben der Test, dann musst du nur noch Kopieren und einfügen bzw auch neue Dateien anlegen:
Code: [AUSKLAPPEN]

const maxint%=$7fffffff
global n%[10]
seedrnd 10
for local a%=0 until n.length
  n[a]=int(rnd(maxint))+int(rnd(maxint)) 'trick 17 :D times 2 would mean you only have equal numbers, no odds
next
for local a%=0 until n.length
  print n[a]
next
print
n=radixsortint(n)
for local a%=0 until n.length
  print n[a]
next
input

global n4#[10]
'n4[0]=5.5
'print float2fpu(n4[0]) 'varptr n4[0]
'n4[0]=-5.5
'print float2fpu(n4[0])
seedrnd 15
for local a%=0 until n4.length
  n4[a]=rnd(10)-5
next
for local a%=0 until n4.length
  print n4[a]
next
print
n4=radixsortfloat(n4)
'qsortfloat n4,0,n4.length-1
for local a%=0 until n4.length
  print n4[a]
next
input

global n2$[10],n3$[10]
seedrnd 118
for local a%=0 until n2.length
for local b%=0 until rnd(7)+1
  n2[a]:+chr(asc("A")+32*int(rnd(2))+rnd(24))
next;next
n2[1]="va"
for local a%=0 until n2.length
  n3[a]=n2[a]
  print n2[a]
next
print
'qsortstr n3,0,n3.length-1
'n3.sort
'n2=radixsortstrlen(n2)
n2=radixsortstr(n2)
for local a%=0 until n2.length
  print n2[a]+":"+n3[a]
next
input
end

Midimaster

BeitragFr, Mai 12, 2023 1:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok, jetzt konnte ich es starten. Genial.... es funzt wirklich. Ich hab den code noch nicht verstanden, sehe aber das es funktioniert... und es ist schnell!!!!

Allerdings hab ich mal nur BlitzMax ohne Assembler verwendet. Im neuen BlitzMax NG geht ja kein direkter ASM (glaube ich jedenfalls).

Außerdem habe ich mal die Schreibweise von Old-School auf BlitzMax NG umgetuppert. So kann ich es besser lesen. Ich habe auch ein paar unnötige Code-Zeilen rausgenommen...

Zum dritten hängt auch ein Main-Programm dran, so das es jetzt jeder sofort ausprobieren kann:

Radix-Sort für FLOAT-Variablen

BlitzMax: [AUSKLAPPEN]
' Radix-Sort für FLOAT-Variablen, PD by Sinjin 2023-05-12
SuperStrict
Global Size:Int=30 ' oder auch 1000000
Global Roh:Float[Size], Ergebnis:Float[]

For Local i:Int=0 Until Size
Roh[i]=Rnd(-1000,1000)
Next

Global zeit:Int=MilliSecs()
Ergebnis = RadixSortFloat( Roh)
zeit = MilliSecs() - zeit
Print "zeit=" + zeit

For Local i:Int=0 Until 30
Print Ergebnis[i]
Next


Function RadixSortFloat:Float[]( Source:Float[])
Local Pos:Int
Local Result:Float[Source.length]
Repeat
Local SourcePointer:Int Ptr = Varptr Source[0]
Local ResultPointer:Int Ptr = Varptr Result[0]
Local cnt:Int[256]

For Local a:Int=0 Until Source.length
Local m:Int = (SourcePointer[a]~$80000000) Shr pos&255 ~$7f Shr (~SourcePointer[a] Shr 28&$8)
cnt[m]:+1
Next

For Local a:Int=1 Until 256
cnt[a]:+cnt[a-1]
Next

For Local a:Int = Source.length-1 To 0 Step-1
Local m:Int =(SourcePointer[a]~$80000000) Shr pos&255 ~$7f Shr (~SourcePointer[a] Shr 28&$8)
cnt[m]:-1
ResultPointer[cnt[m]] = SourcePointer[a]
Next
Pos:+8
If (pos>=32) Then Return Result

Local Swap:Float[] = Source
Source = Result
Result = Swap
Forever
End Function




Hier mal eine Zeitangabe, wie lange das Sortieren eines Rnd-Array mit 1.000.000 Floats unter BlitzMax NG bei mir gedauert hat: 45msec.
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe
 

sinjin

BeitragFr, Mai 12, 2023 6:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Cool das du es jetzt verstehst ^^ mit den ganzen Sprachen...lol ich versteh nur Bahnhof haha Nee, aber ich würde echt mal ne Sprache sehen die wie Blitz aufgebaut ist also ohne {} oder das halt AUCH implementiren aber halt auch das man Asm sofort einbinden kann, also so was wie:
For a:int (oder %) until 5 (to 4 geht ja auch)...aber...
das man sofort Assembler einbinden kann ohne Prozeduren Aufrufe...
also direkt mov eax,5 (hier nehme ich einfach an das a%=eax ist...halt ohne ne funktion aufzurufen und ohne iwas zu pushen! Ausserdem die ganze pusherrei....omg)...Du es ist 2023! In TASM und Turbo Pascal war das so, das du alles einbindest ABER er kompiliert nur das was nötig ist....ich verstehe das das Probleme gibt mit DLLs zb...aber statt Framework...lann man ja auch "Binde alles ein" schreiben lol
Ich habe mich mal versucht nen eigenen Compiler zu schreiben (in ASM) aber das ist Jahre her und das ist MEGA kompliziert(mein Problem waren einfach niur die Strings! Und da hat man JEDE MENGE VON!)...kann sein das man da LUA oder so einbinden kann, aber ich steh halt total drauf wenn wirklich ALLES einsehbar ist, dh finde ich asm so geil, weil da geht nix mehr zum Basteln, das ist so wie es ist und das wird wirklich DIREKT überstetzt in MaschinenSprache! Und sowas wie RETURN float[] from int ptr würde da auch gehen...Bzw jaa mag ja Hackemäßig daherkommen, ist ja dann Kein echtes Basic mehr und man muss halt Wissen mitbringen, man muss es ja nicht tun!...beides ist halt möglich. wenn man halt kein ASM kann ists halt Basic!. Und ja ich verstehe dann auch...in C muss man auch den Speicher, den man gebraucht hat, selber freigeben...Garbage finde ich auch gut....wenn beides halt gehen würde....und auch...jetzt wirds Hardcore...
man braucht auch kein If und Then mehr...du könntest ja ne Liste von Funktionen machen...wie in Widows/Linux...
If Box is active do something...das braucht man GAR nicht. du könntetst ja an einem Punkt einfach nur Fragen. der Knopf wurde aktiv: nun binde die Funktion in die liste ein die aufgerufen wird.... und gar nicht mehr fragen ob der Knopf noch aktiv ist... Das tut man ja auch mit Types also...man hat ne Funktion in dem Type aber alle enderen types sind halt EXTENDtions Very Happy da hat man "immer mal" ne Funktion die nix macht, wir aber einfach aufgerufen ohne IF.
+Und mit den Mantissen und Exponenten...wenn ich ne Bitfolge habe 0%0000000000 0000000000000000000000 ich habe mal "iwo" nen Leerzeichen gemacht angenommen die unteren Bits sind die Mantisse(der Nachkommateil) und die oberen Bits der Exponent....der Exponent ist IMMER größer, demnach nach INTS zu sortieren macht ja Sinn!
Sry ich habs jetzt echt nicht gezählt, aber du siehst das ich es vertehe.
Und ja das sind die Bits in Bltz!
local var%=%0000001 'das sind Bits!
Ich vertshe auch das Leute bei Floats falsch denken: die werden in Bits gespeichert...anders kann der Computer es gar nicht! Zufall guibts es auch nicht, das ist ne Funktion wie alle anderen auch! Nur das man mit der Eingangszahl "praktisch" iwas macht...aber IIMER ist es deterministisch...also mehr als + und - kann der Computer gar nicht! * und / sind nur Gewschwindigkeit! Genauso wie du es gesagt hast!
Das klingt alleso einfach, ist es auch! Nur das es total kompliziert wird haha....Glaube mir wenn ich sage, der Computer kann nix anderes als + und -, das sind die EINZIGEN Rechenwege die der Mensch je..."entdeckt" hat!
ALLES sind Funktionen ob du nun OpenGl hast oder DirectX EGAL WAS! Am Ende hat der Computer nix mehr gemacht als das alles zusammen zurechnen, bzw zu einer Variable....ALLES! Egal welche Prgramme, egal welches Betriebsystem!
Wen dem nicht so wäre redet man von Magie die unerklärbar ist! Wie kann man eine Maschine bauen die sich selbst nicht erklären kann bzw KEIN MENSCH? Smile
Wenn Aliens landen, und die haben nen Computer...oder sowas...."jede Fortgeschrittene Technologie erscheint als Magie" lol Das hat mal jmd gesgat...Carl Seargant? Aber das stimmt auch Heute schon, jeder der ein Handy hat, weiß wohl kaum wie das Handy funktioniert! Manchmal "ecke" ich auch an Leute...oder die ecken an mir und die wollen es auch nicht verstehen, statt das die 1*0.5 verstehen, sagen die halt das ist 2! Oder noch einfacher 1+2*3..ist nicht 6 sondern halt 7! Aber das ist sowas von falsch! Und das die ihr Handy mal in der Situation benutzen oder benutzen die es überhaput? Egal! haha
Dh wird AI auch so gross, es erschient als Magie, aber ich weiß und der Typ von (Chat)GPT weiß es auch...es sind Zahlen nix weiter!
Noch ein Wort zu FLoats,. angenommen du multiplitierst jede Zahl mit.. 1000000? dann kommst du ja zu dem Punkt wo du nur noch INTS hast! Very Happy In der Theorie

Midimaster

BeitragFr, Mai 12, 2023 8:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich werde mal Derron drauf anssprechen, inwieweit man Assembler einbinden kann in BlitzMax NG. Der ist DER Experte

Besuch uns doch mal im DISCORD-channel:
https://discord.com/channels/613699895139762176

Mit deinem Wissen könnten wir Dich dort gut gebrauchen. Du wirst dort mit den Entwicklern von BlitzMax zusammentreffen.

Oder werden doch Mitglied bei Syntaxbomb. Da würde ein Beitrag über RadixSort echt viel Beachtung finden:
https://www.syntaxbomb.com

Wie war es jetzt mit der Zeitmessung auf deinem System? Wie lange braucht das alte BlitzMax+Assembler für das Sortieren von 1.000.000 Zufalls-FLOATs?
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe
 

sinjin

BeitragSa, Mai 13, 2023 21:55
Antworten mit Zitat
Benutzer-Profile anzeigen
1.000.000? Also ich habe noch nen älteren Rechner, I5 4 Core mit 2.67GHz, in einer Sekunde schafft er bei mir 20 Durchläufe. Qsort braucht länger als eine Sekunde und wenns nicht sortiert ist....zu lange Smile Leider besitze ich kein Handy, also Discord ist nicht so meins, jmd hatte mir mal einen Account gemacht, aber ich habe den nicht mehr. Aber Syntaxbomb schaue ich mir mal an.

Midimaster

BeitragSo, Mai 14, 2023 14:06
Antworten mit Zitat
Benutzer-Profile anzeigen
sinjin hat Folgendes geschrieben:
1.000.000? Also ich habe noch nen älteren Rechner, I5 4 Core mit 2.67GHz, in einer Sekunde schafft er bei mir 20 Durchläufe....


Du meinst sicherlich: Der Rechner braucht 1 Sekunde für 20x Sortieren von einem 1.000.000-elemente -Array, oder? Das wären ja dann auch etwa 50msec.

Da wäre ja dann auf dem alten BlitzMax gleich schnell wie auf dem BlitzMax NG

Oder meist Du: "In einer Sekunde kann ich gerade mal 20 elemente sortieren". Das kann nicht sein! Das wäre viel zu langsam.
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe
 

sinjin

BeitragDi, Mai 16, 2023 17:59
Antworten mit Zitat
Benutzer-Profile anzeigen
20 "Aufrufe" von Radixsort mit 1000000 Elementen. Mein Beispiel wirft ja jede Sekunde die Anzahl der Aufrufe aus, dein Code kommt bei mir auf 50ms. Kommt ja auch hin 1000ms(1sek)/20=50ms Smile
 

sinjin

BeitragFr, Jun 09, 2023 20:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hatte ein paar Fehler drin, so sollte es richtig sein:
Code: [AUSKLAPPEN]
function radixsortint%[](arr%[])
  local cnt%[256]
  local pos%
  local arr2%[arr.length]
  repeat
    for local a%=0 until arr.length
      local m%=(arr[a]~$80000000) shr pos&255 'adjust negative numbers
      cnt[m]:+1
    next

    for local a%=1 until 256
      cnt[a]:+cnt[a-1]
    next

    for local a%=arr.length-1 to 0 step-1
      local m%=(arr[a]~$80000000) shr pos&255 'adjust negative numbers
      cnt[m]:-1
      arr2[cnt[m]]=arr[a]
    next

    pos:+8
    if (pos=32) then return arr2
    local swp%[]=arr
    arr=arr2
    arr2=swp

    for local a%=0 until 256
      cnt[a]=0
    next
  forever
endfunction

function radixsortfloat#[](source#[])
  local cnt%[256]
  local temp#[]
  local negativecount%
  local pos%,m%
  local result:float[source.length]
'  local srclen%=source.length-1
  local sourceptr%ptr=int ptr varptr source[0]
  local resultptr%ptr=int ptr varptr result[0]
  repeat
    for local a%=0 until source.length
      m=sourceptr[a] shr pos&$ff
      cnt[m]:+1
      if (pos=24) then negativecount:+m shr 7
    next

    for local a%=1 until 256
      cnt[a]:+cnt[a-1]
    next

    for local a%=source.length-1 to 0 step-1
      m=sourceptr[a] shr pos&$ff
      cnt[m]:-1

      if (pos=24) then
        if (m shr 7) then resultptr[srclen-cnt[m]]=sourceptr[a]..
                     else resultptr[cnt[m]+negativecount]=sourceptr[a]
      else
        resultptr[cnt[m]]=sourceptr[a]
      endif
    next

    pos:+8
    if (pos=32) then return result
    temp=source
    source=result
    result=temp

    sourceptr=int ptr varptr source[0]
    resultptr=int ptr varptr result[0]

    for local a%=0 until 256
      cnt[a]=0
    next
  forever
endfunction

function radixsortstr$[](arr$[],maxlen%=-1)
  if (maxlen<0) then for local a%=0 until arr.length
    if (maxlen<arr[a].length) then maxlen=arr[a].length
  next
  if not maxlen then return arr
  maxlen:-1
  local arr2$[arr.length]
  local cnt%[256]
  repeat
    for local a%=0 until arr.length
      local m%
      if arr[a] then
        m=arr[a][min(maxlen,arr[a].length-1)]&255
        if (m>=asc"A") and (m<=asc"Z") then m:+asc"a"-asc"A"
      endif
      cnt[m]:+1
    next

    for local a%=1 until 256
      cnt[a]:+cnt[a-1]
    next

    for local a%=0 until arr.length
      local m%
      if arr[a] then
        m=arr[a][min(maxlen,arr[a].length-1)]&255
        if (m>=asc"A") and (m<=asc"Z") then m:+asc"a"-asc"A"
      endif
      cnt[m]:-1
      arr2[cnt[m]]=arr[a]
    next

    if not maxlen then return arr2
    maxlen:-1
    local swp$[]=arr
    arr=arr2
    arr2=swp

    for local a%=0 until 256
      cnt[a]=0
    next
  forever
endfunction

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group