QB64.org Forum

Active Forums => QB64 Discussion => Topic started by: Cobalt on January 04, 2022, 12:57:43 pm

Title: Small hiccup in ABS
Post by: Cobalt on January 04, 2022, 12:57:43 pm
Found this small hiccup in our ABS function. As ABS typically turns a negative(-) number into a positive one. however it is failing to do so with the BYTE type at a value of -128 as demonstrated by the following code.

Code: QB64: [Select]
  1. Shift%% = 127
  2. Shift%% = Shift%% + 1
  3. PRINT ABS(Shift%%); Shift%%
  4.  
  5.  
  6. Shift%% = Shift%% + 1
  7. PRINT ABS(Shift%%); Shift%%
  8.  
output:

-128  -128

127  -127

the -128 fails to print positive with ABS but the -127(and on) works correctly.
seems to be this way from 1.1 build 82(oldest I have at the ready) clear  up to 2.0.2 4d85302

Update, further testing show it does this with INTEGER(at -32768) and LONG(at -2147483648) too. However INTEGER64 works correctly.
Title: Re: Small hiccup in ABS
Post by: Qwerkey on January 04, 2022, 01:35:56 pm
At least ABS() works correctly at the minimum of SINGLE variable type (-2.802597E-45), but Cobalt has indeed uncovered a Bug.

Title: Re: Small hiccup in ABS
Post by: jack on January 04, 2022, 01:56:44 pm
I would check whether it's the Abs function or the Str function used by the Print statement
Title: Re: Small hiccup in ABS
Post by: Qwerkey on January 04, 2022, 02:09:54 pm
A good point, @jack , but It's still -ve without using PRINT.
Title: Re: Small hiccup in ABS
Post by: Cobalt on January 04, 2022, 02:26:02 pm
I would check whether it's the Abs function or the Str function used by the Print statement

I first uncovered it in an equation, I just used print to show it. so it is ABS

Code: QB64: [Select]
  1. Shift%% = 127
  2. Shift%% = Shift%% + 1
  3. B% = ABS(Shift%%)
  4.  

same result, it  prints -128
Title: Re: Small hiccup in ABS
Post by: SMcNeill on January 04, 2022, 02:58:56 pm
Isn't this expected behavior?

A byte only holds values from -128 to 127.  You're trying to store a value of 128 in a 127-limit variable.  This causes overflow, which is giving the result you're seeing.

What's the expected answer you think you should see, since a byte can only hold values up to 127 in it?
Title: Re: Small hiccup in ABS
Post by: Cobalt on January 04, 2022, 03:16:08 pm
Isn't this expected behavior?

A byte only holds values from -128 to 127.  You're trying to store a value of 128 in a 127-limit variable.  This causes overflow, which is giving the result you're seeing.

What's the expected answer you think you should see, since a byte can only hold values up to 127 in it?

I'm not assigning the ABS value to a BYTE in either case. First case I am printing the ABS value, and second case I am assigning it to an INTEGER. Otherwise I agree, if I were to B%% = ABS(-128) I would expect a negative(-) value. But not in these cases.
Title: Re: Small hiccup in ABS
Post by: FellippeHeitor on January 04, 2022, 03:20:48 pm
Before we classify it as a bug I want one of you to please check what QB4.5 would do in these scenarios (except for byte, which wasn't a data type back then).
Title: Re: Small hiccup in ABS
Post by: Cobalt on January 04, 2022, 03:31:37 pm
Before we classify it as a bug I want one of you to please check what QB4.5 would do in these scenarios (except for byte, which wasn't a data type back then).

Save QB4.5 doesn't allow for overflow either.
so all it does it call an OVERFLOW error

but if you PRINT ABS(-32768)
it does indeed print  32768
Title: Re: Small hiccup in ABS
Post by: johnno56 on January 04, 2022, 03:35:19 pm
Forgive me if I have missed something... I understand 'integer', 'byte' and 'abs'... but what does '%%' signify? (first time I have seen this...)
Title: Re: Small hiccup in ABS
Post by: Cobalt on January 04, 2022, 03:36:49 pm
not that anybody can run it in this form, but this is where\how I found the issue, and what I am doing at the time.
This of course is called from inside a DO\LOOP so it runs all the time with K%% and SHIFT%% being STATIC variables.

Code: QB64: [Select]
  1.  FOR i%% = 0 TO 4
  2.   K%% = K%% + 1
  3.   IF K%% = 1 THEN Shift%% = Shift%% + 1: C% = C% + 1: K%% = 0 'neat flashy effect thanks to variable roll-over and ABS.
  4.   LINE (577 + E.World_X_Start * 18 + i%%, 9 + E.World_Y_Start * 13 + i%%)-STEP(13 - i%% * 2, 8 - i%% * 2), _RGB32(64 + ABS(Shift%%), 16 * i%%, 16 * i%%), BF
  5.   _PUTIMAGE (0, 10 * C%), Layer(1), temp&, (577 + E.World_X_Start * 18, 9 + E.World_Y_Start * 13)-STEP(13, 8)
  6.  NEXT i%%
  7.  

and the line I have added to get by at the moment
Code: QB64: [Select]
  1.   IF Shift%% = -128 THEN Shift%% = -127 'catch for the ABS(-128%%) issue
  2.  
Title: Re: Small hiccup in ABS
Post by: Cobalt on January 04, 2022, 03:37:13 pm
Forgive me if I have missed something... I understand 'integer', 'byte' and 'abs'... but what does '%%' signify? (first time I have seen this...)

Let me direct you here:
https://wiki.qb64.org/wiki/Variable_Types
Title: Re: Small hiccup in ABS
Post by: SMcNeill on January 04, 2022, 06:47:57 pm
It seems to me that ABS is simply returning the same type as you send it.  Send it a byte, get a byte back.  Is this a normal c-style result, which we inherited in translation, or is there more going on behind the scenes like function overloading at play?  If nobody digs into this by Friday, I'll look into it for us.  The holidays are finally over, and this seems like a simple enough issue to jump into to get my feet back into the waters of QB64.  ;)
Title: Re: Small hiccup in ABS
Post by: bplus on January 04, 2022, 07:07:06 pm
Forgive me if I have missed something... I understand 'integer', 'byte' and 'abs'... but what does '%%' signify? (first time I have seen this...)

@johnno56

%% is the suffix for a Byte

You can say:
Dim x as _Byte

or just use the suffix x%% 

like n% is an integer, n! is a single, n# is a Double...
Title: Re: Small hiccup in ABS
Post by: luke on January 04, 2022, 07:17:52 pm
I would like to reiterate the points made above:
 - ABS's return type is the same as its argument, so you can't expect to get back a value that can't be represented in that width
 - The QB4.5 interpreter correctly gives an overflow error

And also note:
 - If you compile the program with Q4.5 and run the resulting binary you'll get the same behaviour experienced here (printing the most negative value), since compiled binaries don't have overflow checking.

With that all in mind I'm deeming this slightly surprising but not buggy behaviour.
Title: Re: Small hiccup in ABS
Post by: FellippeHeitor on January 04, 2022, 07:35:28 pm
We're settled then ❤️
Title: Re: Small hiccup in ABS
Post by: Cobalt on January 04, 2022, 08:38:03 pm
I would like to reiterate the points made above:
 - ABS's return type is the same as its argument, so you can't expect to get back a value that can't be represented in that width
 - The QB4.5 interpreter correctly gives an overflow error

And also note:
 - If you compile the program with Q4.5 and run the resulting binary you'll get the same behaviour experienced here (printing the most negative value), since compiled binaries don't have overflow checking.

With that all in mind I'm deeming this slightly surprising but not buggy behaviour.

so why does it not show the same behavior with integer64? the negative sign is removed in that case?
Title: Re: Small hiccup in ABS
Post by: Cobalt on January 04, 2022, 08:40:04 pm
We're settled then ❤️

not really, cause if that is expected behavior then ABS with INTEGER64 is broken.
Title: Re: Small hiccup in ABS
Post by: FellippeHeitor on January 04, 2022, 09:10:19 pm
I stand with Luke on that technicality.
Title: Re: Small hiccup in ABS
Post by: Cobalt on January 04, 2022, 09:29:08 pm
So be it.

The wiki has been updated to NOTE this limitation of ABS to save future users the headache.

You may double check my wording to make sure I have it correct.
Title: Re: Small hiccup in ABS
Post by: FellippeHeitor on January 04, 2022, 10:02:12 pm
Thanks for the wiki edit, it seems proper.
Title: Re: Small hiccup in ABS
Post by: SMcNeill on January 04, 2022, 11:19:13 pm
Since we're bugward compatible, an easy user-function for this is:

FUNCTION Absolute## (x AS _FLOAT)
  Absolute## = SGN(x) * x
END FUNCTION
Title: Re: Small hiccup in ABS
Post by: Qwerkey on January 05, 2022, 05:34:37 am
Thanks everybody for clearing that up.

To the inveterate idiots of the community, it would not have occurred that ABS(-128) would ever be anything except 128, but now that you've explained that ABS() retains the variable type, we see that for a byte 128 -> -128.

You really shouldn't let technology loose on the unthinking!