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") }

Reply via email to