vbhanuchander-lang opened a new pull request, #7744:
URL: https://github.com/apache/hop/pull/7744
Addresses #6111.
`BigDecimal.valueOf(double)` is specified as `new
BigDecimal(Double.toString(val))`, and `Double.toString()` switches to
scientific notation from 10<sup>7</sup> onwards. For `55487400.0` it returns
`"5.54874E7"`, which parses into an unscaled value of 554874 with a scale of
`-2`. It is that negative scale which makes `BigDecimal.toString()` render the
value as `5.54874E+7` again:
```java
BigDecimal bd = BigDecimal.valueOf(55487400.0);
bd.scale(); // -2
bd.toString(); // "5.54874E+7"
bd.toPlainString(); // "55487400"
```
So every consumer that serializes a BigNumber through `toString()` emits
scientific notation for a value that started out as plain digits:
- JDBC drivers that inline statement parameters — the Table Output `INSERT`
in the reported case
- `writeBigNumber()`, used by the binary row serialization
- `getDataXml()`, used by the XML data serialization
The formatting layer is not involved: both default masks (`####0.0#########`
and `######0.0###################`) render the value as `55487400.0` correctly.
### Change
The four `Double` to `BigDecimal` conversions in `ValueMetaBase` —
`getBigNumber()` for `TYPE_NUMBER` across its three storage types, and
`convertStringToBigNumber()` — now go through a single helper:
```java
protected static BigDecimal convertDoubleToBigNumber(double number) {
BigDecimal bigDecimal = BigDecimal.valueOf(number);
return bigDecimal.scale() < 0 ? bigDecimal.setScale(0) : bigDecimal;
}
```
Rescaling upwards from a negative scale is exact, so no rounding mode is
required, no `ArithmeticException` is possible, and the numeric value is
unchanged.
### Compatibility
- Values that already convert to a non-negative scale are returned
untouched, scale included.
- The string conversion paths format through `DecimalFormat` and never
emitted scientific notation. Their output is unchanged, and a regression test
pins that down.
- BigNumber comparison in `ValueMetaBase` uses `compareTo()`, which is
scale-insensitive, so ordering and equality semantics are unaffected.
- The XML and binary serialized forms do change for affected values, from
`5.54874E+7` to `55487400`. Both round-trip correctly, since `readBigNumber()`
parses whatever was written.
### Tests
Eight tests added to `ValueMetaBaseTest`:
- the reported value, and a range of magnitudes including negatives and
2<sup>53</sup>
- the untouched-scale guarantee, asserted with scale-sensitive `equals()`
rather than `compareTo()`
- the `convertData()` metadata-change path a Select Values transform performs
- the `writeBigNumber()` / `readBigNumber()` round trip
- `getDataXml()`
- a regression guard on the `DecimalFormat` string path
### Verification
`./mvnw -pl core test` — 1039 tests, 0 failures, 0 errors. `spotless:check`
and `apache-rat:check` both pass. The full `mvn clean install` was not run
locally; relying on CI for the complete build.
### Note for reviewers
`ValueDataUtil.ceil()`, `floor()`, `abs()` and `sqrt()` build BigNumber
results with `BigDecimal.valueOf(Math.xxx(...))` and can produce the same
negative scale. I left them out to keep this change focused, since sharing the
helper across packages would mean widening its visibility. Happy to follow up
in a separate PR if you would like that covered.
------------------------
Thank you for your contribution! Follow this checklist to help us
incorporate your contribution quickly and easily:
- [x] Run `mvn clean install apache-rat:check` to make sure basic checks
pass. A more thorough check will be performed on your pull request
automatically. *(see Verification above for exactly what was run locally)*
- [x] If you have a group of commits related to the same change, please
squash your commits into one and force push your branch using `git rebase -i`.
- [x] Mention the appropriate issue in your description (for example:
`addresses #123`), if applicable.
To make clear that you license your contribution under the [Apache License
Version 2.0, January 2004](http://www.apache.org/licenses/LICENSE-2.0)
you have to acknowledge this by using the following check-box.
- [x] I hereby declare this contribution to be licensed under the [Apache
License Version 2.0, January 2004](http://www.apache.org/licenses/LICENSE-2.0)
- [ ] In any other case, please file an [Apache Individual Contributor
License Agreement](https://www.apache.org/licenses/icla.pdf).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]