-
Notifications
You must be signed in to change notification settings - Fork 321
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add tests for Integer-Decimal cross-equality and fix these
- Loading branch information
Showing
17 changed files
with
212 additions
and
115 deletions.
There are no files selected for viewing
108 changes: 108 additions & 0 deletions
108
std-bits/base/src/main/java/org/enso/base/polyglot/NumericConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package org.enso.base.polyglot; | ||
|
||
import java.math.BigDecimal; | ||
|
||
/** | ||
* The numeric converter deals with conversions of Java numeric types to the two main types | ||
* supported by Enso - Long for integers and Double for decimals. Any other types are coerced to one | ||
* of these types. | ||
* | ||
* <p>It provides two concepts - coercion - which allows to coerce an integer type to a decimal, but | ||
* will not convert a decimal to an integer even if it has 0 fractional part. Then there is | ||
* conversion which allows to convert a decimal with 0 fractional part to an integer. Conversion | ||
* should be used when we care about the original type of the object (i.e. we want any decimals to | ||
* require decimal storage even if they have 0 fractional part). Conversion is to be used when we | ||
* want to be consistent with Enso's equality semantics where 2 == 2.0. | ||
*/ | ||
public class NumericConverter { | ||
/** | ||
* Coerces a number (possibly an integer) to a Double. | ||
* | ||
* <p>Will throw an exception if the object is not a number. | ||
*/ | ||
public static double coerceToDouble(Object o) { | ||
return switch (o) { | ||
case Double x -> x; | ||
case BigDecimal x -> x.doubleValue(); | ||
case Float x -> x.doubleValue(); | ||
default -> (double) coerceToLong(o); | ||
}; | ||
} | ||
|
||
/** | ||
* Coerces a number to an Integer. | ||
* | ||
* <p>Will throw an exception if the object is not an integer. | ||
* | ||
* <p>Decimal values are not accepted. | ||
*/ | ||
public static long coerceToLong(Object o) { | ||
return switch (o) { | ||
case Long x -> x; | ||
case Integer x -> x.longValue(); | ||
case Short x -> x.longValue(); | ||
case Byte x -> x.longValue(); | ||
default -> throw new UnsupportedOperationException(); | ||
}; | ||
} | ||
|
||
/** Returns true if the object is any supported number. */ | ||
public static boolean isCoercibleToDouble(Object o) { | ||
return o instanceof Double | ||
|| o instanceof BigDecimal | ||
|| o instanceof Float | ||
|| isCoercibleToLong(o); | ||
} | ||
|
||
/** | ||
* Returns true if the object is any supported integer. | ||
* | ||
* <p>Returns false for decimals with 0 fractional part - the type itself must be an integer type. | ||
*/ | ||
public static boolean isCoercibleToLong(Object o) { | ||
return o instanceof Long || o instanceof Integer || o instanceof Short || o instanceof Byte; | ||
} | ||
|
||
/** | ||
* Tries converting the value to a Double. | ||
* | ||
* <p>It will return null if the object represented a non-numeric value. | ||
*/ | ||
public static Double tryConvertingToDouble(Object o) { | ||
return switch (o) { | ||
case Double x -> x; | ||
case BigDecimal x -> x.doubleValue(); | ||
case Float x -> x.doubleValue(); | ||
case Long x -> x.doubleValue(); | ||
case Integer x -> x.doubleValue(); | ||
case Short x -> x.doubleValue(); | ||
case Byte x -> x.doubleValue(); | ||
case null, default -> null; | ||
}; | ||
} | ||
|
||
/** | ||
* Tries converting the value to a Long. | ||
* | ||
* <p>Decimal number types are accepted, only if their fractional part is 0. It will return null | ||
* if the object represented a non-integer value. | ||
*/ | ||
public static Long tryConvertingToLong(Object o) { | ||
return switch (o) { | ||
case Long x -> x; | ||
case Integer x -> x.longValue(); | ||
case Short x -> x.longValue(); | ||
case Byte x -> x.longValue(); | ||
case Double x -> x % 1.0 == 0.0 ? x.longValue() : null; | ||
case Float x -> x % 1.0f == 0.0f ? x.longValue() : null; | ||
case BigDecimal x -> { | ||
try { | ||
yield x.longValueExact(); | ||
} catch (ArithmeticException e) { | ||
yield null; | ||
} | ||
} | ||
case null, default -> null; | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 0 additions & 53 deletions
53
std-bits/table/src/main/java/org/enso/table/data/NumericConverter.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...able/src/main/java/org/enso/table/data/column/operation/aggregate/FunctionAggregator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 51 additions & 20 deletions
71
std-bits/table/src/main/java/org/enso/table/data/column/operation/map/SpecializedIsInOp.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.