# Implement the <=> three-way comparison operator on numbers

In C++, there exists a a <=> b three-way comparison operator that, for numerical types, does the following:

• If a < b, then return a negative number.
• If a = b, then return a (mathematically speaking) sign-less number.
• If a > b, then return a positive number.

## The Challenge

Implement the shortest full program, function, method, or custom operator such that, when given two numbers of the same type a and b,

• If a < b, then return -1.
• If a = b, then return 0.
• If a > b, then return 1.

### Notes

• If you're writing in x86 assembly, this question may be of use to you.
• This is , so shortest answer in bytes wins!
• Do we have to handle all combinations of inputs? (I.e. can we assume that a - b will yield the arithmetic result, even when a is the lowest representable value and b is the highest?) Commented Mar 20, 2023 at 13:15
• @TobySpeight You will need to handle all combinations of inputs. Commented Mar 20, 2023 at 13:22
• Note that the C++ 3-way comparison is actually "compares equal to 0" and "compares less than 0" and "compares greater than 0". 1 and -1 are explicitly not required, by design, unlike your ask. I only mention this because your first paragraphs are not true.
– Yakk
Commented Mar 21, 2023 at 14:57
• If a language has support for multiple numeric types, such as integers and floating point numbers, does it need to support all of them? Basically every solution using subtraction and supporting floating point numbers doesn't work. Commented Mar 22, 2023 at 9:47
• @Tyilo the original draft of this challenge in sandbox had a bonus for supporting multiple numeric types, but was cut because "bonuses are bad". Pick whichever numeric type leads to the shortest solution. Commented Mar 22, 2023 at 13:04

# BQN, 2 bytes

×-


Try it at BQN REPL

×       # sign of
-      # left arg minus right arg


# BQN, 3 bytes

<->


Try it at BQN REPL

This clearly isn't the shortest possible solution in BQN (see above), but it is particularly visually appealing due to its similarity to the C++/Perl/etc <=> operator.

<->     # 3-element train abc
# ( x abc y expands to: (x a y) b (x c y) )
<       # left arg < right arg
-      # minus
>     # left arg > right arg


(a similar 'reverse-comparison' operator - >-< is also possible and also [I think] looks nice)

• Polyglots with Dyalog APL too Commented Mar 20, 2023 at 12:37
• Does this handle overflows? Commented Mar 21, 2023 at 6:16
• @MooingDuck - Yes and yes. The first one is helped by BQN's representation of overflowing-numbers as infinity (type 1e1000 into the REPL to see); the second one only needs to compare two booleans so doesn't have a problem. Commented Mar 21, 2023 at 7:53
• Isn't what you call "reverse-comparison" operator actually the correct answer to this question, and not the other one?
– wimi
Commented Mar 22, 2023 at 9:22
• @wimi - Hm - I think you're right (that >-< and not <-> is equivalent to <=>). The question itself just states that we are 'given two numbers', without specifying the order, but I agree that they're the wrong way around... That's a pity Commented Mar 22, 2023 at 11:25

# polyglot, 3 bytes

<=>


Try it in Perl!

<Insert other languages that already have the exact <=> operator here>

• is this valid? it's not a function, after all... Commented Mar 20, 2023 at 11:39
• I don't know, really. The challenge reads "Implement the shortest full program, function, method, or custom operator...". It's an operator. Obviously it isn't custom, because it's a built-in, and for the same reason I didn't implement it myself, but otherwise it seems Ok... Commented Mar 20, 2023 at 11:42
• ah, didn't see the part about custom operators being explicitly allowed... but yeah it does still feel on the line Commented Mar 20, 2023 at 11:55
• I'm not sure, since the OP speaks of C++, where you can define custom operators, and asks us to implement it.. simply inserting the operator you chose in an answer would not do, the code should implement it Commented Mar 22, 2023 at 14:41
• @Kaddath - I agree with you, but currently I count at least 8 built-in answers (Python 2, Java, 05AB1E, etc) that don't implement anything. That's why I feel it's appropriate to put all the boring built-ins together into a 'community wiki' answer... Commented Mar 22, 2023 at 16:08

# Python 2, 3 bytes

cmp


A built-in function that accepts $$\a\$$ and $$\b\$$ and returns $$\a \lt = \gt b\$$.

Try it online!

# JavaScript (ES6), 17 bytes

Expects (a)(b).

a=>b=>(a>b)-(a<b)


Try it online!

• 3 bytes can be cut down by using Math.sign(a-b)
– cdm
Commented Mar 21, 2023 at 16:52
• @cmd We would still need to take a and b as input, for a total of +3 bytes. (If we had a Math.cmp builtin taking 2 arguments, then the answer would be just Math.cmp.) Commented Mar 21, 2023 at 16:55

# Python 3, 22 bytes

lambda a,b:(a>b)-(a<b)


Try it online!

Python 3 lacks the builtin cmp

-1 thanks to Dominic van Essen

• Surely lambda a,b:(a>b)-(a<b) is only 22...? Commented Mar 20, 2023 at 8:57
• @DominicvanEssen Of course! Commented Mar 20, 2023 at 9:17

# Go, 52 51 bytes

func(a,b int)int{n:=1
for-1<n&&b-a<n{n--}
return-n}


Attempt This Online!

By @Kevin Cruijssen. Uses a for loop to get the return value rather than a chain of ifs.

### Changelog

• -1 by @naffetS

func(a,b int)int{n:=0
if a>b{n=1}
if a<b{n=-1}
return n}


Attempt This Online!

Go doesn't have any sort of built-in abs like C, or default type methods like Java, so a function it is. Go also doesn't have ternary expressions, so the old-school "set and check" pattern is needed.

• Wow, this seems really long! I don't speak GO, but can't you at least save a few bytes like this? Commented Mar 20, 2023 at 13:50
• Or even like this...? Commented Mar 20, 2023 at 14:01
• Yeah, the else was real obvious and somehow I missed that lol. Commented Mar 20, 2023 at 14:01
• 52 bytes Commented Mar 20, 2023 at 14:19
• -1 Commented Mar 22, 2023 at 3:52

# Vyxal, 2 bytes

-±


Try it Online!

Takes input as b then a. Simply subtract the two numbers and get the sign of the result.

Alternatively a more fun looking, symbol only answer comes in at 17 bytes:

## Vyxal, 17 bytes

-:::-<[::-$~-|:]/  Try it Online! Also takes b then a. This answer is purely just for fun, and could be made shorter by using numbers and letters (-D0<[N|:]/). ### Explained -:::-<[::-$~-|:]/
-:                # Subtract the two numbers and push a copy
::-             # Push 0 to the stack by subtracting the top of the stack from itself
<            # Is the original top of the stack < 0?
[           # If so:
::         #   Duplicate the top of the stack twice. This could just be D, but that wouldn't be a symbol.
-        #   Subtract those copies to get 0 again.
$~- # Push the 0 under the top of the stack, and subtract without popping. The stack is now [0, a - b, -(a - b)] | # Otherwise: : # Just duplicate the top of the stack ] # this whole if statement was to make sure there was [a - b, abs(a - b)] as the stack / # Divide the top two stack items to get either -1, 0 or 1. negative/positive = -1, 0/0 = 0 and positive/positive = 1  • -:ȧ/ or ₌><- for a non builtin Commented Mar 22, 2023 at 3:49 # Java (JDK), 14 bytes Float::compare  Try it online! ## Java (JDK), 13 bytes Long::compare  Try it online! Only supports integers. • For a more general solution: Comparable::compareTo (not golfier but felt like sticking this in a comment) Commented Mar 20, 2023 at 1:40 • This answer does not satisfy the question. Float.compare() returns a positive, zero, or negative number to indicate ordering, not +1, 0, -1. The problem is that the question is more restrictive than what programming languages actually prescribe. Commented Mar 21, 2023 at 15:28 • @Nayuki Did you try testing the code through the TIO link in my answer? It never returns anything other than -1, 0, or 1. On Code Golf, "a programming language is defined by its implementation". My code works on this implementation (always giving the correct outputs), so it is a valid submission. Commented Mar 21, 2023 at 16:35 • Most implementations do return -1, 0, or 1 for the static compare methods. (In fact, it'd be strange to have an implementation not return one of those, as that doesn't make it any easier to implement.) For example, you can see OpenJDK's source for Float here: github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/… Commented Mar 21, 2023 at 16:36 • @Nayuki That doesn't matter. The consensus is that languages are defined by implementation, not specification. See codegolf.meta.stackexchange.com/questions/7832/…, codegolf.meta.stackexchange.com/a/14339/99986. So it's perfectly valid to rely on undefined or implementation-dependent behavior. See codegolf.meta.stackexchange.com/questions/5486/… as well as the comments there. Commented Mar 21, 2023 at 17:07 # Excel, 12 bytes =SIGN(A1-B1)  where A1 and B1 contain a and b respectively. • This does not appear to handle overflows Commented Mar 21, 2023 at 6:17 # Nibbles, 1.5 bytes (3 nibbles) $-

$- # full program $-$@ # with implicit args shown; $          # get sign of
$# arg1 - # minus @ # arg2  # K (ngn/k), 9 bytes 1&-_1^-%-  Try it online! K lacks a sign builtin, which makes this a bit trickier. -%- negative square root of a-b. This is negative if a>b, zero if a=b and -0n (negative null value) if a<b. 1^ Replace null with 1. -_ floor and negate the number. In combination with the earlier - this does a ceil on the square root. 1& take the minimum of 1 and this number. If the input was restricted to integers, 0 1' would calculate the sign, leading to 0 1'- as a full solution. • If the input was restricted to integers, you could also do 1&-1|-... Commented Mar 22, 2023 at 3:47 # J, 3 bytes *@-  Try it online! The 3-byte solution >-< featured in a few other answers also works for the same byte count (greater-than minus less-than). Works for any numeric type. Anonymous dyad. ## Explanation *@- * sign @ of - difference  • Looks like a dyad to me. Commented Mar 21, 2023 at 1:19 • @south Right you are! Heavens know why I said monad lol Commented Mar 21, 2023 at 2:49 • Outputs the wrong answer for (-1e308, -1e308) => _1 and (-1e308, 1e308) => 0 Commented Mar 22, 2023 at 9:45 • @Tyilo OP clarified that we can pick whichever type works for the golf. The numbers you provided are floating point numbers. I pick the integer type, which you will note my solution works well for. If you insist on numbers so large, you can use the extended type: (-10^308x) f (-10^308x) outputs 0 as expected. Commented Mar 22, 2023 at 17:17 • @Tyilo I suppose, fair enough! Just shows it works so long as the input isn't deviously crafted :) Commented Mar 23, 2023 at 4:12 # Raku, 8 bytes +(*cmp*)  Try it online! cmp is Raku's built-in smart comparison operator, and *cmp* is an anonymous function that passes its arguments to that operator. Unfortunately for this challenge, cmp doesn't return -1, 1, or 0, but one of the enumerated values Less, More, or Same, so the prefix + operator converts those values into their integer values. The non-golfy solution would be to just compose the two operators: &prefix:<+> o &[cmp]  • can use cmp to not write the space Commented Mar 21, 2023 at 14:02 • @MustafaAydın Huh! I assumed cmp was the stringwise version of <=> as in Perl 5, but it's smarter than that. Thanks! – Sean Commented Mar 24, 2023 at 20:09 # Kotlin, 16 bytes Float::compareTo  Try it online! Annoyingly, longer than Java. # Kotlin, 14 bytes Int::compareTo  Try it online! Works only on ints (I edited this after seeing that Java got edited). # R, 15 bytes \(a,b)sign(a-b)  Attempt This Online! • It would have been cooler if you'd made it inline as %<=>%, though... Commented Mar 20, 2023 at 7:35 # 05AB1E, 2 bytes .S  Builtin. Takes the inputs in the order $$\b,a\$$. Try it online. Explanation: .S # Compare the second (implicit) input-integer a with the first (implicit) # input-integer b, and push -1 if a<b; 0 if a==b; or 1 if a>b # (which is output implicitly as result)  ## HP‑41C series, 9 11 Bytes a needs to be entered first, then b, so a is placed in the Y register and b in the X register. 01♦LBL⸆S 5 Bytes global label requires 4 + m Bytes 02 SF 24 2 Bytes ignore “out of range” errors, and instead return ±9.999999999E99 as an approximation 03 − 1 Byte X ≔ Y − X 04 X≠0? 1 Byte if X = 0 then skip next line 05 SIGN 1 Byte ↯ SIGN returns 1 for zero 06 RTN 1 Byte RTN does not affect local label search  • Does work also on the Free42 calculator Commented Mar 21, 2023 at 10:17 # Golfscript, 7 bytes .~>\~<-  read from stdin # explanation: . # duplicate ~ # unpack > # gt \ # store the result and get duplicated stdin again ~ # unpack < # lt - # gt-lt  • Welcome to Code Golf! Commented Mar 21, 2023 at 22:23 # Burlesque, 2 bytes cm  Try it online! Built in compare. # PIC16F88x Machine Code, 6 words (84 bits) A function that expects a to be at address 0x70 in memory, and b to be in register W. Returns the result in register W. The PIC16 uses 14-bit instruction words. Because the number of words is even, this function can be represented exactly in hex with no padding: 0bc1d03d001ff0dfff401  In mpasm syntax, that is:  SUBWF 0x70,F ; Subtract W from the value at 0x70. Leave the result at ; 0x70. BTFSC STATUS,2 ; Check the zero flag (bit 2 of the STATUS register) and skip ; the next instruction if it's not set. RETLW 0x00 ; Set the W register to 0 and return. BTFSC 0x70,7 ; Skip the next instruction if the MSb of the value at 0x70 ; is 0 (i.e. the result of subtraction is positive). RETLW 0xFF ; Set the W register to 0xff (-1) and return. RETLW 0x01 ; Set the W register to 1 and return.  Bit for bit, this is encoded as: 00 0010 1111 0000 00 0010 SUBWF 111 0000 0x70 1 F 01 1101 0000 0011 01 11 BTFSC 000 0011 STATUS 01 0 2 11 0100 0000 0000 11 01 RETLW 0000 0000 0x00 00 (ignored) 01 1111 1111 0000 01 11 BTFSC 111 0000 0x70 11 1 7 11 0111 1111 1111 11 01 RETLW 1111 1111 0xff 11 (ignored) 11 0100 0000 0001 11 01 RETLW 0000 0001 0x01 00 (ignored)  The PIC16F88x family of microcontrollers have four memory banks of 128 bytes each. (These are actually bytes this time, and not 14-bit words.) Which one is used depends on the value of the STATUS register. However, addresses 0x70 through 0x7f are the same on all banks, so by placing the operands there the function doesn't have to change banks to access them. I'm not aware of any standard calling convention as far as argument location goes, but the return value being in register W is standard (hence the existence of the RETLW instruction). # K (ngn/k), 5 bytes -/<?,  Try it online! • , concatenate the inputs • <? grade-up the distinct-ified result from above; if the first value is smaller than the second, the result will be 0 1; if larger, 1 0, if the same, ,0 • -/ run a minus-reduce and (implicitly) return An alternative version that takes the input as a list of two numbers is -/<?:. • Aah, how did I miss this? Only had the APLcart version ({⊃(⍋-⍒)⍺⍵}) in mind, which would've been too long because of the two grades – ovs Commented Mar 24, 2023 at 6:55 ## Pascal, 55 Bytes function f(a,b:real):real;begin f:=ord(a>b)-ord(a<b)end  # Retina 0.8.2, 29 bytes \d+$*
(1*) \1
0
1+0
1
01+
-1


Try it online! Link includes test cases. Only works on non-negative integers. Explanation:

\d+
\$*


Convert to unary.

(1*) \1
0


Try to subtract; this will leave 0 if a = b.

1+0
1


If a > b then replace the result with 1.

01+
-1


If a < b then replace the result with -1.

# Charcoal, 12 bytes

ＮθＮηＩ⁻›θη‹θη


Try it online! Link is to verbose version of code. Explanation: Port of @Arnauld's JavaScript answer.

Alternative approach, also 12 bytes:

≔⁻ＮＮθＩ÷θ∨↔θ¹


Try it online! Link is to verbose version of code. Explanation: Divides the difference between the numbers by the absolute value of the difference, or 1 if that's zero.

# MathGolf, 2 bytes

,σ


Try it online.

Explanation:

,  # Subtract the second (implicit) input by the first (implicit) input: b-a
σ # Get the sign of that (-1 if <0; 0 if ==0; 1 if >0)
# (after which the entire stack is output implicitly as result)


# C (gcc), 22 bytes

This is practically @TobySpeight's answer now since he changed the entire algorithm.

f(a,b){a=(a>b)-(a<b);}


Try it online!

• The more usual implementation, a=(a>b)-(a<b) is not only 4 bytes shorter, but also correct for values where a-=b is undefined due to signed integer overflow. Commented Mar 20, 2023 at 13:18
• @TobySpeight I didn't think of that ... thanks :) Commented Mar 20, 2023 at 13:37

# Pip, 4 bytes

aCMb


There's a built-in operator for that. (Fun fact: in my original designs for Pip, this operator was <=>, until I realized that having a 3-character operator in a golfing language was silly.)

Attempt This Online!

# Pyth, 3 bytes

._-


Try it online!

Defines a function which takes two inputs b, a.

### Explanation

  -    # subtract the second argument from the first
._     # take the sign

• It makes an emoticon :D Commented Mar 24, 2023 at 19:46

# Julia 1.0, 13 3 bytes

cmp


Try it online!

-10 bytes thanks to MarcMush: use cmp

## Alternate solution, 13 bytes

a%b=sign(a-b)


Try it online!

## Alternate solution (15 bytes)

a%b=(a>b)-(a<b)


Try it online!

Some operators have lower precedence than < and >. Redefining one of them as - removes the need for parentheses but doesn't save bytes overall:

~=-
a%b=a>b~a<b


Try it online!

• 3 bytes : cmp Commented Mar 21, 2023 at 18:41
• Good catch! I've added your solution here, but it probably deserves its own answer. Commented Mar 21, 2023 at 19:38

# Piet + ascii-piet, 21 bytes (4×7=28 codels)

vekabrA krbtkFbks?Tbb


Try Piet online!

Just a minor variation from my answer to "output the sign". Takes two numbers and subtracts instead of taking just one number, and then the rest follows the same logic.

A1->A4
inN inN -    [a-b] Take two numbers and subtract
A4->A7->B7->B5
dup 1 ! > !  [a-b a-b<=0]
CC+          [a-b] Continue on row B if a-b<=0, shift to row C otherwise
B5->B2
! 1 -        [(a-b==0)-1] -1 if a-b!=0 (which implies a-b<0), 0 otherwise
C5->C2
1            [a-b 1] Ignore the previous number and push 1
C2->C1
outN         Print the top number and exit