This is an automated email from the ASF dual-hosted git repository.

andy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/jena.git

commit 16ec4d84d77196c2fd5ae75825df43beeeb6e913
Author: Andy Seaborne <[email protected]>
AuthorDate: Tue Dec 30 19:00:01 2025 +0000

    Rename NodeValue constants for certain xsd:double cases
---
 .../org/apache/jena/sparql/expr/NodeValue.java     | 28 +++++++++++----
 .../sparql/expr/nodevalue/NodeValueDouble.java     |  2 +-
 .../jena/sparql/expr/nodevalue/NodeValueFloat.java |  2 +-
 .../jena/sparql/expr/nodevalue/NodeValueOps.java   |  2 +-
 .../jena/sparql/expr/nodevalue/XSDFuncOp.java      | 40 ++++++++++++++++++++--
 .../org/apache/jena/sparql/function/CastXSD.java   |  9 +++--
 .../org/apache/jena/sparql/expr/LibTestExpr.java   |  4 +--
 .../jena/sparql/expr/TestExpressionsMath.java      | 16 ++++-----
 .../jena/sparql/expr/TestLeviathanFunctions.java   |  2 +-
 9 files changed, 80 insertions(+), 25 deletions(-)

diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
index 26fc926e66..e127b4aaf0 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
@@ -106,19 +106,35 @@ public abstract class NodeValue extends ExprNode
     public static final NodeValue TRUE   = NodeValue.makeNode("true", 
XSDboolean);
     public static final NodeValue FALSE  = NodeValue.makeNode("false", 
XSDboolean);
 
+    public static final NodeValue nvEmptyString  = NodeValue.makeString("");
+
     public static final NodeValue nvZERO = 
NodeValue.makeNode(NodeConst.nodeZero);
-    public static final NodeValue nvNegZERO = NodeValue.makeNode("-0.0e0", 
XSDdouble);
     public static final NodeValue nvONE  = 
NodeValue.makeNode(NodeConst.nodeOne);
     public static final NodeValue nvTEN  = 
NodeValue.makeNode(NodeConst.nodeTen);
 
     public static final NodeValue nvDecimalZERO = NodeValue.makeNode("0.0", 
XSDdecimal);
     public static final NodeValue nvDecimalONE  = NodeValue.makeNode("1.0", 
XSDdecimal);
 
-    public static final NodeValue nvNaN     = NodeValue.makeNode("NaN", 
XSDdouble);
-    public static final NodeValue nvINF     = NodeValue.makeNode("INF", 
XSDdouble);
-    public static final NodeValue nvNegINF  = 
NodeValue.makeNode("-INF",XSDdouble);
+    public static final NodeValue nvDoubleNegZERO = 
NodeValue.makeNode("-0.0e0", XSDdouble);
+    public static final NodeValue nvDoubleNaN     = NodeValue.makeNode("NaN", 
XSDdouble);
+    public static final NodeValue nvDoubleINF     = NodeValue.makeNode("INF", 
XSDdouble);
+    public static final NodeValue nvDoubleNegINF  = 
NodeValue.makeNode("-INF",XSDdouble);
 
-    public static final NodeValue nvEmptyString  = NodeValue.makeString("");
+    /** @deprecated Use {@link #nvDoubleNegZERO} */
+    @Deprecated
+    public static final NodeValue nvNegZERO = nvDoubleNegZERO;
+
+    /** @deprecated Use {@link #nvDoubleNaN} */
+    @Deprecated
+    public static final NodeValue nvNaN     = nvDoubleNaN;
+
+    /** @deprecated Use {@link #nvDoubleINF} */
+    @Deprecated
+    public static final NodeValue nvINF     = nvDoubleINF;
+
+    /** @deprecated Use {@link #nvDoubleNegINF} */
+    @Deprecated
+    public static final NodeValue nvNegINF  = nvDoubleNegINF;
 
     public static final String xsdNamespace = XSD+"#";
 
@@ -605,7 +621,7 @@ public abstract class NodeValue extends ExprNode
         // Java equals, not "same value" or "same term"
         if ( other == null ) return false;
         if ( this == other ) return true;
-        // This is the equality condition Jena uses - lang tags are different 
by case.
+        // This is the equality condition Jena uses
         if ( ! ( other instanceof NodeValue nv) )
             return false;
         return asNode().equals(nv.asNode());
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueDouble.java
 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueDouble.java
index 0351f913d7..5e404a7141 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueDouble.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueDouble.java
@@ -31,7 +31,7 @@ import org.apache.jena.sparql.util.XSDNumUtils;
 
 public class NodeValueDouble extends NodeValue {
 
-    double value = Double.NaN;
+    private final double value;
 
     public NodeValueDouble(double d)         { super(); value = d; }
     public NodeValueDouble(double d, Node n) { super(n); value = d; }
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueFloat.java
 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueFloat.java
index 20cfc14dea..0b32c89a86 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueFloat.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueFloat.java
@@ -26,7 +26,7 @@ import org.apache.jena.sparql.util.XSDNumUtils;
 
 public class NodeValueFloat extends NodeValue
 {
-    float value = Float.NaN;
+    private final float value;
 
     public NodeValueFloat(float f)         { super(); value = f; }
     public NodeValueFloat(float f, Node n) { super(n); value = f; }
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueOps.java
 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueOps.java
index b11cbc79ad..5b397efb6f 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueOps.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueOps.java
@@ -40,7 +40,7 @@ import org.apache.jena.sparql.util.NodeUtils;
  * Operations relating to {@link NodeValue NodeValues}.
  * <ul>
  * <li>The code parts of arithmetic operations on {@link NodeValue}s.
- * <li>Library code such as Argument testing
+ * <li>Library code such as expression string argument testing
  * </ul>
  * <p>
  * This class is not considered to be part of the ARQ API.
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java
index 6bfc904fe1..6fd848817d 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java
@@ -397,14 +397,50 @@ public class XSDFuncOp
                     dec = v.getDecimal().setScale(0, RoundingMode.HALF_UP);
                 return NodeValue.makeDecimal(dec);
             case OP_FLOAT:
-                return NodeValue.makeFloat(Math.round(v.getFloat()));
+                return NodeValue.makeFloat(roundFloat(v.getFloat()));
             case OP_DOUBLE:
-                return NodeValue.makeDouble(Math.round(v.getDouble()));
+                return NodeValue.makeDouble(roundDouble(v.getDouble()));
             default:
                 throw new ARQInternalErrorException("Unrecognized numeric 
operation : " + v);
         }
     }
 
+    private static double roundDouble(double d) {
+        if ( Double.isNaN(d) )
+            return Double.NaN;
+        if ( d == Double.POSITIVE_INFINITY )
+            return d;
+        if ( d == Double.NEGATIVE_INFINITY )
+            return d;
+        if ( d == -0.0e0 )
+            return d;
+        // Math.round returns a java long
+        long resultLong = Math.round(d);
+        if ( resultLong == 0 && d < 0 )
+            // Return -0 for round negative to 0.
+            return -0.0e0d;
+        // Cast to double by the return.
+        return resultLong;
+    }
+
+    private static float roundFloat(float f) {
+        if ( Float.isNaN(f) )
+            return Float.NaN;
+        if ( f == Float.POSITIVE_INFINITY )
+            return f;
+        if ( f == Float.NEGATIVE_INFINITY )
+            return f;
+        if ( f == -0.0e0f )
+            return f;
+        // Math.round returns a java long
+        long resultLong = Math.round(f);
+        if ( resultLong == 0 && f < 0 )
+            // Return -0 for round negative to 0.
+            return -0.0e0f;
+        // Math.round returns a java long, which is cast to float by the 
return.
+        return resultLong;
+    }
+
     // The following function 'roundXpath3' implements the definition for 
"fn:round" in F&O v3.
     // This is different to the "fn:round" in F&O v2.
     // SPARQL 1.1 references F&O v2.
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD.java
index ae43940b2c..07362c4142 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD.java
@@ -18,8 +18,8 @@
 
 package org.apache.jena.sparql.function;
 
-import static org.apache.jena.sparql.expr.NodeValue.nvNaN;
-import static org.apache.jena.sparql.expr.NodeValue.nvNegZERO;
+import static org.apache.jena.sparql.expr.NodeValue.nvDoubleNaN;
+import static org.apache.jena.sparql.expr.NodeValue.nvDoubleNegZERO;
 import static org.apache.jena.sparql.expr.NodeValue.nvZERO;
 import static org.apache.jena.sparql.expr.nodevalue.XSDFuncOp.*;
 import java.math.BigDecimal;
@@ -273,7 +273,10 @@ public class CastXSD {
         if ( nv.isBoolean() )
             return nv;
         if ( nv.isNumber() ) {
-            if ( NodeValue.sameValueAs(nv, nvZERO) || 
NodeValue.sameValueAs(nv, nvNaN) || NodeValue.sameValueAs(nv, nvNegZERO) )
+            if ( NodeValue.sameValueAs(nv, nvZERO) )
+                return NodeValue.FALSE;
+            // sameValueAs Covers xsd:float
+            if ( NodeValue.sameValueAs(nv, nvDoubleNaN) || 
NodeValue.sameValueAs(nv, nvDoubleNegZERO) )
                 return NodeValue.FALSE;
             return NodeValue.TRUE;
         }
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/LibTestExpr.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/LibTestExpr.java
index b56dec1871..44e455442b 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/LibTestExpr.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/LibTestExpr.java
@@ -94,8 +94,8 @@ public class LibTestExpr {
         assertTrue(sameValueSameDatatype(expected, actual), ()->"Expected = " 
+ expected + " : Actual = " + actual);
     }
 
-    public static void testIsNaN(String exprStr) {
-        testSameObject(exprStr, NodeValue.nvNaN);
+    public static void testDoubleIsNaN(String exprStr) {
+        testSameObject(exprStr, NodeValue.nvDoubleNaN);
     }
 
     public static void testSameObject(String exprStr, NodeValue expected) {
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressionsMath.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressionsMath.java
index 13e8aa18e7..d8392350f9 100644
--- 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressionsMath.java
+++ 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressionsMath.java
@@ -20,7 +20,7 @@ package org.apache.jena.sparql.expr;
 
 import static org.apache.jena.sparql.expr.LibTestExpr.test;
 import static org.apache.jena.sparql.expr.LibTestExpr.testDouble;
-import static org.apache.jena.sparql.expr.LibTestExpr.testIsNaN;
+import static org.apache.jena.sparql.expr.LibTestExpr.testDoubleIsNaN;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
 import org.junit.jupiter.api.Test;
@@ -41,7 +41,7 @@ public class TestExpressionsMath
     @Test public void exp_04()          { test("math:exp(1e0/0)", 
"'INF'^^xsd:double"); }
     @Test public void exp_05()          { test("math:exp('INF'^^xsd:double)", 
"'INF'^^xsd:double"); }
     @Test public void exp_06()          { test("math:exp('-INF'^^xsd:double)", 
"'0.0e0'^^xsd:double"); }
-    @Test public void exp_07()          { 
testIsNaN("math:exp('NaN'^^xsd:double)"); }
+    @Test public void exp_07()          { 
testDoubleIsNaN("math:exp('NaN'^^xsd:double)"); }
 
     @Test public void exp10_01()        { test("math:exp10(2)", "100"); }
     @Test public void exp10_02()        { testDouble("math:exp10(-1)", 0.1, 
0.00001); }
@@ -55,7 +55,7 @@ public class TestExpressionsMath
     @Test public void log_04()          { test("math:log(0)", 
"'-INF'^^xsd:double"); }
     @Test public void log_05()          { test("math:exp('INF'^^xsd:double)", 
"'INF'^^xsd:double"); }
     @Test public void log_06()          { test("math:exp('-INF'^^xsd:double)", 
"'0.0e0'^^xsd:double"); }
-    @Test public void log_07()          { 
testIsNaN("math:exp('NaN'^^xsd:double)"); }
+    @Test public void log_07()          { 
testDoubleIsNaN("math:exp('NaN'^^xsd:double)"); }
 
     @Test public void pow_01()          { test("math:pow(2,2)", "4"); }
     @Test public void pow_02()          { testDouble("math:pow(2,-2)", 0.25, 
0.00001); }
@@ -67,18 +67,18 @@ public class TestExpressionsMath
 
     @Test public void pow_13()          { 
test("math:pow('INF'^^xsd:double,0)", "'1.0e0'^^xsd:double"); }
     @Test public void pow_14()          { test("math:pow('-INF'^^xsd:double, 
0)", "'1.0e0'^^xsd:double"); }
-    @Test public void pow_15()          { 
testIsNaN("math:pow('NaN'^^xsd:double, 1)"); }
-    @Test public void pow_16()          { testIsNaN("math:pow(1, 
'NaN'^^xsd:double)"); }
+    @Test public void pow_15()          { 
testDoubleIsNaN("math:pow('NaN'^^xsd:double, 1)"); }
+    @Test public void pow_16()          { testDoubleIsNaN("math:pow(1, 
'NaN'^^xsd:double)"); }
 
     @Test public void sqrt_01()         { test("math:sqrt(1)", 
"'1.0e0'^^xsd:double"); }
     @Test public void sqrt_02()         { testDouble("math:sqrt(2)", 
Math.sqrt(2), 0.000001); }
-    @Test public void sqrt_03()         { testIsNaN("math:sqrt(-2)"); }
+    @Test public void sqrt_03()         { testDoubleIsNaN("math:sqrt(-2)"); }
 
     @Test public void sqrt_04()         { assertThrows(ARQException.class, 
()->test("math:sqrt('TWO')", "'dummy'")); }
 
     @Test public void sqrt_10()         { test("math:sqrt('INF'^^xsd:double)", 
"'INF'^^xsd:double"); }
-    @Test public void sqrt_11()         { 
testIsNaN("math:sqrt('-INF'^^xsd:double)"); }
-    @Test public void sqrt_12()         { 
testIsNaN("math:sqrt('NaN'^^xsd:double)"); }
+    @Test public void sqrt_11()         { 
testDoubleIsNaN("math:sqrt('-INF'^^xsd:double)"); }
+    @Test public void sqrt_12()         { 
testDoubleIsNaN("math:sqrt('NaN'^^xsd:double)"); }
 
     //  4.8.7 math:sqrt
     //  4.8.8 math:sin
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestLeviathanFunctions.java
 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestLeviathanFunctions.java
index 55e06dc527..bf10c8c831 100644
--- 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestLeviathanFunctions.java
+++ 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestLeviathanFunctions.java
@@ -135,7 +135,7 @@ public class TestLeviathanFunctions {
     public void log_03() {
         NodeValue actual = LibTestExpr.eval("lfn:log(-1)");
         // Test the object, not the value.
-        assertTrue(NodeValue.nvNaN.equals(actual));
+        assertTrue(NodeValue.nvDoubleNaN.equals(actual));
     }
 
     @Test

Reply via email to