What is a safe Haskell data type to store and manipulate Money values?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
26 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: What is a safe Haskell data type to store and manipulate Money values?

Richard A. O'Keefe

> On 5/04/2017, at 5:08 PM, Joachim Durchholz <[hidden email]> wrote:
>
> What languages besides Cobol actually make use of [decimal floats]?

Aside from obvious things like PL/I and ABAP,
there is an official way to use decimal floats in C,
if you have them.  gcc is *part* of the way there.
https://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html

Having used gcc on a machine with no hardware binary floats,
where binary floats were emulated, I'd rather like to use
decimal floats on my Macs.  However gcc 5.3.0 on my laptop
*recognises* decimal floats but just says that it's not
supported on this target.  The decNumber library's licences
are perfectly compatible with gcc.

Solaris Studio supports decimal floats on SPARCX[+] processors,
for some value of "support" strictly between 0 and 1.  (It knows
the _Decimal64 type but you have to call special intrinsics to
get the arithmetic instructions, though you _do_ get them.)

>
> Are there any plans by Intel or AMD to support them?
> I'm not aware of any, but you never know.

Perhaps if Microsoft realised that _Decimal128 is exactly what
they want for Excel, and put pressure on Intel?
Intel do provide a decimal floating point *library*
https://software.intel.com/en-us/articles/intel-decimal-floating-point-math-library
http://www.netlib.org/misc/intel/
so in *some* sense they already support decimal floats.
The date in the README file is "August 15, 2011", so we've
had an "official" decimal floating point library for Intel
systems for nearly 8 years (first release in 2009).
[Amusingly, the only difference between LIBRARY/RUNOSX and
LIBRARY/RUNLINUX is that the OSX version has a space after
"./linuxbuild".]   The code is in C and has support for
big-endian machines, and eula.txt is very permissive, so
it looks very much as though nobody needs to go without.



_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: What is a safe Haskell data type to store and manipulate Money values?

David Turner-2
In reply to this post by Richard A. O'Keefe
On 5 Apr 2017 04:15, "Richard A. O'Keefe" <[hidden email]> wrote:

> On 4/04/2017, at 11:21 PM, Saurabh Nanda <[hidden email]> wrote:

> * Allowing end-customers to see product prices in different currencies (so, currency conversion)
> * Various reports to see total sales, total receivables, and total payables (basically a **very** small subset of small-business accounting)

There are Haskell data types that will let you compute sums and
differences of money times percentages exactly.  For final reporting,
you will need to round.

Careful here. I've worked on systems where one of the fundamental requirements is that any sums of columns of numbers representing amounts of money _must_ add up precisely. In a situation where you apply different tax rates to different items you could either calculate the tax on each one (and round it to £0.01) or group the items together into subtotals that all had the same tax rate, then calculate the tax on the subtotal (and round it to £0.01). What you couldn't do was keep track of the precise amount of tax on each item and round it at the very end for reporting purposes only, because you had to show the tax breakdown (using numbers rounded to £0.01) and if your working calculation was more precise then the numbers in the report wouldn't always quite add up, which would upset the auditors.

This is why it's frequently recommended to use an integral type representing multiples of your smallest reporting unit for representing money.

The rounding rule is *probably* the one
you learned in school, but you really should check with a friendly
accountant.

The actual rounding rule in question seemed relatively unimportant compared with the requirement that numbers in reports must add up precisely, although I also agree that you should check with an accountant. They may not even mention the columns-of-numbers-must-add-up thing because that's so fundamental it almost goes without saying.

Cheers,

David







_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: What is a safe Haskell data type to store and manipulate Money values?

Joachim Durchholz
Am 06.04.2017 um 08:32 schrieb David Turner:
> They may not even mention the columns-of-numbers-must-add-up
> thing because that's so fundamental it almost goes without saying.

I have seen very different policies on that.
 From "it must be exact" to "don't worry if the difference is less than
0.5*number-of-summands because then it could be a round-off error".
It all depends on whether there's somebody who wants to double-check.

For taxes calculations (any percentages actually), round-off errors are
unavoidable. People tend to shift them around to minimize that error -
that's why taxes are typically applied to sums, not to individual
summands; the per-summand tax breakdowns are then taken to be purely
informative and need not add up.
And then there's "creative accounting" where these differences are
larger than just a round-off error - that's what auditors are trying to
find, and they don't want your numbers to add up because that in itself
is relevant, they want your numbers to add up because it makes their
jobs easier.
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: What is a safe Haskell data type to store and manipulate Money values?

Richard A. O'Keefe
In reply to this post by David Turner-2

> On 6/04/2017, at 6:32 PM, David Turner <[hidden email]> wrote:
> Careful here. I've worked on systems where one of the fundamental requirements is that any sums of columns of numbers representing amounts of money _must_ add up precisely. In a situation where you apply different tax rates to different items you could either calculate the tax on each one (and round it to £0.01) or group the items together into subtotals that all had the same tax rate, then calculate the tax on the subtotal (and round it to £0.01). What you couldn't do was keep track of the precise amount of tax on each item and round it at the very end for reporting purposes only, because you had to show the tax breakdown (using numbers rounded to £0.01) and if your working calculation was more precise then the numbers in the report wouldn't always quite add up, which would upset the auditors.

For what it's worth, there are rounding algorithms that work on a whole bunch of numbers
at once, ensuring that the total of the rounded numbers is equal to the total of the
unrounded numbers.


_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: What is a safe Haskell data type to store and manipulate Money values?

Bardur Arantsson-2
On 2017-04-07 00:35, Richard A. O'Keefe wrote:
>
>> On 6/04/2017, at 6:32 PM, David Turner <[hidden email]> wrote:
>> Careful here. I've worked on systems where one of the fundamental requirements is that any sums of columns of numbers representing amounts of money _must_ add up precisely. In a situation where you apply different tax rates to different items you could either calculate the tax on each one (and round it to £0.01) or group the items together into subtotals that all had the same tax rate, then calculate the tax on the subtotal (and round it to £0.01). What you couldn't do was keep track of the precise amount of tax on each item and round it at the very end for reporting purposes only, because you had to show the tax breakdown (using numbers rounded to £0.01) and if your working calculation was more precise then the numbers in the report wouldn't always quite add up, which would upset the auditors.
>
> For what it's worth, there are rounding algorithms that work on a whole bunch of numbers
> at once, ensuring that the total of the rounded numbers is equal to the total of the
> unrounded numbers.

REFERENCES TO LITERATURE, PLEASE!

(I'm not being sarcastic -- this would be very useful to almost anyone
dealing with monetary amounts... anywhere.)

Cheers,

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: What is a safe Haskell data type to store and manipulate Money values?

Richard A. O'Keefe

> On 7/04/2017, at 10:42 AM, Bardur Arantsson <[hidden email]> wrote:
>
> On 2017-04-07 00:35, Richard A. O'Keefe wrote:
>> For what it's worth, there are rounding algorithms that work on a whole bunch of numbers
>> at once, ensuring that the total of the rounded numbers is equal to the total of the
>> unrounded numbers.
>
> REFERENCES TO LITERATURE, PLEASE!
>
> (I'm not being sarcastic -- this would be very useful to almost anyone
> dealing with monetary amounts... anywhere.)

I first saw mention of such an algorithm in a journal about 40 years ago.
I have a more recent memory of a paper by Knuth in a volume of his
collected papers that I cannot at the moment locate, but I believe this
is the article:
Two-Way Rounding
Author: Donald E. Knuth
Published in:
· Journal
SIAM Journal on Discrete Mathematics archive
Volume 8 Issue 2, May 1995
Pages 281 - 290
Society for Industrial and Applied Mathematics Philadelphia, PA, USA
table of contents doi>10.1137/S0895480194264757

Ah, FOUND IT.
Selected Papers on Design of Algorithms
Donald E. Knuth
CSL Lecture Notes Number 191
CSLI Publications, Stanford, California.
ISBN-13: 978-1-57586-582-9
ISBN-10:     1-57686-582-3
Chapter 16, pp 219-234 "Two-Way Rounding"
"Given n real numbers 0 <= x1 < 1, ..., 0 <= xn < 1,
and a permutation \sigma of {1,...,n}, we can always
find integers x'1 \in {0,1}, ..., x'n \in {0,1}
so that the partial sums x'1+...+x'k and
x'\sigma[1]+...+x'\sigma[k] differ from the
unrounded values x1+...+xk and
x\sigma[1...+x\sigma[k] by at most n/(n+1)
for 1 <= k <= n.  The latter bound is the best possible."
Section 1, An Application
"Sometimes it is desirable to round "spreadsheet" data to
larger units while preserving row and column totals and
the grand total."

This application to matrices has been studied by others.

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.421.2051&rep=rep1&type=pdf
Rounding of Sequences and Matrices, with Applications
"We show that any real matrix can be rounded to an integer matrix in
such a way that the rounding errors of all row sums are less than one,
and the rounding errors of all column sums as well as all sums of
consecutive row entries are less than two.
Such roundings can be computed in linear time."

http://people.mpi-inf.mpg.de/~doerr/papers/unbimatround.pdf
Unbiased Matrix Rounding
"We show several ways to round a real matrix to an integer one
such that the rounding errors in all rows and columns as well as
the whole matrix are less than one. ... our roundings also have a
rounding error of less than one in all initial intervals of rows
and columns.  Consequently, arbitrary intervals have an error of
at most two. ... The same result can be obtained via (dependent)
randomized rounding. This has the additional advantage that the
rounding is unbiased."

Here's a bunch of less formal discussions of the 1D case.

http://stackoverflow.com/questions/32544646/round-vector-of-numerics-to-integer-while-preserving-their-sum
http://stackoverflow.com/questions/792460/how-to-round-floats-to-integers-while-preserving-their-sum
https://explainextended.com/2009/09/21/rounding-numbers-preserving-their-sum/
https://biostatmatt.com/archives/2902


_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
12