Introduction
In RISC-V, floating-point comparison instructions compare two
values in floating-point registers and write an integer result
(1 for true, 0 for false) into a general-purpose integer
register.
Comparison Instructions
For single-precision (.s) and double-precision (.d) floats,
use the following instructions where the destination rd is an
integer register and the sources rs1 and rs2 are
floating-point registers:
- Equal to (feq): Sets rd = 1 if rs1 == rs2, else 0.
- feq.s rd, rs1, rs2 (Single-precision)
- feq.d rd, rs1, rs2 (Double-precision)
- Less than (flt): Sets rd = 1 if rs1 < rs2, else 0.
- flt.s rd, rs1, rs2 (Single-precision)
- flt.d rd, rs1, rs2 (Double-precision)
- Less than or equal to (fle):
Sets rd = 1 if rs1 <= rs2, else 0.
- fle.s rd, rs1, rs2 (Single-precision)
- fle.d rd, rs1, rs2 (Double-precision)
Greater Than or Greater Than or Equal
RISC-V does not have dedicated fgt or fge instructions.
Instead, you swap the source registers:
- To check if rs1 > rs2, use flt.s rd, rs2, rs1 (swap source registers).
- To check if rs1 >= rs2, use fle.s rd, rs2, rs1 (swap source registers).
Example Code
# Compare fa0 and fa1 (single-precision floats)
# Check if fa0 < fa1
flt.s t0, fa0, fa1 # t0 = (fa0 < fa1) ? 1 : 0
bnez t0, less_than # Branch if t0 != 0 (true)
Test Two Floating-Point Numbers For Equality
It can be tricky to compare two floating-point number;
Especially if they came from two different calculations.
It is probably better to test them against the
absolute value of the difference between them
(f1 - f2).
If the difference is small enough, they
can be considered to be equal. (This very much depends
on the problem you are trying to solve.)
# test if two floating-point numbers are equal
# for this example the tolerance is 0.00001
difference = | f1 - f2 | # absolute difference
if difference <= 0.00001 ? 1 : 0