Seite 1 von 2
isSchnapszahl() » auch für negative Zahlen
Verfasst: 11.01.2008 13:35
von AND51
Hallo!
Mir war langweilig, und endlich ist mir was eingefallen:
isSchnapszahl()
Vielleicht kann man es der ein oder andere ja doch noch gebrauchen.
Die Prozedur funktioniert übrigens auch prima mit negativen Zahlen!
Code: Alles auswählen
Procedure isSchnapszahl(zahl.l) ; AND51/Jan-2008
Protected ziffer.l=zahl%10
If zahl > 10 Or zahl < -10
While zahl
If zahl%10 <> ziffer
ProcedureReturn 0
EndIf
zahl/10
Wend
ProcedureReturn 1
EndIf
EndProcedure
Debug isSchnapszahl(-222222222)
Wie so oft bin ich sehr an performanteren Codes interessiert, wem es also in den Fingern kribbelt...
Die üblichen Mitmachregeln:
-performant & galant
-Unicodesupport
Verfasst: 11.01.2008 15:50
von NicTheQuick
Weiß nicht, ob das schneller ist, aber ich habe mal an MODs gespart. Dafür
läuft aber die Schleife alle Ziffern durch.
Code: Alles auswählen
Procedure isSchnapszahl2(zahl.l)
Protected ziffer.l, zahl2.l
If zahl < 0 : zahl = -zahl : EndIf
If zahl < 10 : ProcedureReturn #False : EndIf
ziffer = zahl % 10
While zahl2 < zahl : zahl2 * 10 + ziffer : Wend
ProcedureReturn (Not (zahl2 ! zahl))
EndProcedure
Debug isSchnapszahl2(232)
Debug isSchnapszahl2(4444)
Aber der Geschwindigkeitsvorteil macht sich bei den paar Ziffern, die ein
Long aufnehmen kann, wohl kaum bemerkbar.
Dann lieber mit Strings.
Code: Alles auswählen
Procedure isSchnapszahl3(*c.Character)
Protected *c2.Character = *c
While *c\c
If *c\c ! *c2\c : ProcedureReturn #False : EndIf
*c + SizeOf(Character)
Wend
ProcedureReturn ((*c - *c2 - SizeOf(Character)) * *c2\c) And 1
EndProcedure
Debug isSchnapszahl3(@"232")
Debug isSchnapszahl3(@"4")
Debug isSchnapszahl3(@"44")
Debug isSchnapszahl3(@"")
Verfasst: 11.01.2008 16:11
von Kaeru Gaman
freak hatte letztens gesagt, dass ein MOD auch nur ein DIV ist,
lediglich das andere rückgaberegister wird abgefragt.
sollte also wesentlich performanter sein, als die algorithmen von früher.
Verfasst: 11.01.2008 16:24
von NicTheQuick
@Kaeru Gaman:
Habs grad gesehen.
Cool!
Code: Alles auswählen
; a.l = 4
MOV dword [v_a],4
; b.l = 3
MOV dword [v_b],3
; c.l = a % b
MOV ebx,dword [v_a] ;markiert
MOV eax,ebx ;markiert
CDQ
IDIV dword [v_b]
MOV ebx,edx
MOV dword [v_c],ebx
Warum der Compiler aus den beiden markierten Zeilen allerdings nicht
eine macht, weiß ich nicht.
Verfasst: 11.01.2008 16:27
von AND51
@ NtQ:
Hey cool!
Geschickt, du schnappst dir die letzte Ziffer und reihst diese so oft hintereinander, wie die Originalzahl Ziffern hat!
So etwas ähnlcihes habe ich vorher auch versucht: Ich habe die Länge der Zahl (mit der MOD-Methode) und die Quersumme gebildet und wollte daraus was basteln... Hat aber nicht ganz so geklappt und so bin ich bei meiner Methode gelandet.
Ich habe auch schon daran gedacht, mit bool'schen Ausdrücken zu arbeiten, aber damit wäre ich lieber vorsichtig; zumindest, bis man das "offiziell" kann.
@ Kaeru Gaman:
Danke für diese Info! hatte mich schon gefragt, wie Mod eigentlich arbeitet...
@ NtQ:
Deine prozedur ist deutlisch schneller!
Bei 1<<24 (16,7 Mio.) Schleifendurchläufen braucht deine Prozedur (bei mir) ziemlich genau 1 Sekunde. Meine Prozedur braucht knapp über 4 Sekunden.
Aber ich gebe nicht auf!

Verfasst: 11.01.2008 17:03
von AND51
@ NtQ:
Ich habe einen Bug gefunden, deine Prozedur versagt bei -10.
Die While Schleife kann nicht verlassen werden. Dies liegt daran, dass du die Ziffer 0 schnappst und diese dann mit 10 multiplizierst (ergibt immer null). Die Bedingung bis die generierte Zahl 'zahl2' größer als 'zahl' ist, wird also nie erfüllt.
Deshalb ist vermutlich dieser Bug bei dir bei allen Zahlen, die auf null enden.
Verfasst: 12.01.2008 11:36
von NicTheQuick
Na dann muss man die WhileSchleife etwas ändern:
Code: Alles auswählen
While zahl2 < zahl And ziffer : zahl2 * 10 + ziffer : Wend
Verfasst: 02.07.2008 22:45
von Xaby
Kaeru Gaman hat geschrieben:freak hatte letztens gesagt, dass ein MOD auch nur ein DIV ist
Ein DOM ist auch nur ein SUB

Verfasst: 02.07.2008 22:53
von TomS
Ein spanisches Dorf ist auch nur ein Bahnhof
Sorry, ich kapier gar nix. Aber interessieren würd's mich schon. Wo kommt denn in dem Code von da oben MOD oder DIV vor und was soll das überhaupt sein?
Verfasst: 02.07.2008 22:55
von Thorium
NicTheQuick hat geschrieben:
Code: Alles auswählen
; a.l = 4
MOV dword [v_a],4
; b.l = 3
MOV dword [v_b],3
; c.l = a % b
MOV ebx,dword [v_a] ;markiert
MOV eax,ebx ;markiert
CDQ
IDIV dword [v_b]
MOV ebx,edx
MOV dword [v_c],ebx
Warum der Compiler aus den beiden markierten Zeilen allerdings nicht
eine macht, weiß ich nicht.
Ist zwar Offtopic aber es passt grad so schön.
Von wegen Compileroptimierung und so. Bin heute über einen Code, den der VS C++ Compiler gebaut hat gestolpert, wo ich auch schmunzeln musste.
Code: Alles auswählen
MOV EBP,ESP
PUSH ECX
MOV DWORD PTR SS:[EBP-4],ECX
MOV ECX,DWORD PTR SS:[EBP-4]
