Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why does money.New() take an int64 #30

Closed
vendion opened this issue Mar 30, 2018 · 4 comments
Closed

Why does money.New() take an int64 #30

vendion opened this issue Mar 30, 2018 · 4 comments

Comments

@vendion
Copy link

vendion commented Mar 30, 2018

By making money.New() accept an int64 rather than a float or more inline with other libraries do (possibly more idiomatic?) a *big.Float it cuts off the ability to use a value with a decimal amount during allocation.

dollar := money.New(3.50, "USD") // type error
dollar := money.New(big.NewFloat(3.50), "USD") // would work
@Rhymond
Copy link
Owner

Rhymond commented Apr 2, 2018

Hi @vendion,

Why you see problem using 350 instead of 3.50?
By the way, floating-points and currency are working well together.

"If I had a dime for every time I've seen someone use FLOAT to store currency, I'd have $999.997634" -- Bill Karwin

if your project requires usage of float, go-money shouldn't be responsible for type conversion. My suggestion would be to do type conversion inside your project (if required)

@vendion
Copy link
Author

vendion commented Apr 2, 2018

So some of the issues I see with taking ints are: 1) 350 isn't as obvious as 3.50 if hardcoded (for whatever reason that may be) at first glance it's impossible to know if that's three hundred and fifty, or three dollars (or insert your currency here) and fifty cents. 2) It is fairly common, at least from my experience, to use a datatype similar to a float with fixed precession to store currency in a database (https://www.postgresql.org/docs/current/static/datatype-money.html).

One advantage Go's *big.Float has is the ability to set the precision on it as well https://golang.org/pkg/math/big/#Float.SetPrec so it could be set to a precision of 2 places if need be. So in the case of the Bill Karwin quote he would have either $999.99 or maybe $1000depending on the rounding mode (by default it's the latter https://play.golang.org/p/p2wKfpbiofy BTW). Although that may not be the best example.

I wasn't trying to say that this implementation was bad/wrong or anything, it just seems odd to me and when I was originally looking for a good way to handle currency, it seemed like *big.Float was suggested more often, and even used in another package to handle formatting currency https://github.com/leekchan/accounting#caution

@vendion
Copy link
Author

vendion commented Apr 16, 2018

Anyways, closing this as you pretty much answered my question with the fact that go-money won't handle conversions

@vendion vendion closed this as completed Apr 16, 2018
@dey-dey
Copy link

dey-dey commented Oct 28, 2021

Just a thought, but I would add here that while forcing the responsibility on lib users to do their own float conversion minimizes complexity for go-money, it also seems handling it in the library itself could prevent a lot of user error. Having a well-tested package that exports conversion functionality would relieve users of the library of a lot of duty they may not be knowledgable enough to have, especially for those new to Go. It's a decent enough use case to take these integers and display/work with floats on the frontend, so it would be nice to have this handled in an authoritative library and not have every lib user think about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants