You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by ja...@apache.org on 2019/02/11 18:29:42 UTC
[incubator-daffodil] branch master updated: Return xs:decimal when
dividing xs:long
This is an automated email from the ASF dual-hosted git repository.
jadams pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-daffodil.git
The following commit(s) were added to refs/heads/master by this push:
new a20ff41 Return xs:decimal when dividing xs:long
a20ff41 is described below
commit a20ff4172807f5e0264ce68142f15f9798df1e8b
Author: Josh Adams <ja...@tresys.com>
AuthorDate: Thu Feb 7 10:28:02 2019 -0500
Return xs:decimal when dividing xs:long
Originally dividing xs:long was returning a double, but it should have
been returning a decimal instead. Similar fixes have been made for other
integer based types.
DAFFODIL-2063
---
.../org/apache/daffodil/dpath/NodeInfoUtils.scala | 4 +-
.../org/apache/daffodil/dpath/NumericOps.scala | 80 +++-------------------
.../section23/dfdl_expressions/expressions.tdml | 30 ++++++++
.../dfdl_expressions/TestDFDLExpressions2.scala | 3 +
4 files changed, 45 insertions(+), 72 deletions(-)
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dpath/NodeInfoUtils.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dpath/NodeInfoUtils.scala
index 8d9052f..bfe3bbf 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dpath/NodeInfoUtils.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dpath/NodeInfoUtils.scala
@@ -86,9 +86,9 @@ object NodeInfoUtils {
case Decimal => Decimal
case Integer => Decimal
case Double => Double
- case Long => Double
+ case Long => Decimal
case Float => Float
- case Int => Float
+ case Int => Decimal
case ArrayIndex => ArrayIndex
case _ => Assert.usageError("Unsupported return type: %s".format(resultType))
}
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/NumericOps.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/NumericOps.scala
index 5be6845..d5cc702 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/NumericOps.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/NumericOps.scala
@@ -99,13 +99,7 @@ case object TimesInteger extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JBigInt = { asBigInt(v1).multiply(asBigInt(v2)) }
}
case object DivInteger extends NumericOp {
- def operate(v1: JNumber, v2: JNumber): JBigDecimal = {
- val v2bd = asBigDecimal(v2)
- if (v2bd.compareTo(JBigDecimal.ZERO) == 0) {
- throw new ArithmeticException("/ by zero")
- }
- asBigDecimal(v1).divide(v2bd)
- }
+ def operate(v1: JNumber, v2: JNumber): JBigDecimal = { DivDecimal.operate(v1, v2) }
}
case object IDivInteger extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JBigInt = { asBigInt(DivInteger.operate(v1, v2)) }
@@ -124,13 +118,7 @@ case object TimesNonNegativeInteger extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JBigInt = { asBigInt(v1).multiply(asBigInt(v2)) }
}
case object DivNonNegativeInteger extends NumericOp {
- def operate(v1: JNumber, v2: JNumber): JBigDecimal = {
- val v2bd = asBigDecimal(v2)
- if (v2bd.compareTo(JBigDecimal.ZERO) == 0) {
- throw new ArithmeticException("/ by zero")
- }
- asBigDecimal(v1).divide(v2bd)
- }
+ def operate(v1: JNumber, v2: JNumber): JBigDecimal = { DivDecimal.operate(v1, v2) }
}
case object IDivNonNegativeInteger extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JBigInt = { asBigInt(DivNonNegativeInteger.operate(v1, v2)) }
@@ -149,13 +137,7 @@ case object TimesUnsignedLong extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JBigInt = { asBigInt(v1).multiply(asBigInt(v2)) }
}
case object DivUnsignedLong extends NumericOp {
- def operate(v1: JNumber, v2: JNumber): JBigDecimal = {
- val v2bd = asBigDecimal(v2)
- if (v2bd.compareTo(JBigDecimal.ZERO) == 0) {
- throw new ArithmeticException("/ by zero")
- }
- asBigDecimal(v1).divide(v2bd)
- }
+ def operate(v1: JNumber, v2: JNumber): JBigDecimal = { DivDecimal.operate(v1, v2) }
}
case object IDivUnsignedLong extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JBigInt = { asBigInt(DivUnsignedLong.operate(v1, v2)) }
@@ -174,13 +156,7 @@ case object TimesLong extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JNumber = { asLong(v1) * asLong(v2) }
}
case object DivLong extends NumericOp {
- def operate(v1: JNumber, v2: JNumber): JNumber = {
- val v2l = asLong(v2)
- if (v2l == 0) {
- throw new ArithmeticException("/ by zero")
- }
- asDouble(v1) / v2l
- }
+ def operate(v1: JNumber, v2: JNumber): JBigDecimal = { DivDecimal.operate(v1, v2) }
}
case object IDivLong extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JNumber = { asLong(DivLong.operate(v1, v2)) }
@@ -199,13 +175,7 @@ case object TimesUnsignedInt extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JNumber = { asLong(v1) * asLong(v2) }
}
case object DivUnsignedInt extends NumericOp {
- def operate(v1: JNumber, v2: JNumber): JNumber = {
- val v2l = asLong(v2)
- if (v2l == 0) {
- throw new ArithmeticException("/ by zero")
- }
- asDouble(v1) / v2l
- }
+ def operate(v1: JNumber, v2: JNumber): JNumber = { DivDecimal.operate(v1, v2) }
}
case object IDivUnsignedInt extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JNumber = { asLong(DivUnsignedInt.operate(v1, v2)) }
@@ -224,13 +194,7 @@ case object TimesInt extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JNumber = { asInt(v1) * asInt(v2) }
}
case object DivInt extends NumericOp {
- def operate(v1: JNumber, v2: JNumber): JNumber = {
- val v2i = asInt(v2)
- if (v2i == 0) {
- throw new ArithmeticException("/ by zero")
- }
- asFloat(v1) / v2i
- }
+ def operate(v1: JNumber, v2: JNumber): JNumber = { DivDecimal.operate(v1, v2) }
}
case object IDivInt extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JNumber = { asInt(DivInt.operate(v1, v2)) }
@@ -249,13 +213,7 @@ case object TimesUnsignedShort extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JNumber = { asInt(v1) * asInt(v2) }
}
case object DivUnsignedShort extends NumericOp {
- def operate(v1: JNumber, v2: JNumber): JNumber = {
- val v2i = asInt(v2)
- if (v2i == 0) {
- throw new ArithmeticException("/ by zero")
- }
- asFloat(v1) / v2i
- }
+ def operate(v1: JNumber, v2: JNumber): JNumber = { DivDecimal.operate(v1, v2) }
}
case object IDivUnsignedShort extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JNumber = { asInt(DivUnsignedShort.operate(v1, v2)) }
@@ -274,13 +232,7 @@ case object TimesShort extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JNumber = { asShort(v1) * asShort(v2) }
}
case object DivShort extends NumericOp {
- def operate(v1: JNumber, v2: JNumber): JNumber = {
- val v2i = asInt(v2)
- if (v2i == 0) {
- throw new ArithmeticException("/ by zero")
- }
- asFloat(v1) / v2i
- }
+ def operate(v1: JNumber, v2: JNumber): JNumber = { DivDecimal.operate(v1, v2) }
}
case object IDivShort extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JNumber = { asShort(DivShort.operate(v1, v2)) }
@@ -299,13 +251,7 @@ case object TimesUnsignedByte extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JNumber = { asShort(v1) * asShort(v2) }
}
case object DivUnsignedByte extends NumericOp {
- def operate(v1: JNumber, v2: JNumber): JNumber = {
- val v2i = asInt(v2)
- if (v2i == 0) {
- throw new ArithmeticException("/ by zero")
- }
- asFloat(v1) / v2i
- }
+ def operate(v1: JNumber, v2: JNumber): JNumber = { DivDecimal.operate(v1, v2) }
}
case object IDivUnsignedByte extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JNumber = { asShort(DivUnsignedByte.operate(v1, v2)) }
@@ -324,13 +270,7 @@ case object TimesByte extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JNumber = { asByte(v1) * asByte(v2) }
}
case object DivByte extends NumericOp {
- def operate(v1: JNumber, v2: JNumber): JNumber = {
- val v2i = asInt(v2)
- if (v2i == 0) {
- throw new ArithmeticException("/ by zero")
- }
- asFloat(v1) / v2i
- }
+ def operate(v1: JNumber, v2: JNumber): JNumber = { DivDecimal.operate(v1, v2) }
}
case object IDivByte extends NumericOp {
def operate(v1: JNumber, v2: JNumber): JNumber = { asByte(DivByte.operate(v1, v2)) }
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 91e8fed..6b56480 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
@@ -7047,6 +7047,9 @@
<xs:element name="div19" type="xs:double" dfdl:inputValueCalc="{ xs:double(5) div xs:double('INF') }" />
<xs:element name="div20" type="xs:float" dfdl:inputValueCalc="{ xs:float(5) div xs:float('INF') }" />
<xs:element name="div21" type="xs:double" dfdl:inputValueCalc="{ 90.0 div 1234567.0 }" />
+ <xs:element name="div22" type="xs:decimal" dfdl:inputValueCalc="{ (9 * xs:long(5)) div 1600 }" />
+ <xs:element name="div23" type="xs:double" dfdl:inputValueCalc="{ (9 * xs:long(5)) div 1600 }" />
+ <xs:element name="div24" type="xs:float" dfdl:inputValueCalc="{ (xs:int(5)) div xs:int(3) }" />
<xs:element name="idiv01" type="xs:int" dfdl:inputValueCalc="{ xs:double(5) idiv xs:double(2) }" />
<xs:element name="idiv02" type="xs:int" dfdl:inputValueCalc="{ xs:float(5) idiv xs:float(2) }" />
@@ -7184,6 +7187,33 @@
<tdml:infoset><tdml:dfdlInfoset><div21>7.290005321703885E-5</div21></tdml:dfdlInfoset></tdml:infoset>
</tdml:parserTestCase>
+ <tdml:parserTestCase name="div22" root="div22" model="XPathDiv" description="Section 23 - DFDL Expressions - div"
+ config="cfg_errorOnResultCoercion">
+ <tdml:document></tdml:document>
+ <tdml:infoset><tdml:dfdlInfoset><div22>0.028125</div22></tdml:dfdlInfoset></tdml:infoset>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="div23" root="div23" model="XPathDiv" description="Section 23 - DFDL Expressions - div"
+ config="cfg_errorOnResultCoercion">
+ <tdml:document></tdml:document>
+ <tdml:errors>
+ <tdml:error>Expression result type</tdml:error>
+ <tdml:error>Decimal</tdml:error>
+ <tdml:error>must be manually cast</tdml:error>
+ <tdml:error>Double</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="div24" root="div24" model="XPathDiv" description="Section 23 - DFDL Expressions - div"
+ config="cfg_errorOnResultCoercion">
+ <tdml:document></tdml:document>
+ <tdml:errors>
+ <tdml:error>Expression result type</tdml:error>
+ <tdml:error>Decimal</tdml:error>
+ <tdml:error>must be manually cast</tdml:error>
+ <tdml:error>Float</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
<tdml:parserTestCase name="idiv01" root="idiv01" model="XPathDiv" description="Section 23 - DFDL Expressions - idiv">
<tdml:document></tdml:document>
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions2.scala b/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions2.scala
index e452a77..cb38c7c 100644
--- a/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions2.scala
+++ b/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions2.scala
@@ -94,6 +94,9 @@ class TestDFDLExpressions2 {
@Test def test_div19 { runner.runOneTest("div19") }
@Test def test_div20 { runner.runOneTest("div20") }
@Test def test_div21 { runner.runOneTest("div21") }
+ @Test def test_div22 { runner.runOneTest("div22") }
+ @Test def test_div23 { runner.runOneTest("div23") }
+ @Test def test_div24 { runner.runOneTest("div24") }
@Test def test_idiv01 { runner.runOneTest("idiv01") }
@Test def test_idiv02 { runner.runOneTest("idiv02") }