Tested before to post it. And also now.Demivec wrote:Your original code could not be used on values equal to zero. It caused a wrap to occur and you had to wait for the value to count down from 2147483647 to 0 before it exited. Try it and see, I used this statement for the time test: GrayCodingToBinaryCoding(0). That's how I came to the precise speed increase of a gazillion times.
Please take a closer look because you are very wrong this time.
Again wrong.Demivec wrote:One more comment, the "Until d<2 or s=something" is used to determine when shifting any more would be useless. Either it has run out of bits to shift (d<2 which affects shifts to the right) or it has run into a maximum value (s=something, which affects shifts to the left). The shift to the left value is equal to the size of the variable with all bits on except the sign bit (or high bit). For example in my code it equals $4000000000000000.
For your example code $40 is enough. There is a nonsense more than $40 when dealing with quads. And there is a nonsense more than $20 for longs.
Here it is a nice version:
Code: Select all
;Albert (Psychophanta) February 2008:
;with GrayCodingToBinaryCoding() by Demivec
;improved GrayCodingToBinaryCoding() by Pupil
Procedure.l BinaryCodingToGrayCoding(n.l)
ProcedureReturn n!(n>>1)
EndProcedure
Procedure.l GrayCodingToBinaryCoding(n.l)
Protected s.l=1,d.l
Repeat
d=n>>s
n!d
s<<1
Until d<2 Or s=32; <- s=64 if quads (.q) are used instead of longs (.l)
ProcedureReturn n
EndProcedure
;Test it:
For t.l=1 To 1000
a.l=Random(3000000)
If a<>BinaryCodingToGrayCoding(GrayCodingToBinaryCoding(a))
Debug "wrong!"
EndIf
Next