Adding BigDecimal.valueOf(float val) constructor
Raffaello Giulietti
raffaello.giulietti at oracle.com
Fri Feb 14 14:26:29 UTC 2025
> We can hardly add an override of valueOf(float).
correction
We can hardly add an overload of valueOf(float).
On 2025-02-14 15:12, Raffaello Giulietti wrote:
> I think that we should definitely improve the documentation of
> valueOf(double) to clarify that passing a float might not be the best
> usage of the method, and suggest using the idiom
> valueOf(Float.toString(f))
> as already noted in this thread.
>
> We can hardly add an override of valueOf(float).
>
> Adding something like valueOfFloat(float) could be more viable, but
> personally I doubt that there's much "market demand" for it. Moreover,
> it would kind of break decades long naming conventions.
>
> But more importantly, the models of binary floating-point values, like
> float and double, and of decimal floating-point value, like BD, are
> different.
> Wanting to emulate decimal arithmetic with float/double or wishing to
> emulate binary arithmetic with BD is asking for troubles in most cases.
> This is to say that one needs to be very careful when mixing float/
> double and BD and converting one value of one model to the other.
>
>
> Greetings
> Raffaello
>
>
>
> On 2025-02-13 20:30, Kevin Bourrillion wrote:
>> My latest thoughts; please advise if I have misunderstood anything.
>>
>>
>>> On Jan 24, 2025, at 3:11 AM, Jan Kowalski <jan7493 at gmail.com> wrote:
>>>
>>> I'd say that, if it's possible, we should reduce the arithmetic
>>> artifacts, rather than introduce them through not really needed, and
>>> not visible at the first sight, type conversions.
>>>
>>> … Do you think introducing such change would be beneficial to
>>> simplify the code, or rather introduce minor precision improvement,
>>> while we still don’t have 100% decimal precision?
>>
>> Okay, so what we’re looking for is a way to convert floats to
>> BigDecimals in such a way that `0.1f` comes out the same as `new
>> BigDecimal(“0.1”)`.
>>
>> This thread is characterizing that outcome as “reducing artifacts” and
>> “improving precision”, which seems fair on the surface, but I believe
>> this is more like an illusion. I think the reason this looks like
>> obvious “improvement” to us is only because we happen to be using /
>> literals/ in our examples. But for a float value that isn’t a literal,
>> like our friend `0.1f + 0.2f`, I think that the illusion is shattered.
>> I think this “exposes" that the scale chosen by BD.valueOf(double) is
>> based on an “artifact” of that value that isn’t really meant to be
>> “information carried by” the value. (Were we to think the latter way,
>> it makes us think of a float-to-double cast as /losing information/,
>> which feels like nonsense.)
>>
>> I think the fact that a new overload would affect current behavior
>> means we need to rule that option out. I don’t think this is a case
>> that can justify that cost. So it would at best have to be a new
>> separately-named method like `valueOfFloat`. So at best this issue
>> will /still/ bite users of `valueOf`, and we would still want the
>> documentation of that method to advise users on what to do instead.
>>
>> My feeling is that all we need it to do is advise the user to call
>> `BigDecimal.valueOf(Float.toString(val))`. This is very transparent
>> about what’s really happening. Here the user is intentionally /
>> choosing/ the representation/scale.
>>
>> I personally don’t see this as a case where fast-enough benchmark
>> result would justify adding a new method.
>>
>> Your thoughts?
>
More information about the core-libs-dev
mailing list