Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Possible issue with < and > (* solved *)
#1
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!
Reply
#2
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:
Reply
#3
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.
Reply
#4
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:
Reply
#5
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!
Reply
#6
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.
Reply
#7
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
Reply
#8
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.
Reply
#9
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
Reply
#10
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.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)