Hi, Before addressing your request I want to try to just add a little context as to what’s really going on (after which Joe will probably correct me). You might know some or all of this, but it’s a refresher for everyone (including myself).
First, the value 0.1d is a “human-friendly” representation of the actual binary value, which is more accurately expressed as the hex literal 0x1.999999999999Ap-4 Notice it’s a repeating expansion, and it has to be rounded up at the end to make it fit into 13 hex digits. The true decimal representation of this value is 0.1000000000000000055511151231257827021181583404541015625 If we’d rounded that last digit (A) down (to 9) we would get this instead: 0.09999999999999999167332731531132594682276248931884765625 Now, the only reason we even call this value “0.1” at all (which it is not!), and that Java even calls it “0.1” when it is talking to us, is simply this: It happens to be the nearest representable value to 0.1 (which you can observe for yourself if you look very closely at the full decimal expansions I just gave). All that this means is that the short string “0.1” becomes a suitably unambiguous way to refer to that number. A “shorthand” for it. Now, the fact that BigDecimal.valueOf(0.1d) decides to produce a value with scale set to 1 is … interesting: jshell> double a = 0.1 a ==> 0.1 jshell> double b = 0.2 b ==> 0.2 jshell> BigDecimal.valueOf(a).scale() $14 ==> 1 jshell> BigDecimal.valueOf(b).scale() $15 ==> 1 jshell> BigDecimal.valueOf(a + b).scale() $16 ==> 17 You’ve described its behavior as “correct”, but I would question whether that’s really the right term for it. It feels uncomfortably arbitrary to me. When your goal is to get the BigDecimal value “0.1” (with scale 1), the safe and recommended way to do that is with `new BigDecimal(“0.1”)`. Maybe some variation on this idea will help you in your case; I’m not sure. Again, I’m not directly commenting on your suggestion, just providing context. On Jan 23, 2025, at 1:20 PM, Jan Kowalski <jan7...@gmail.com> wrote: Hi! I’m currently working on a project that heavily relies on float values, and we occasionally use BigDecimal for more precise mathematical operations. However, I’ve noticed that the current BigDecimal constructor implementation only supports double, which can lead to unintentional type conversion and precision loss when creating a BigDecimal from a float. The documentation suggests using BigDecimal.valueOf(double val) as the preferred method for converting double or float values to BigDecimal, but since method takes double as an argument, it leads much more often to precision loss when float is passed. For example: - BigDecimal.valueOf(0.1d) correctly produces 0.1. - However, BigDecimal.valueOf(0.1f) produces 0.10000000149011612, which introduces unwanted precision artifacts. What would you think about introducing a static factory method specifically for float values, such as: public static BigDecimal valueOf(float val) { return new BigDecimal(Float.toString(val)); } This addition should improve usability and ensure that float values are handled more precisely within the BigDecimal API