Recent

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

SonnyBoyXXl

  • Jr. Member
  • **
  • Posts: 57
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

  • Full Member
  • ***
  • Posts: 143
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: 2319
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: 1271
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.

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
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 »
Specialize a type, not a var.

Red_prig

  • Full Member
  • ***
  • Posts: 143
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

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: three-way comparison
« Reply #6 on: November 28, 2022, 09:26:30 pm »
Posts crossed. Plz read my reply first.
Specialize a type, not a var.

Red_prig

  • Full Member
  • ***
  • Posts: 143
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 ()

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: three-way comparison
« Reply #8 on: November 28, 2022, 09:30:12 pm »
Specialize a type, not a var.

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
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 »
Specialize a type, not a var.

Red_prig

  • Full Member
  • ***
  • Posts: 143
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

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
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... O:-) And get found out at some point....Like you just have been...
Specialize a type, not a var.

Kays

  • Hero Member
  • *****
  • Posts: 569
  • Whasup!?
    • KaiBurghardt.de
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: 394
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 . . .');
  23. readln;
  24. end.
  25.  

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: three-way comparison
« Reply #14 on: November 28, 2022, 10:13:57 pm »
No, not really, the ** implementation as operator is already used in the maths unit. It is just shorthand for Power(x,y). So overriding it is a conflict of interest.

I would stick to a proper implementation of ternary logic. And it is free and fast.
« Last Edit: November 28, 2022, 10:29:30 pm by Thaddy »
Specialize a type, not a var.

 

TinyPortal © 2005-2018