DaveAKing / guava-libraries

Automatically exported from code.google.com/p/guava-libraries
Apache License 2.0
0 stars 0 forks source link

RFE: DiscreteDomain for BigDecimal #1653

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
DiscreteDomain provides default implementations for int, long, BigInteger. 
Isn't it possible to provide one for BigDecimal as follows?

class BigDecimalDiscreteDomain extends DiscreteDomain<BigDecimal>
{
    @Override
    public BigDecimal next(BigDecimal value)
    {
        return value.add(value.ulp());
    }

    @Override
    public BigDecimal previous(BigDecimal value)
    {
        return value.subtract(value.ulp());
    }

    @Override
    public long distance(BigDecimal start, BigDecimal end)
    {
        return end.subtract(start).longValue();
    }
}

Original issue reported on code.google.com by cow...@bbs.darktech.org on 30 Jan 2014 at 5:02

GoogleCodeExporter commented 9 years ago
There is no way to implement previous() for BigDecimal -- it's our "go-to" 
example for an impossible DiscreteDomain.  You could have instead subtracted 
1/10th of the ulp, or less, or less....

Original comment by kevinb@google.com on 30 Jan 2014 at 5:05

GoogleCodeExporter commented 9 years ago
Oh, and there's *really* no way to implement distance().  You could kind of do 
next/previous for a DiscreteDomain<Double> but never that.  Even apart from 
that, these sorts of DiscreteDomains could only be used to do meaningless 
things, anyway.

What are you really trying to do?

Original comment by kevinb@google.com on 30 Jan 2014 at 5:07

GoogleCodeExporter commented 9 years ago
Implementing this is a bit tricky. For example, I think the above distance() 
implementation is incorrect. I'm guessing it should be something along the 
lines of:

  return end.subtract(start).divide(start.ulp()).longValueExact();

but I would appreciate your second pair of eyes to make sure this makes sense.

Original comment by cow...@bbs.darktech.org on 30 Jan 2014 at 5:08

GoogleCodeExporter commented 9 years ago
cowwoc, I think you're misreading the spec.  DiscreteDomain's contract 
specifies that next() returns the  "unique least value of type C that is 
greater than value, or null if none exists."  The ulp is irrelevant: what 
matters is that given 

BigDecimal x;
BigDecimal y = domain.next(x);

that there be no value *whatsoever* of type BigDecimal that compares as greater 
than x and less than y; otherwise, y was not the "least value of type C that is 
greater than [x]."

Original comment by lowas...@google.com on 30 Jan 2014 at 5:50

GoogleCodeExporter commented 9 years ago
@kevin,

I was trying to invoke Range.canonical(DiscreteDomain) before printing out an 
error message saying: "value must be in range [low, high]". I am invoking 
Range.canonical() because it converts the range to closed-closed. 
Range.canonical(), in turn, depends on DiscreteDomain which is why I was trying 
to formulate one for BigDecimal.

I guess I'll just have to make due with an open range in the error message.

@lowasser, excellent explanation. Thank you!

Original comment by cow...@bbs.darktech.org on 30 Jan 2014 at 5:56

GoogleCodeExporter commented 9 years ago
@cowwoc: Yeah, you can actually see based on Louis's explanation why it isn't 
possible to turn an open bound on a Range<BigDecimal> into an equivalent closed 
bound: any BigDecimal value you pick for the closed bound still has an infinite 
number of possible BigDecimal values that are between it and the open bound, so 
the resulting Range could not be equivalent.

Original comment by cgdecker@google.com on 30 Jan 2014 at 6:53

GoogleCodeExporter commented 9 years ago
This issue has been migrated to GitHub.

It can be found at https://github.com/google/guava/issues/<issue id>

Original comment by cgdecker@google.com on 1 Nov 2014 at 4:10

GoogleCodeExporter commented 9 years ago

Original comment by cgdecker@google.com on 3 Nov 2014 at 9:07