Forum
Possible issue with < and > (* solved *) - Printable Version

+- Forum (https://www.boriel.com/forum)
+-- Forum: Compilers and Computer Languages (https://www.boriel.com/forum/forumdisplay.php?fid=12)
+--- Forum: ZX Basic Compiler (https://www.boriel.com/forum/forumdisplay.php?fid=11)
+---- Forum: Bug Reports (https://www.boriel.com/forum/forumdisplay.php?fid=15)
+---- Thread: Possible issue with < and > (* solved *) (/showthread.php?tid=806)



Possible issue with < and > (* solved *) - LTee - 06-20-2017

I'm struggling a bit with the behaviour of the < and > operators compared to Spectrum BASIC and I'm not sure if what I'm seeing is a bug or expected behaviour.

Check out this program:
Code:
dim t,t2 as byte

let t=1
let t2=0

print 1>0
print 1<0
print t>0
print t<0
print t>t2
print t<t2

If I run the equivalent of this in Sinclair BASIC then the output is:
1
0
1
0
1
0

But compiled in ZX Basic I get:
1
0
255
0
255
0

With just numbers the result is the same as Spectrum BASIC, but as soon as I start using typed variables in ZX Basic the 'true' value switches from 1 to 255. Is that expected behaviour? It seems a bit odd, but I realise there might be a really good reason for it.

The program I'm trying to compile relies on the result of similar clauses to perform calculations, so if the answer could be something other than 0 or 1 I'll have to rewrite it a bit. That's not a problem, but I didn't want to do that if this is actually a bug that might get fixed later. Smile

Thanks for any help!


Re: Possible issue with < and > - boriel - 06-21-2017

Yes, it's intended behaviour. This is because, believe it or not, it's faster to get 255 (which is -1 in two-complement) using Z80 ASM.
You will get -1 (the real value) if you use Byte type: CAST(Byte, t > 0).

Anyway, if you really need "1" value, then use --strict-bool parameter.
This will ensure True values are always "1", at the cost of a small (very small) overhead. :roll:


Re: Possible issue with < and > (* solved *) - LTee - 06-21-2017

That's great, boriel - thanks for the clarification. It won't cause me any problems, I'll just adapt the code accordingly - just wanted to make sure it was 'correct' behaviour before I did that.


Re: Possible issue with < and > (* solved *) - boriel - 06-21-2017

LTee Wrote:That's great, boriel - thanks for the clarification. It won't cause me any problems, I'll just adapt the code accordingly - just wanted to make sure it was 'correct' behaviour before I did that.
But remember if you need to have 1/0 logic to use:
Code:
zxb --strict-bool program.bas
so you don't have to change your code :!: :roll:


Re: Possible issue with < and > (* solved *) - LTee - 06-21-2017

Ah, yes - I'd somehow managed to forget about that by the end of the sentence, sorry! The tiny increase in processing time shouldn't be a big deal in this scenario, I think, so it's probably the safest solution.

The --base-string issue is causing me more problems at the moment, tbh - this issue at least only causes some wrong colours to appear on screen. Smile

Thanks again!


Re: Possible issue with < and > (* solved *) - britlion - 06-21-2017

For most cases having non 1 value for "True" doesn't matter (even in Sinclair basic, a positive value > 1 is "true)

So if you are doing

let bool=1>2
if bool then print "True" : end if

It's fine if bool=255, for logic. It's bad logic in ZX Basic to assume true=1, though. You can cast it with SGN, probably, or BAND 1 to limit it to definite 1/0 - then you aren't putting the overhead into every comparison. Your call as to which is most efficient, probably.


Re: Possible issue with < and > (* solved *) - LTee - 06-22-2017

In the original BASIC listing I was using it as a memory/time-saving way of selecting a colour based on the value of a variable.

e.g.
PRINT INK 1+(val<5);val

So if val>=5 the message prints in ink 1, but if it's less than 5 it becomes ink 2. Obviously this doesn't work out so well if the value is suddenly 255 instead of 1 or 0. Big Grin


Re: Possible issue with < and > (* solved *) - britlion - 07-30-2017

LTee Wrote:In the original BASIC listing I was using it as a memory/time-saving way of selecting a colour based on the value of a variable.

e.g.
PRINT INK 1+(val<5);val

So if val>=5 the message prints in ink 1, but if it's less than 5 it becomes ink 2. Obviously this doesn't work out so well if the value is suddenly 255 instead of 1 or 0. Big Grin

Yup. You'd have to wrap it in the SGN function, which I think should return 1 for positive numbers, 0 for zero, and -1 for negative numbers if you want to explicitly do that. It's a bit of a sinclair basic cheat, really. Languages that have an explicit boolean type wouldn't let you get away with this cheese either Smile

I haven't tested, but try 1+SGN(val<5)

Though given VAL is a reserved word, that's a bad variable name choice btw.


Re: Possible issue with < and > (* solved *) - boriel - 07-31-2017

That's a good idea.

You can enable strict boolean evaluation (which always returns 0 or 1) in the code with:

Code:
#pragma strict_bool = true

On the other hand, you can also create this macro, using Britlion's idea:

Code:
#define BOOL(x)  (ABS(SGN(x)))

PRINT INK 1+BOOL(value<5);value



Re: Possible issue with < and > (* solved *) - britlion - 08-08-2017

That's quite clever, Boriel. Then you only lock things to strict where you need them, and don't have to lengthen the code for each individual boolean calculation.