Faster and safer way of comparing two currency values is certainly to map the variables to their internal Int64 binary representation, as such:

function CompCurrency(var A,B: currency): Int64;
var A64: Int64 absolute A;
    B64: Int64 absolute B;
begin
  result := A64-B64;
end;

This will avoid any rounding error during comparison (working with *10000 integer values), and will be faster than the default implementation, which uses the FPU (or SSE2 under x64 architecture) instructions.

In SynCommons.pas, there are some functions using the Int64 binary representation (accessible either as PInt64(aCurrencyVar)^ or the absolute syntax).
They will by-pass the FPU/SSE2 use, and are therefore both fast and safe at the same time:

- function Curr64ToString(Value: Int64): string;
- function StrToCurr64(P: PUTF8Char): Int64;
- function Curr64ToStr(Value: Int64): RawUTF8;
- function Curr64ToPChar(Value: Int64; Dest: PUTF8Char): PtrInt;
- function StrCurr64(P: PAnsiChar; const Value: Int64): PAnsiChar;

Using those functions can be much faster for textual conversion than using the standard FloatToText() implementation. They are validated with provided regression tests.

Of course, in normal code, it is certainly not worth using the Int64 binary representation of currency, but rely on the default compiler/RTL implementation. In all cases, having optimized functions was a need for both speed and accuracy of our ORM data processing, and also for external database handling.

Comments and feedback are welcome on our forum.