lmi-commits
[Top][All Lists]

## [lmi-commits] [lmi] valyuta/002 a3f1b6f 8/8: Probably prefer floating to

 From: Greg Chicares Subject: [lmi-commits] [lmi] valyuta/002 a3f1b6f 8/8: Probably prefer floating to integral datatype Date: Mon, 5 Oct 2020 19:57:19 -0400 (EDT)

```branch: valyuta/002
commit a3f1b6feda835e673f800a83af33f3bc675c7b7a
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

Probably prefer floating to integral datatype

- conversion to and from double cannot fail
- floating point already handles overflow and underflow gracefully
- integer math may be faster per se, but integral <-> floating
conversions are often required in lmi, and are costly

Another transient advantage is that suppressing this:
#define CURRENCY_UNIT_IS_CENTS
makes 'currency' do just about nothing, at a cost of just about
nothing.

For all its apparent complexity, UL is much like a bank account: an
account value is incremented by payments, like bank deposits; it is
decremented by various charges such as a bank might impose; and interest
is periodically credited on the current balance, introducing a floating-
point factor--but the balance is always an integral number of cents.

This all becomes clearer from a fresh point of view. Imagine that lmi
had always expressed account value in cents instead of dollars, and that
always been properly rounded. Then account value would always be an
exact integral number of cents, and it wouldn't matter whether it were
stored internally as 'double' or as 'int64_t'. It would need to be
multiplied by one hundred for printing, but that's just a convenience
for humans who think in terms of "dollars and cents", i.e., integral
dollars and integral cents separated by what looks like a decimal point,
but it's more like hours:minutes than rational arithmetic because the
smallest unit cannot be subdivided. The proper abstractions are full
minutes and full hours, translated to 59:59 or \$99.99 for printing.

CLI '--self_test' timings for x86_64 pc-linux-gnu:

master
naic, no solve      : 1.903e-02 s mean;    18879 us least of  53 runs
naic, specamt solve : 3.321e-02 s mean;    32989 us least of  31 runs
naic, ee prem solve : 3.054e-02 s mean;    30144 us least of  33 runs
finra, no solve     : 7.516e-03 s mean;     7275 us least of 100 runs
finra, specamt solve: 2.040e-02 s mean;    19940 us least of  50 runs
finra, ee prem solve: 1.909e-02 s mean;    18865 us least of  53 runs

naic, no solve      : 2.506e-02 s mean;    24715 us least of  40 runs
naic, specamt solve : 4.350e-02 s mean;    43029 us least of  23 runs
naic, ee prem solve : 3.974e-02 s mean;    39406 us least of  26 runs
finra, no solve     : 8.522e-03 s mean;     8183 us least of 100 runs
finra, specamt solve: 2.502e-02 s mean;    24580 us least of  40 runs
finra, ee prem solve: 2.326e-02 s mean;    22822 us least of  43 runs

naic, no solve      : 2.469e-02 s mean;    24428 us least of  41 runs
naic, specamt solve : 4.299e-02 s mean;    42701 us least of  24 runs
naic, ee prem solve : 3.928e-02 s mean;    39009 us least of  26 runs
finra, no solve     : 8.132e-03 s mean;     7911 us least of 100 runs
finra, specamt solve: 2.466e-02 s mean;    24213 us least of  41 runs
finra, ee prem solve: 2.293e-02 s mean;    22660 us least of  44 runs

naic, no solve      : 2.001e-02 s mean;    19763 us least of  50 runs
naic, specamt solve : 3.495e-02 s mean;    34712 us least of  29 runs
naic, ee prem solve : 3.204e-02 s mean;    31676 us least of  32 runs
finra, no solve     : 7.721e-03 s mean;     7374 us least of 100 runs
finra, specamt solve: 2.133e-02 s mean;    21018 us least of  47 runs
finra, ee prem solve: 1.986e-02 s mean;    19544 us least of  51 runs
---
currency.hpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/currency.hpp b/currency.hpp
index 283159f..1a0eaf8 100644
--- a/currency.hpp
+++ b/currency.hpp
@@ -34,7 +34,7 @@

#define CURRENCY_UNIT_IS_CENTS

-#define CURRENCY_HAS_INTEGER_DATATYPE
+//#define CURRENCY_HAS_INTEGER_DATATYPE

#if !defined CURRENCY_UNIT_IS_CENTS && defined CURRENCY_HAS_INTEGER_DATATYPE
#   error No can do!

```