[ 
https://issues.apache.org/jira/browse/CAMEL-25703?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Work on CAMEL-25703 started by shashank.
----------------------------------------
> camel-bindy - a BigDecimal, Double or Float field without precision is 
> marshalled with at most three decimals (1.23456 is written as 1.235, 0.000123 
> as 0), so data is silently rounded and a record does not round trip
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25703
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25703
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-bindy
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>
> Since CAMEL-24168 (4.22.0) the default {{precision}} of {{@DataField}} and 
> {{@KeyValuePairField}} is {{-1}}, documented as "Use -1 (default) to preserve 
> the original scale from the input". Unmarshal now keeps the scale, but 
> marshal does not keep the decimals.
> {{AbstractNumberFormat}} (main d46d51c24550, lines 50-65) creates a {{new 
> DecimalFormat()}} and, for a precision of {{-1}}, does not set the fraction 
> digits at all ("skip DecimalFormat fraction digit configuration when 
> precision is unset", PR #24919). The default pattern of {{DecimalFormat}} is 
> {{#,##0.###}}: at most three fraction digits, rounded {{HALF_EVEN}}. 
> {{BigDecimalFormatFactory}}, {{DoubleFormatFactory}} and 
> {{FloatFormatFactory}} format with it, so every value with more than three 
> decimals is rounded when it is written, without an error or a log line:
> ||field type||value||written on main||
> |{{BigDecimal}}|{{1.23456}}|{{1.235}}|
> |{{BigDecimal}}|{{0.98765}}|{{0.988}}|
> |{{Double}}|{{12.3456789}}|{{12.346}}|
> |{{Double}}|{{0.000123}}|{{0}}|
> Unmarshal reads {{1.23456}} correctly, so a route that unmarshals a CSV, 
> fixed-length or key-value-pair record and marshals it again changes the 
> numbers. Exchange rates, unit prices, quantities and coordinates with four or 
> more decimals are common in the files Bindy is used for, and the default 
> annotation ({{@DataField(pos = 1)}}) is enough to hit it. The only test of 
> the unset case ({{BindyBigDecimalNoPrecisionTest}}, added by CAMEL-24168) 
> uses {{10.35}}, two decimals, so it passes.
> Trigger: default options; a {{BigDecimal}}, {{Double}} or {{Float}} field 
> with neither {{precision}} nor {{pattern}}; any value with more than three 
> decimals; {{marshal().bindy(...)}} of type Csv, Fixed or KeyValue.
> h3. Reproduction
> New {{BindyNumberWithoutPrecisionKeepsDecimalsTest}} (5 tests, locale {{en}}):
> * CSV marshal of {{BigDecimal 1.23456}}, {{Double 0.000123}}, {{Float 1.1}}: 
> expected {{1.23456,0.000123,1.1}}, main writes {{1.235,0,1.1}};
> * CSV unmarshal of {{0.98765,12.3456789,2.5}} then marshal: main writes 
> {{0.988,12.346,2.5}};
> * fixed-length record ({{BigDecimal}} and {{Double}}, length 10 each) 
> unmarshalled and marshalled: {{   1.23456  0.000123}} becomes {{     1.235    
>      0}};
> * controls (pass on main and with the fix): {{10}}, {{10.0}} and {{0.5f}} are 
> written as {{10,10,0.5}}; the whole-number float {{123456792f}} is written as 
> {{123456792}}.
> On main 3 of the first 4 fail (the first control passes; the whole-number 
> float control was not run against main, which writes that float through the 
> same {{double}} path). With the fix the five pass, and the camel-bindy tests: 
> 243 run, 0 failures, 0 errors, 3 skipped.
> h3. Proposed fix
> * {{AbstractNumberFormat}}: when no precision is set (and no implied decimal 
> separator), {{setMaximumFractionDigits(Integer.MAX_VALUE)}}, so the formatter 
> keeps every decimal of a {{BigDecimal}} and the shortest decimal form of a 
> {{double}} ({{DecimalFormat}} caps a {{double}} at 340 fraction digits 
> itself). Grouping, locale symbols and the whole-number output ({{10}}, not 
> {{10.0}}) are unchanged.
> * {{FloatFormatFactory}}: a finite {{Float}} with a fraction part and without 
> precision is formatted through {{new BigDecimal(Float.toString(value))}}; 
> otherwise the widening to {{double}} would now show as {{1.100000023841858}} 
> instead of {{1.1}}. A whole-number {{Float}} keeps the exact digits it had 
> before ({{123456792}}, not the shorter {{123456790}} of {{Float.toString}}).
> * An explicit {{precision}}, a {{pattern}} and {{impliedDecimalSeparator}} 
> are not affected.
> Users can notice that such values are written with all their decimals, also a 
> {{Double}} that is the result of a calculation ({{0.1 + 0.2}} is written 
> {{0.30000000000000004}}, before {{0.3}}); a note goes into the 4.24 upgrade 
> guide.
> How it was found: round r29, track I (silent data corruption in data 
> formats), a metamorphic check "unmarshal then marshal is the identity on 
> valid input" applied by reading the number formats of Bindy; a JShell probe 
> of {{new DecimalFormat()}} with grouping off gave {{12.346}} for {{12.34567}} 
> and {{0}} for {{0.000123}}, then the test above on the real data format.
> Affected: main (d46d51c24550; tested). camel-4.23.x and camel-4.22.x have the 
> same {{AbstractNumberFormat}} lines and {{precision() default -1}} (read, not 
> run). camel-4.18.x and camel-4.14.x still have the older code of CAMEL-24168 
> (precision 0, all decimals dropped), which is that ticket, not this one.
> Duplicate check (2026-10-16): JIRA text "bindy BigDecimal", "bindy 
> precision", "bindy decimal digits", "bindy fraction digits", "bindy rounded 
> three decimals" and the camel-bindy issues created since 2026-06-01 
> (CAMEL-24168 is the only related one, resolved; CAMEL-25150, 25151, 25152 are 
> other defects); GitHub pull requests "bindy precision", "bindy decimal" and 
> "bindy in:title" (PR #24919 for CAMEL-24168, merged; nothing open).
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to