Posts: 805
Threads: 135
Joined: Apr 2009
Reputation:
5
Bit shift by 0, when 0 is from a variable=0, which is incorrect!
Code: DIM num as uByte=1
DIM num2 as uByte=0
PRINT num
PRINT (num<<0)
PRINT (num<<num2)
All three lines should read "1"
Posts: 805
Threads: 135
Joined: Apr 2009
Reputation:
5
britlion Wrote:Bit shift by 0, when 0 is from a variable=0, which is incorrect!
Code: DIM num as uByte=1
DIM num2 as uByte=0
PRINT num
PRINT (num<<0)
PRINT (num<<num2)
All three lines should read "1"
Code: ld hl, (_num2 - 1)
ld a, (_num)
ld b, h
__LABEL0:
add a, a
djnz __LABEL0
Putting a byte through HL is a bit inefficient (as opposed to ld a,(_num2) / ld b,a / ld a,(_num)- but I see the heart of the problem. DJNZ decreases first (to 255) then loops if not zero. So this does 256 bit shifts before releasing - making the result bit shift right off the top of the byte value. Not trivial to solve this and still be efficient, however. Looks like it might need a CP test
I like how var<<0 is completely ignored to just print var though - very nice coding for that constant. Same code as the line above.
Posts: 1,770
Threads: 55
Joined: Aug 2019
Reputation:
24
britlion Wrote:britlion Wrote:Bit shift by 0, when 0 is from a variable=0, which is incorrect!
Code: DIM num as uByte=1
DIM num2 as uByte=0
PRINT num
PRINT (num<<0)
PRINT (num<<num2)
All three lines should read "1"
Code: ld hl, (_num2 - 1)
ld a, (_num)
ld b, h
__LABEL0:
add a, a
djnz __LABEL0
Putting a byte through HL is a bit inefficient (as opposed to ld a,(_num2) / ld b,a / ld a,(_num)- but I see the heart of the problem. DJNZ decreases first (to 255) then loops if not zero. So this does 256 bit shifts before releasing - making the result bit shift right off the top of the byte value. Not trivial to solve this and still be efficient, however. Looks like it might need a CP test
I like how var<<0 is completely ignored to just print var though - very nice coding for that constant. Same code as the line above. Yes, I supposed this was the problem. Anyway, the rule of thumb is that from the BASIC programmer point of view expr << 0 and expr << var must return the same result when 'var' = 0, as you pointed.
I could rearrange the instructions above, in the backend, to produce this:
Code: ; Loads a and h in reverse order so, a = number of shift iterations
; h = expression to shift
ld a, (_num2 - 1)
ld hl, (_num)
or a ; a = 0?
jr z, __LABEL1 ; a = 0 => No loop
ld b, a ; Loads counter into b
ld a, h ; Loads expression into a
__LABEL0:
add a, a
djnz __LABEL0
__LABEL1:
Will try to apply this patch this evening. Also, can you check if this bug happens with Uinteger and with Ulong, please?
Posts: 1,770
Threads: 55
Joined: Aug 2019
Reputation:
24
I think it's fixed for 8 bits (16 and 32 pending).
Please, download version 1.3.0s938, and tell me if it works.
This version also changes the way Floating point numbers are managed. They are some (a few) t-states slower, but uses much less memory (basically, using a subroutine), so new programs will save some precious bytes
Posts: 1,770
Threads: 55
Joined: Aug 2019
Reputation:
24
Britlion, Did you test it?
It worked for me.
Posts: 805
Threads: 135
Joined: Apr 2009
Reputation:
5
Test: Sadly, I still hadn't. I've been so crazy busy this month, I've done no coding at all...
I still have the same job, though. So you win on that...
|