Cole-Greer commented on code in PR #3153:
URL: https://github.com/apache/tinkerpop/pull/3153#discussion_r2224003410


##########
gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/NumberHelper.java:
##########
@@ -721,6 +723,86 @@ public static Number coerceTo(final Number a, final 
Class<? extends Number> claz
         return a;
     }
 
+    /**
+     * Casts the given number to the specified numeric type if it can fit into 
it.
+     * Otherwise, throw.
+     *
+     * @param a the number to be cast
+     * @param numberToken the number token denoting the desired type to cast
+     * @return the number cast to the specified type
+     * @throws IllegalArgumentException if the specified numeric type is 
unsupported
+     * @throws ArithmeticException if the number overflows
+     */
+    public static Number castTo(final Number a, final N numberToken) {
+        Class<?> clazz = numberToken.getType();
+        if (a.getClass().equals(clazz)) {
+            return a;
+        } else if (clazz.equals(Integer.class)) {
+            Long val = getLong(a, numberToken);
+            if (val >= Integer.MIN_VALUE && val <= Integer.MAX_VALUE) {
+                return a.intValue();
+            }
+        } else if (clazz.equals(Long.class)) {
+            return getLong(a, numberToken);
+        } else if (clazz.equals(Float.class)) {
+            // BigDecimal to double will overflow into Infinity, we want to 
throw instead of passing through
+            if (!a.getClass().equals(BigDecimal.class) &&

Review Comment:
   BigInteger will also be capable of overflowing into Infinity and will need 
special handling here as well



##########
gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/NumberHelper.java:
##########
@@ -721,6 +723,86 @@ public static Number coerceTo(final Number a, final 
Class<? extends Number> claz
         return a;
     }
 
+    /**
+     * Casts the given number to the specified numeric type if it can fit into 
it.
+     * Otherwise, throw.
+     *
+     * @param a the number to be cast
+     * @param numberToken the number token denoting the desired type to cast
+     * @return the number cast to the specified type
+     * @throws IllegalArgumentException if the specified numeric type is 
unsupported
+     * @throws ArithmeticException if the number overflows
+     */
+    public static Number castTo(final Number a, final N numberToken) {
+        Class<?> clazz = numberToken.getType();
+        if (a.getClass().equals(clazz)) {
+            return a;
+        } else if (clazz.equals(Integer.class)) {
+            Long val = getLong(a, numberToken);
+            if (val >= Integer.MIN_VALUE && val <= Integer.MAX_VALUE) {
+                return a.intValue();
+            }
+        } else if (clazz.equals(Long.class)) {
+            return getLong(a, numberToken);
+        } else if (clazz.equals(Float.class)) {
+            // BigDecimal to double will overflow into Infinity, we want to 
throw instead of passing through
+            if (!a.getClass().equals(BigDecimal.class) &&
+                    (Double.isInfinite(a.doubleValue()) || 
Double.isNaN(a.doubleValue())))  {
+                return a.floatValue();
+            }
+            if (a.doubleValue() >= -Float.MAX_VALUE && a.doubleValue() <= 
Float.MAX_VALUE) {
+                return a.floatValue();
+            }
+        } else if (clazz.equals(Double.class)) {
+            // BigDecimal to double will overflow into Infinity,  we want to 
throw instead of passing through
+            if (!a.getClass().equals(BigDecimal.class) &&
+                    (Double.isInfinite(a.doubleValue()) || 
Double.isNaN(a.doubleValue()))) {
+                return a.doubleValue();
+            }
+            if (!Double.isInfinite(a.doubleValue())) {
+                // float losses precision, use string intermediate
+                return a.getClass().equals(Float.class) ? 
Double.parseDouble(a.toString()) : a.doubleValue();

Review Comment:
   Is there loss of precision when directly using 
[Float.doubleValue()](https://docs.oracle.com/javase/8/docs/api/java/lang/Float.html#doubleValue--)?



##########
gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/NumberHelper.java:
##########
@@ -721,6 +723,86 @@ public static Number coerceTo(final Number a, final 
Class<? extends Number> claz
         return a;
     }
 
+    /**
+     * Casts the given number to the specified numeric type if it can fit into 
it.
+     * Otherwise, throw.
+     *
+     * @param a the number to be cast
+     * @param numberToken the number token denoting the desired type to cast
+     * @return the number cast to the specified type
+     * @throws IllegalArgumentException if the specified numeric type is 
unsupported
+     * @throws ArithmeticException if the number overflows
+     */
+    public static Number castTo(final Number a, final N numberToken) {
+        Class<?> clazz = numberToken.getType();
+        if (a.getClass().equals(clazz)) {
+            return a;
+        } else if (clazz.equals(Integer.class)) {
+            Long val = getLong(a, numberToken);
+            if (val >= Integer.MIN_VALUE && val <= Integer.MAX_VALUE) {
+                return a.intValue();
+            }
+        } else if (clazz.equals(Long.class)) {
+            return getLong(a, numberToken);
+        } else if (clazz.equals(Float.class)) {
+            // BigDecimal to double will overflow into Infinity, we want to 
throw instead of passing through
+            if (!a.getClass().equals(BigDecimal.class) &&
+                    (Double.isInfinite(a.doubleValue()) || 
Double.isNaN(a.doubleValue())))  {
+                return a.floatValue();
+            }
+            if (a.doubleValue() >= -Float.MAX_VALUE && a.doubleValue() <= 
Float.MAX_VALUE) {
+                return a.floatValue();
+            }
+        } else if (clazz.equals(Double.class)) {
+            // BigDecimal to double will overflow into Infinity,  we want to 
throw instead of passing through

Review Comment:
   BigInteger may also overflow here



##########
gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/NumberHelper.java:
##########
@@ -721,6 +723,86 @@ public static Number coerceTo(final Number a, final 
Class<? extends Number> claz
         return a;
     }
 
+    /**
+     * Casts the given number to the specified numeric type if it can fit into 
it.
+     * Otherwise, throw.
+     *
+     * @param a the number to be cast
+     * @param numberToken the number token denoting the desired type to cast
+     * @return the number cast to the specified type
+     * @throws IllegalArgumentException if the specified numeric type is 
unsupported
+     * @throws ArithmeticException if the number overflows
+     */
+    public static Number castTo(final Number a, final N numberToken) {
+        Class<?> clazz = numberToken.getType();
+        if (a.getClass().equals(clazz)) {
+            return a;
+        } else if (clazz.equals(Integer.class)) {
+            Long val = getLong(a, numberToken);
+            if (val >= Integer.MIN_VALUE && val <= Integer.MAX_VALUE) {
+                return a.intValue();
+            }
+        } else if (clazz.equals(Long.class)) {
+            return getLong(a, numberToken);
+        } else if (clazz.equals(Float.class)) {
+            // BigDecimal to double will overflow into Infinity, we want to 
throw instead of passing through
+            if (!a.getClass().equals(BigDecimal.class) &&
+                    (Double.isInfinite(a.doubleValue()) || 
Double.isNaN(a.doubleValue())))  {

Review Comment:
   I believe this will result in something like this:
   ```
   g.inject(5E50).asNumber(N.nfloat)
   ===> Infinity (float)
   ```
   as 5E50 can be represented as a non-infinite double, but not a float. Would 
we also want to throw in these cases?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to