Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

Author Topic: three-way comparison  (Read 882 times)

SonnyBoyXXl

• Jr. Member
• Posts: 56
three-way comparison
« on: November 28, 2022, 08:50:31 pm »
Working on DirectX Math 3.18 i found a very strange C++ code segment.
Code: C  [Select][+][-]
1. #if (__cplusplus >= 202002L)
2.         bool operator == (const XMFLOAT2&) const = default;
3.         auto operator <=> (const XMFLOAT2&) const = default;
4. #endif

The operator <=> is called a three-way comparison operator.
It returns -1 if a<b, returns 0 if a=b and returns 1 if b>a. So far so good. But how do I implement such operator for a type in pascal. I  think there is not a predefined operator at the moment?

Red_prig

• Jr. Member
• Posts: 95
Re: three-way comparison
« Reply #1 on: November 28, 2022, 09:00:23 pm »
There are several different ways, for example I did this:
Code: Pascal  [Select][+][-]
1. Result:=Integer(key1>key2)-Integer(key1<key2);

Zvoni

• Hero Member
• Posts: 1662
Re: three-way comparison
« Reply #2 on: November 28, 2022, 09:14:37 pm »
There are several different ways, for example I did this:
Code: Pascal  [Select][+][-]
1. Result:=Integer(key1>key2)-Integer(key1<key2);
You‘re implying that True „equals“ to 1 (the integer-cast)
Is this always the case? Or might True result to -1?
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Josh

• Hero Member
• Posts: 1047
Re: three-way comparison
« Reply #3 on: November 28, 2022, 09:18:44 pm »
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

• Hero Member
• Posts: 12898
Re: three-way comparison
« Reply #4 on: November 28, 2022, 09:23:06 pm »
In computer science that is called ternary logic. I have implemented it here, some time ago and in some forms.
Look at https://forum.lazarus.freepascal.org/index.php/topic,41144.msg295325.html#msg295325
(The Rosetta code entry is also written by me)
« Last Edit: November 28, 2022, 09:25:47 pm by Thaddy »
Who is responsable for that!! The caller or the callee.. Out! ya'll, NOW. In UTC time, please, so maybe Yesterday or tomorrow.

Red_prig

• Jr. Member
• Posts: 95
Re: three-way comparison
« Reply #5 on: November 28, 2022, 09:25:12 pm »
There are several different ways, for example I did this:
Code: Pascal  [Select][+][-]
1. Result:=Integer(key1>key2)-Integer(key1<key2);
You‘re implying that True „equals“ to 1 (the integer-cast)
Is this always the case? Or might True result to -1?

Can't speak for all architectures and pascal specs, but this at least works correctly on x86

• Hero Member
• Posts: 12898
Re: three-way comparison
« Reply #6 on: November 28, 2022, 09:26:30 pm »
Posts crossed. Plz read my reply first.
Who is responsable for that!! The caller or the callee.. Out! ya'll, NOW. In UTC time, please, so maybe Yesterday or tomorrow.

Red_prig

• Jr. Member
• Posts: 95
Re: three-way comparison
« Reply #7 on: November 28, 2022, 09:30:03 pm »
However, if this is an operator with one input variable, then it doesn’t matter, it’s just Sign ()

• Hero Member
• Posts: 12898
Re: three-way comparison
« Reply #8 on: November 28, 2022, 09:30:12 pm »
Who is responsable for that!! The caller or the callee.. Out! ya'll, NOW. In UTC time, please, so maybe Yesterday or tomorrow.

• Hero Member
• Posts: 12898
Re: three-way comparison
« Reply #9 on: November 28, 2022, 09:32:10 pm »
However, if this is an operator with one input variable, then it doesn’t matter, it’s just Sign ()
No it isn't.  Zero is ambiguous by nature. Zero can be minus zero which is just as valid. From a computer science pov this really matters.
What you propose is only half a solution. See my code.
« Last Edit: November 28, 2022, 09:33:43 pm by Thaddy »
Who is responsable for that!! The caller or the callee.. Out! ya'll, NOW. In UTC time, please, so maybe Yesterday or tomorrow.

Red_prig

• Jr. Member
• Posts: 95
Re: three-way comparison
« Reply #10 on: November 28, 2022, 09:33:24 pm »
However, if this is an operator with one input variable, then it doesn’t matter, it’s just Sign ()
No it isn't. zero can be minus zero. From a computer science pov this really matters.
What you propose is only half a solution. See my code.
Depends on the task

• Hero Member
• Posts: 12898
Re: three-way comparison
« Reply #11 on: November 28, 2022, 09:35:12 pm »
Depends on the task
No it depends on a thorough understanding of the theory.
Of course nitwits are allowed to take shortcuts... And get found out at some point....Like you just have been...
Who is responsable for that!! The caller or the callee.. Out! ya'll, NOW. In UTC time, please, so maybe Yesterday or tomorrow.

Kays

• Sr. Member
• Posts: 492
• Whasup!?
Re: three-way comparison
« Reply #12 on: November 28, 2022, 10:01:00 pm »
There are several different ways, for example I did this:
Code: Pascal  [Select][+][-]
1. Result:=Integer(key1>key2)-Integer(key1<key2);
You use ord to convert Boolean to integer.
Code: Pascal  [Select][+][-]
1. result := ord(key1 > key2) - ord(key1 < key2);

You‘re implying that True „equals“ to 1 (the integer-cast)
Is this always the case? Or might True result to -1?
Yes, Boolean is simply an enumeration data type, so
Code: Pascal  [Select][+][-]
1. type Boolean = (false, true);

would sign function not work?
https://www.freepascal.org/docs-html/rtl/math/sign.html
Yes, I would have mentioned that, too.
Code: Pascal  [Select][+][-]
1. result := math.sign(a - b);

It returns -1 if a<b, returns 0 if a=b and returns 1 if b>a. […] I  think there is not a predefined operator at the moment?
There is actually math.compareValue doing just what you want.
Code: Pascal  [Select][+][-]
1. result := math.compareValue(a, b)
« Last Edit: November 28, 2022, 10:07:36 pm by Kays »
Yours Sincerely
Kai Burghardt

BobDog

• Sr. Member
• Posts: 372
Re: three-way comparison
« Reply #13 on: November 28, 2022, 10:09:47 pm »

I believe ** is available for operator.
Code: Pascal  [Select][+][-]
1. uses
2. math;
3. function three(a,b:int32):integer;
4. begin
5. exit(sign(a-b));
6. end;
7.
8. Operator ** (a:int32;b:int32) z : int32;
9. begin
10. z:=sign(a-b);
11. exit(z);
12. end;
13.
14. begin
15. writeln(three(3,9));
16. writeln(three(3,3));
17. writeln(three(9,3));
18. writeln('-------');
19. writeln(3**9);
20. writeln(3**3);
21. writeln(9**3);
22. writeln('Done, press return to end . . .');
24. end.
25.