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 4caaeff Use setScale() not round() when rounding BigDecimals
4caaeff is described below
commit 4caaeff7b9df8432d482e7bf664b134921ce2293
Author: Josh Adams <[email protected]>
AuthorDate: Fri Mar 15 11:27:42 2019 -0400
Use setScale() not round() when rounding BigDecimals
In order to perform a round/floor/ceiling on a BigDecimal and not retain
any decimal points we need to use BD.setScale with a precision of 0. When
the BD.round function is used with a precision or 0, no rounding is
performed.
DAFFODIL-2076
---
.../org/apache/daffodil/dpath/FNFunctions.scala | 6 +-
.../section23/dfdl_functions/Functions.tdml | 122 ++++++++++++++++++++-
.../dfdl_expressions/TestDFDLExpressions.scala | 5 +
3 files changed, 128 insertions(+), 5 deletions(-)
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/FNFunctions.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/FNFunctions.scala
index 20d1953..86b45df 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/FNFunctions.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/FNFunctions.scala
@@ -685,7 +685,7 @@ case class FNCeiling(recipe: CompiledDPath, argType:
NodeInfo.Kind) extends FNOn
case NodeInfo.Decimal => {
val bd = asBigDecimal(value)
- bd.round(new MathContext(0, RoundingMode.CEILING))
+ bd.setScale(0, RoundingMode.CEILING)
}
case NodeInfo.Float => asAnyRef(asFloat(value).floatValue().ceil)
case NodeInfo.Double => asAnyRef(asDouble(value).floatValue().ceil)
@@ -699,7 +699,7 @@ case class FNFloor(recipe: CompiledDPath, argType:
NodeInfo.Kind) extends FNOneA
case NodeInfo.Decimal => {
val bd = asBigDecimal(value)
- bd.round(new MathContext(0, RoundingMode.FLOOR))
+ bd.setScale(0, RoundingMode.FLOOR)
}
case NodeInfo.Float => asAnyRef(asFloat(value).floatValue().floor)
case NodeInfo.Double => asAnyRef(asDouble(value).doubleValue().floor)
@@ -717,7 +717,7 @@ case class FNRound(recipe: CompiledDPath, argType:
NodeInfo.Kind) extends FNOneA
// A MathContext object whose settings have
// the values required for unlimited precision arithmetic.
val mc = java.math.MathContext.UNLIMITED
- bd.round(mc)
+ bd.setScale(0, RoundingMode.HALF_UP)
}
case NodeInfo.Float => {
val f = asFloat(value).floatValue()
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml
index 1033064..aa1008f 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml
@@ -4324,6 +4324,8 @@
</xs:complexType>
</xs:element>
+ <xs:element name="ceil08" type="xs:decimal" dfdl:inputValueCalc="{
fn:ceiling(xs:decimal(0.125)) }"/>
+
<xs:element name="floor" type="xs:double" dfdl:inputValueCalc="{
fn:floor(4.2) }"/>
<xs:element name="floor02">
@@ -4387,6 +4389,8 @@
</xs:complexType>
</xs:element>
+ <xs:element name="floor08" type="xs:decimal" dfdl:inputValueCalc="{
fn:floor(xs:decimal(0.125)) }"/>
+
<xs:element name="round" type="xs:double" dfdl:inputValueCalc="{
fn:round(4.2) }"/>
<xs:element name="round02">
@@ -4444,6 +4448,17 @@
</xs:complexType>
</xs:element>
+ <xs:element name="round08" type="xs:decimal" dfdl:inputValueCalc="{
fn:round(xs:decimal(0.125)) }"/>
+ <xs:element name="round09" type="xs:decimal" dfdl:inputValueCalc="{
fn:round(xs:decimal(0.5)) }"/>
+ <xs:element name="round10">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="val" type="xs:decimal" dfdl:inputValueCalc="{
xs:decimal(0.5) }"/>
+ <xs:element name="roundVal" type="xs:decimal" dfdl:inputValueCalc="{
fn:round(../ex:val) }"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
<xs:element name="round-hte">
<xs:complexType>
<xs:sequence dfdl:separator=",">
@@ -5419,7 +5434,27 @@
<tdml:error>Argument must be of numeric type but was String.</tdml:error>
</tdml:errors>
</tdml:parserTestCase>
-
+
+<!--
+ Test Name: ceil_09
+ Schema: XPathFunctions
+ Root: ceil08
+ Purpose: This test demonstrates the ceiling function with xs:decimal
+-->
+
+ <tdml:parserTestCase name="ceil_09" root="ceil08"
+ model="XPathFunctions" description="Section 23.5.2 - Standard XPath
Functions - ceiling - DFDL-23-095R">
+
+ <tdml:document>
+ <tdml:documentPart type="text"></tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ceil08>1</ceil08>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
<!--
Test Name: xPathFunc_floor_01
Schema: XPathFunctions
@@ -5600,6 +5635,26 @@
</tdml:parserTestCase>
<!--
+ Test Name: floor_09
+ Schema: XPathFunctions
+ Root: floor08
+ Purpose: This test demonstrates the floor function with xs:decimal
+-->
+
+ <tdml:parserTestCase name="floor_09" root="floor08"
+ model="XPathFunctions" description="Section 23.5.2 - Standard XPath
Functions - floor - DFDL-23-095R">
+
+ <tdml:document>
+ <tdml:documentPart type="text"></tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <floor08>0</floor08>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
+<!--
Test Name: xPathFunc_round_01
Schema: XPathFunctions
Root: round
@@ -5960,7 +6015,70 @@
</tdml:dfdlInfoset>
</tdml:infoset>
</tdml:parserTestCase>
-
+
+<!--
+ Test Name: round_17
+ Schema: XPathFunctions
+ Root: round08
+ Purpose: This test demonstrates the round function with xs:decimal
+-->
+
+ <tdml:parserTestCase name="round_17" root="round08"
+ model="XPathFunctions" description="Section 23.5.2 - Standard XPath
Functions - round - DFDL-23-095R">
+
+ <tdml:document>
+ <tdml:documentPart type="text"></tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <round08>0</round08>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
+<!--
+ Test Name: round_18
+ Schema: XPathFunctions
+ Root: round09
+ Purpose: This test demonstrates the round function with xs:decimal
+-->
+
+ <tdml:parserTestCase name="round_18" root="round09"
+ model="XPathFunctions" description="Section 23.5.2 - Standard XPath
Functions - round - DFDL-23-095R">
+
+ <tdml:document>
+ <tdml:documentPart type="text"></tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <round09>1</round09>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
+<!--
+ Test Name: round_19
+ Schema: XPathFunctions
+ Root: round10
+ Purpose: This test demonstrates the round function with xs:decimal
produces no side effects
+-->
+
+ <tdml:parserTestCase name="round_19" root="round10"
+ model="XPathFunctions" description="Section 23.5.2 - Standard XPath
Functions - round - DFDL-23-095R">
+
+ <tdml:document>
+ <tdml:documentPart type="text"></tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <round10>
+ <val>0.5</val>
+ <roundVal>1</roundVal>
+ </round10>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
<!--
Test Name: xPathFunc_round_hte_01
Schema: XPathFunctions
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 e2e4a86..876fdaf 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
@@ -407,6 +407,7 @@ class TestDFDLExpressions {
@Test def test_ceil_06() { runner2.runOneTest("ceil_06") }
@Test def test_ceil_07() { runner2.runOneTest("ceil_07") }
@Test def test_ceil_08() { runner2.runOneTest("ceil_08") }
+ @Test def test_ceil_09() { runner2.runOneTest("ceil_09") }
@Test def test_xPathFunc_floor_01() {
runner2.runOneTest("xPathFunc_floor_01") }
@Test def test_xPathFunc_floor_02() {
runner2.runOneTest("xPathFunc_floor_02") }
@@ -416,6 +417,7 @@ class TestDFDLExpressions {
@Test def test_floor_06() { runner2.runOneTest("floor_06") }
@Test def test_floor_07() { runner2.runOneTest("floor_07") }
@Test def test_floor_08() { runner2.runOneTest("floor_08") }
+ @Test def test_floor_09() { runner2.runOneTest("floor_09") }
@Test def test_xPathFunc_round_01() {
runner2.runOneTest("xPathFunc_round_01") }
@Test def test_xPathFunc_round_02() {
runner2.runOneTest("xPathFunc_round_02") }
@@ -433,6 +435,9 @@ class TestDFDLExpressions {
@Test def test_xPathFunc_round_14() {
runner2.runOneTest("xPathFunc_round_14") }
@Test def test_xPathFunc_round_15() {
runner2.runOneTest("xPathFunc_round_15") }
@Test def test_xPathFunc_round_16() {
runner2.runOneTest("xPathFunc_round_16") }
+ @Test def test_round_17() { runner2.runOneTest("round_17") }
+ @Test def test_round_18() { runner2.runOneTest("round_18") }
+ @Test def test_round_19() { runner2.runOneTest("round_19") }
@Test def test_xPathFunc_round_hte_01() {
runner2.runOneTest("xPathFunc_round_hte_01") }
@Test def test_xPathFunc_round_hte_02() {
runner2.runOneTest("xPathFunc_round_hte_02") }