If you're at all concerned about precision and rounding this is a bad
idea. It's often important to be exact when dealing with money and
floating point types aren't exact. There's a good description of the
details here: http://docs.python.org/tutorial/floatingpoint.html
Use an integer type for exact representation, but watch for overflows.
If you need bigger numbers, look at package big.
- Evan
Instead of using fmt, I'd look in the package strconv and use Uitob64
as inspiration. Alter it so it's always base 10 and inserts a decimal
in the right place and that's probably what you want.
- Evan
Only accept clients with low incomes.
But seriously, are you panning on handling amounts anywhere near
$92,233,720,368,547,758.07? Picture how big you think, practically,
you might be going, and just be sure (you probably won't have to worry
about it) that your arithmetic always fits in the headroom.
bsr,
For addition, do you mean something like this.
> Also please give a hint on how can I detect overflow (or how to
> prevent the user from doing an overflow operation).
r := x + y
func Add(x, y Money) Money {
if y >= 0 {
if r < x {
panic("Money Add: overflow")
}
Thanks Peter, in that case, we should account for the case where
people are using individual atoms of precious metals as currency. It
might take more than the worlds total computational capacity to
perform a single transaction, but we'll work it out eventually.
I'm sure if bsr wants to use Zimbabwean currency with his software,
he'll answer my question accordingly and design his software around
it. As I said, set parameters on your system, make sure you have room
to operate within them, and enforce them to the degree required by
your use case.
> bsr,
>
>> Also please give a hint on how can I detect overflow (or how to
>> prevent the user from doing an overflow operation).
>
> For addition, do you mean something like this.
>
> func Add(x, y Money) Money {
> r := x + y
> if y >= 0 {
> if r < x {
> panic("Money Add: overflow")
> }
> } else {
> if r > x {
> panic("Money Add: overflow")
> }
> }
> return r
> }
Or this:
func Add(x, y Money) Money {
r := x + y
if (r ^ x) & (r ^ y) < 0 {
panic("Money Add: overflow")
}
return r
}
"Hacker's Delight" by Henry S. Warren contains lots of such goodies.
bsr,
Floating-point arithmetic is an approximation. People hate it when you
make approximations about their money.
What Every Computer Scientist Should Know About Floating-Point
Arithmetic
http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html
Use int64 as cents to represent dollars and cents. Watch for
truncation and rounding, particularly in intermediate results.
Maybe use big.Rat for intermediate results and then store only the legally rounded number.
Dnia 2015-03-27, o godz. 06:45:59
Manlio Perillo <manlio....@gmail.com> napisał(a):
> Using int64 as cents is not that simple.
> 1 cents / 2 = 0 cents, as an example, and I'm not sure banking software
> works this way.
It does. Just computational unit is scaled down. E.g. 1cu = 1/10**4 MU.
Then int64 can represent amount of +/- 922'337'203'685'477 currency units.