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

Add Choose[BigDecimal] #637

Closed
dmurvihill opened this issue Mar 3, 2020 · 7 comments
Closed

Add Choose[BigDecimal] #637

dmurvihill opened this issue Mar 3, 2020 · 7 comments
Milestone

Comments

@dmurvihill
Copy link
Contributor

dmurvihill commented Mar 3, 2020

I was initially going to just do this as part of #636, but now I'm not sure if a Choose[BigDecimal] implicit is even a good idea.

Any practical generator of real numbers can never be truly uniform, as Gen.choose purports to be. This isn't a problem for choose[Double], choose[Long], or even choose[BigInt], as all three of those values have bounded precision anyway. But when we try to implement choose[BigDecimal], we have to somehow accept a new free variable, precision, that is not available via the Gen.choose interface.

One way around this could be: instead of implementing choose[BigDecimal], provide a Choose[BigDecimal] factory that accepts a precision and whose result the user could declare as implicit. Seems pretty clunky, but still maybe easier than writing a BigDecimal generator directly?

@dmurvihill dmurvihill changed the title Add choose[BigDecimal] Add Choose[BigDecimal] Mar 3, 2020
@ashawley
Copy link
Contributor

ashawley commented Mar 4, 2020

Thanks for creating this issue. I don't use a lot of arbitrary precision, and you sound like you have a specific use-case in mind, but why would you need to specify precision? What would be wrong with?

Gen.choose(BigDecimal("-9.22337203685477580E+214748366"), BigDecimal("9.223372036854775807E-2147483629")) 

@dmurvihill
Copy link
Contributor Author

dmurvihill commented Mar 4, 2020

The numbers returned by that generator could be any size from 128 bits all the way up to 500MB in length.

@ashawley
Copy link
Contributor

ashawley commented Mar 4, 2020

Ok, and that is what a precision parameter you mentioned would help avoid, or is this just an issue with the large numbers I chose as an example? I assumed BigDecimal had an efficient implementation, but this isn't the case?

@dmurvihill
Copy link
Contributor Author

dmurvihill commented Mar 4, 2020

Let's simplify and say we are asking for Gen.choose(BigDecimal("-1.0"), BigDecimal("+1.0")).

Can this generator produce 0.1? If so, can it produce 0.11? How about 0.11111111111111111111111111111111111111111111111111111111111111111111, or even a string of 2^32 1s? Where does it end? That question can only be answered by the user based on their analysis of what is "close enough" for their use case.

@ashawley
Copy link
Contributor

ashawley commented Mar 4, 2020

Good point. Finding the range between the values would likely determine what the scale should be. According to the documentation for java.math.BigDecimal, subtraction adopts the largest scale of the two operands. Would that be sufficient?

@dmurvihill
Copy link
Contributor Author

Oh, I really like that. Hang on a minute.

@ashawley ashawley added this to the 1.15.0 milestone Jun 4, 2020
non added a commit to non/scalacheck that referenced this issue Jul 1, 2020
In addition to implicit Choose instances for scala.math.BigDecimal and
java.math.BigDecimal we also include explicit constructor methods, since users
may wish to be explicit about the scale they want. We may want to put those
methods directly on Gen, currently the ergonomics of using this are a bit bad:

    Gen.Choose.chooseBigDecimalScale(100).choose(0, 1)

The BigDecimal generation is not yet tested. That will also be added in a
follow up. This also optimizes the BigInt generator a bit and generalizes it to
java.math.BigInteger to support that as well.

Addresses typelevel#631, typelevel#637, and typelevel#664
@non
Copy link
Contributor

non commented Jul 10, 2020

#670

@larsrh larsrh closed this as completed Oct 24, 2020
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

4 participants