This is an automated email from the ASF dual-hosted git repository.
slawrence pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil.git
The following commit(s) were added to refs/heads/main by this push:
new 854a2929f Prefer xs:double over xs:decimal for numeric operations
854a2929f is described below
commit 854a2929f5366b85ac506a341b49d76e8a1c6061
Author: Steve Lawrence <[email protected]>
AuthorDate: Wed Oct 15 14:23:49 2025 -0400
Prefer xs:double over xs:decimal for numeric operations
Commit 6650eb918e modified numeric operations so that if the args did
not have any common parent type (e.g. xs:double and xs:int) then we
always promoted to xs:decimal. However, this caused tiny changes in
precision for some operations so could lead to minor backwards
incompatibilities.
This modifies the logic so we only promote numeric operations to
xs:decimal if one of the args is a xs:nonNegativeInteger, xs:integer, or
xs:decimal (i.e. arbitrary-precision types). If neither arg is
arbitrary-precision, then it means both args have finite precision
(xs:float, xs:double, xs:long, xs:unsignedLong, or subtype) and so we
promote to xs:double. This should give more efficient performance,
maintains fixed-precision/width operations, and maintains backwards
compatibility with previous versions of Daffodil.
DAFFODIL-2574
---
.../apache/daffodil/core/dpath/NodeInfoUtils.scala | 19 ++++++++++++++++++-
.../section23/dfdl_expressions/expressions.tdml | 13 +++++++++++++
.../section23/dfdl_expressions/expressions2.tdml | 2 +-
.../dfdl_expressions/TestDFDLExpressions.scala | 3 +++
4 files changed, 35 insertions(+), 2 deletions(-)
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/NodeInfoUtils.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/NodeInfoUtils.scala
index 931332835..6ea89b392 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/NodeInfoUtils.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/NodeInfoUtils.scala
@@ -99,7 +99,24 @@ object NodeInfoUtils {
val lub = NodeInfoUtils.typeLeastUpperBound(leftArgType, rightArgType)
val argType = lub match {
case ArrayIndex => Long
- case SignedNumeric => Decimal // lub of float/double and other types
+ case SignedNumeric => {
+ // SignedNumeric is the least upper bound of float, double, and
decimal/subtypes. One of
+ // the args must be a float or double, so we must promote to either
Double or Decimal.
+ // If one of the args is arbitrary width/precision (i.e. non-negative
integer or a
+ // parent type) then we promote the args to Decimal to maintain that
level of precision.
+ // Otherwise, it means both args are finite width/precision and we
promote both args to
+ // Double. This provides efficient math and maintains limited
precision operations while
+ // still having reasonably good precision. This also maintains
compatibility with older
+ // version of Daffodil that did most math using Doubles
+ if (
+ NonNegativeInteger.isSubtypeOf(leftArgType) ||
+ NonNegativeInteger.isSubtypeOf(rightArgType)
+ ) {
+ Decimal
+ } else {
+ Double
+ }
+ }
case Decimal => Decimal
case Double => Double
case Float => Float
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expressions.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expressions.tdml
index 7301e4164..9dc1ae1ed 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expressions.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expressions.tdml
@@ -7427,6 +7427,9 @@ blastoff
<xs:element name="mod02" type="xs:double" dfdl:inputValueCalc="{
xs:double(10.5) mod xs:double(3) }" />
<xs:element name="mod03" type="xs:float" dfdl:inputValueCalc="{
xs:float(10.5) mod xs:float(3) }" />
<xs:element name="mod04" type="xs:decimal" dfdl:inputValueCalc="{
xs:decimal(10.5) mod xs:decimal(3) }" />
+
+ <xs:element name="precision01" type="xs:double" dfdl:inputValueCalc="{
xs:int(3) + xs:double(xs:int(34) div xs:double(60.0)) }" />
+ <xs:element name="precision02" type="xs:double" dfdl:inputValueCalc="{
xs:integer(3) + xs:double(xs:integer(34) div xs:double(60.0)) }" />
</tdml:defineSchema>
<tdml:parserTestCase name="div01" root="div01" model="XPathMath"
description="Section 23 - DFDL Expressions - div">
@@ -7770,6 +7773,16 @@ blastoff
<tdml:infoset><tdml:dfdlInfoset><mod04>1.5</mod04></tdml:dfdlInfoset></tdml:infoset>
</tdml:parserTestCase>
+ <tdml:parserTestCase name="precision01" root="precision01" model="XPathMath"
description="Section 23 - DFDL Expressions - div">
+ <tdml:document></tdml:document>
+
<tdml:infoset><tdml:dfdlInfoset><precision01>3.5666666666666664</precision01></tdml:dfdlInfoset></tdml:infoset>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="precision02" root="precision02" model="XPathMath"
description="Section 23 - DFDL Expressions - div">
+ <tdml:document></tdml:document>
+
<tdml:infoset><tdml:dfdlInfoset><precision02>3.566666666666667</precision02></tdml:dfdlInfoset></tdml:infoset>
+ </tdml:parserTestCase>
+
<tdml:defineSchema name="DFDLCheckRange">
<xs:include
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
<dfdl:format ref="ex:GeneralFormat" />
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expressions2.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expressions2.tdml
index 1602028d6..7337a8cba 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expressions2.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expressions2.tdml
@@ -218,7 +218,7 @@
<tdml:errors>
<tdml:error>Schema Definition Error</tdml:error>
<tdml:error>If-expression branches must have similar types</tdml:error>
- <tdml:error>Decimal</tdml:error>
+ <tdml:error>Double</tdml:error>
<tdml:error>String</tdml:error>
</tdml:errors>
</tdml:parserTestCase>
diff --git
a/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
b/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
index 8459131f0..47295ae7d 100644
---
a/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
+++
b/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
@@ -417,6 +417,9 @@ class TestDFDLExpressions extends TdmlTests {
@Test def mod03 = test
@Test def mod04 = test
+ @Test def precision01 = test
+ @Test def precision02 = test
+
// DFDL-1617 - should detect errors due to query-style expressions
@Test def query_style_01 = test
@Test def query_style_02 = test