Recent

Author Topic: If (qword-longint) question  (Read 2800 times)

Josh

  • Hero Member
  • *****
  • Posts: 1274
If (qword-longint) question
« on: June 22, 2018, 03:33:27 pm »
Hi

Debugging anothers code I came across this.

So I thought I would raise a question, in the examples below Comparing QWORD or other +ve only Integer Type, the application return 'Positive'

Does the IF do its internal comaprison based on one of the definitions in the comparion part of the statement, and if so which one does it assume.
I ask because it also reports 'Positive' if y = LongInt;

Code: Pascal  [Select][+][-]
  1. var x:qword=3225;
  2.     y:qword=3900;
  3. begin
  4.   if x-y<0 then showmessage('Negative')
  5.   else showmessage('Positive');
  6. end;  


if I explicity use int64(x) etc, then the reuslt is correct, it Returns 'Negative'.
Code: Pascal  [Select][+][-]
  1. var x:qword=3225;
  2.     y:longint=3900;
  3. begin
  4.   if int64(x)-int64(y)<0 then showmessage('Negative')
  5.   else showmessage('Positive');
  6. end;        
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

ASerge

  • Hero Member
  • *****
  • Posts: 2242
Re: If (qword-longint) question
« Reply #1 on: June 22, 2018, 03:50:45 pm »
 ;D I think you just ignore compiler warning: Comparison might be always false due to range of constant and expression

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: If (qword-longint) question
« Reply #2 on: June 22, 2018, 04:01:31 pm »
How about?:
Code: Pascal  [Select][+][-]
  1. uses math;
  2. var x:qword=3225;
  3.     y:qword=3900;
  4. begin
  5.   if sign(int64(x-y)) =-1 then
  6.     writeln('Negative')
  7.   else
  8.     writeln('Positive');
  9. end.
The sign function can determine negative zero or positive and returns a value in the range of -1..1. (note It can't handle -0 which is valid in some systems )
« Last Edit: June 22, 2018, 04:04:05 pm by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: If (qword-longint) question
« Reply #3 on: June 22, 2018, 04:29:15 pm »
Or (cheeky! don't try this at home!  :D :D :D :o)
Code: Pascal  [Select][+][-]
  1. {$Q-}{$macro on}{$define showmessage := writeln}
  2. var x:qword=3225;
  3.     y:qword=3900;
  4. begin
  5.   if x-y > High(int64) then  // the result is in the negative range of an int64
  6.     showmessage('Negative')
  7.   else
  8.     showmessage('Positive');
  9. end.
 
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Josh

  • Hero Member
  • *****
  • Posts: 1274
Re: If (qword-longint) question
« Reply #4 on: June 22, 2018, 04:29:42 pm »
Hi Thaddy,

Thanks for the idea of the sign(x-y) function..

The problem is a little more complex ie through out the code, there is similar comparisons, and some are not just checking for negative but for a -range.

if int64(x-y)<-500 then showmessage('Negative 500')

will give a range check error when debugging, but will run correctly in release mode. Which makes it hard to debug the rest of the code.

It's not my code, so having to go through it thoroughly and check all types when comparison of integers are involved..

Code: Pascal  [Select][+][-]
  1. var x:qword=3225;
  2.     y:longint=3900;
  3. begin
  4.   if int64(x-y)<-500 then showmessage('Negative 500')
  5.   else showmessage('Positive');
  6. end;  
  7.  
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: If (qword-longint) question
« Reply #5 on: June 22, 2018, 04:31:18 pm »
See my last example, that may help but demands {$Q-} Our posts crossed. The new example is not dependent on math nor any other unit..
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Josh

  • Hero Member
  • *****
  • Posts: 1274
Re: If (qword-longint) question
« Reply #6 on: June 22, 2018, 04:58:08 pm »
Hi Thaddy

Thanks adding the {$Q-} does solve my issue, as it allows me to run with the debugger :)

So I have defined Disable_Range_Check in my debug mode project option.
I can now disable it through the project and units as I come across them, and still keeping the overflow checking in rest of code, It will then give me time to correct the code later....  With a big masive TODO marked... So I do not forgot...

Thanks for your prompt help Thaddy.

Code: Pascal  [Select][+][-]
  1. {$ifdef Disable_Range_Check}{$Q-}{$endif}
  2. if int64(x-y)<-500 then showmessage('Negative 500')
  3. else showmessage('Positive');
  4. {$ifdef Disable_Range_Check}{$Q+}{$endif}  
  5.  

The best way to get accurate information on the forum is to post something wrong and wait for corrections.

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: If (qword-longint) question
« Reply #7 on: June 22, 2018, 05:14:12 pm »
You can range checks on or off from the command line fpc -B -Cr- or in the project options of Lazarus. Note it needs a full rebuild, because otherwise units that are compiled in {$Q+} mode are kept. Also note that range checks is a local option, maybe hard to "fix" when{$push}/{pop} is used.
In your case it may be better to NOT use a qword but an int64 OR cast the result to int64.
« Last Edit: June 22, 2018, 05:16:57 pm by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Josh

  • Hero Member
  • *****
  • Posts: 1274
Re: If (qword-longint) question
« Reply #8 on: June 22, 2018, 05:33:37 pm »
Hi Thaddy,

Unfortunately the codebase is not mine, I am just enhancing it a bit and adding a basic UI to it.

I am hoping using the IFDEF sequence I can just turn it off when I know it would otherwise generate an error whilst debugging.

I agree changing all to INT64 would be the ideal, but some of the values are coming from and to external routines and hardware. ANd I would like to leave all that code alone as its been working for many years without issue.

Will probably create some autoconverter/check routine that can handle the different types and preserve their respective types.

Thanks.


If (longint-qword)<-500 generates an error; I thought the resulting (longint-qword) would be a longint as I am subracting a qword from longint.. Just for a quick sanity check
« Last Edit: June 22, 2018, 05:45:38 pm by josh »
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

jamie

  • Hero Member
  • *****
  • Posts: 6130
Re: If (qword-longint) question
« Reply #9 on: June 22, 2018, 11:04:38 pm »
Last time I checked the LongInt is a 32 bit integer, even in 64 bit mode,,.

QWORD is 64 bit non integer;

its like BYTE-WORD; The compile may accept that because it converts it to a integer in the
background for evaluation but, I am sure there will be an error at some point.
The only true wisdom is knowing you know nothing

birin

  • New member
  • *
  • Posts: 9
Re: If (qword-longint) question
« Reply #10 on: June 23, 2018, 12:26:00 am »
Hi josh,

I'm not sure of undertanding your question (I'm french).

If X is QWord and Y is QWord, then (X - Y) is QWord.
QWord is unsigned number.
(unsigned number) < 0 is simply not possible !

If X is a QWord and Y is any integer type, then the compiler converts Y to QWord to do the (X - Y) calculation, because QWord as the bigest possible value of any inter types.

Then, "X - Y < 0" is alwais false if X (or Y) is a QWord.

Is this correct ?

 

TinyPortal © 2005-2018