Skip to content

Commit

Permalink
improve toInt method
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeloffner committed Feb 9, 2024
1 parent f9d90a2 commit 37155b9
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 11 deletions.
25 changes: 16 additions & 9 deletions core/src/main/java/lucee/runtime/op/Caster.java
Original file line number Diff line number Diff line change
Expand Up @@ -849,18 +849,19 @@ public static int toIntValue(Number n) {
}

public static int toIntValueLossless(double d) throws ExpressionException {
long l = Math.round(d);
// Check if d is within the int range
if (d < Integer.MIN_VALUE || d > Integer.MAX_VALUE) {
throw new ExpressionException("The value " + d + " is outside the range that can be represented as an int.");
if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
throw new ExpressionException("The value [" + Caster.toStringPercise(d) + "] is outside the range that can be represented as an int.");
}
// Check if the absolute value of the fractional part is smaller than the acceptable threshold
double fractionPart = d % 1;
double acceptableFraction = 1e-24;
if (Math.abs(fractionPart) >= acceptableFraction) {
throw new ExpressionException("The value " + d + " cannot be converted to int without significant data loss.");
}
return (int) Math.round(d); // Use Math.round to properly handle values very close to the next integer
int i = (int) l; // safe to do because of the test above

if (l == d) return i;

if (d > l && (d - l) < 0.000000000001) return i;
if (l > d && (l - d) < 0.000000000001) return i;

throw new ExpressionException("The value [" + Caster.toStringPercise(d) + "] cannot be converted to int without significant data loss.");
}

/**
Expand Down Expand Up @@ -2308,9 +2309,11 @@ public static String toString3(double d) {
return str;
}

private static DecimalFormat pf = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
private static DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
private static DecimalFormat ff = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
static {
pf.applyLocalizedPattern("#.################################################");
df.applyLocalizedPattern("#.########################");
ff.applyLocalizedPattern("#.#######");
}
Expand All @@ -2325,6 +2328,10 @@ public static String toString(double d) {
return df.format(d);
}

public static String toStringPercise(double d) {
return pf.format(d);
}

public static String toString(float f) {
long l = (long) f;
if (l == f) return toString(l);
Expand Down
4 changes: 2 additions & 2 deletions test/functions/BitAnd.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ component extends="org.lucee.cfml.test.LuceeTestCase"{
assertEquals("1",BitAnd(1, 3));
assertEquals("1",BitAnd(3, 5));
assertEquals("1",BitAnd(1, 1.0));
assertEquals("1",BitAnd(1, 0.999999999999999999));
assertEquals("0",BitAnd(1, 0.000000000000000001));
assertEquals("1",BitAnd(1, 0.999999999999));
assertEquals("0",BitAnd(1, 0.000000000001));
});

it(title="test outside the int range", body = function( currentSpec ) {
Expand Down

0 comments on commit 37155b9

Please sign in to comment.