Conversation
There was a problem hiding this comment.
Needs work.
I'm wondering if there isn't a simpler solution, to use the double functionality as is, but if it is floats we do a shrink (if they fit) else expand to Double/BigDecimal as needed. This will be a much smaller change and less things that can cause additional headaches.
| if (lhs instanceof BigDecimal) | ||
| return bigDecimalBinaryOperation( (BigDecimal) lhs, (BigDecimal) rhs, kind ); | ||
| if (lhs instanceof Float) | ||
| return floatBinaryOperation( (Float) lhs, (Float) rhs, kind ); |
There was a problem hiding this comment.
This will cause a precision problem, and even cast error, if rhs is double.
There was a problem hiding this comment.
binaryOperationImpl only has one usage (in Operators.binaryOperation()), and that is after lhs and rhs have been passed through Operators.promotePrimitves(). At this point if lhs is Float it is not possible for rhs to not be Float.
|
|
||
| } | ||
| if ( OVERFLOW_OPS.contains(kind) ) | ||
| return bigDecimalBinaryOperation(BigDecimal.valueOf(lhs), BigDecimal.valueOf(rhs), kind); |
There was a problem hiding this comment.
I wonder if we shouldn't first overflow to double here
There was a problem hiding this comment.
Can we just stick with Java math please? Some of us depend on it.
| case POWER: | ||
| case POWERX: | ||
| double check = Math.pow(lhs, rhs); | ||
| if ( Double.isInfinite(check) ) |
There was a problem hiding this comment.
Should we not try and return a float here?
There was a problem hiding this comment.
Math.pow returns a double, so no one is expecting to get a float here.
src/main/java/bsh/Operators.java
Outdated
| lhs = Long.valueOf(lnum.longValue()); | ||
| if ( !(rhs instanceof Long) ) | ||
| rhs = Long.valueOf(rnum.longValue()); | ||
| if (!(lhs instanceof Float && rhs instanceof Float)) { |
There was a problem hiding this comment.
It is hard to see what happens here but this seems wrong.
From the existing function:
beanshell/src/main/java/bsh/Operators.java
Lines 513 to 541 in 53b0436
There is a precedence BigDecimal, Double, BigInteger, Long and it seems this check needs to be around line 524 when we are checking for Doubles.
There was a problem hiding this comment.
I can refactor this but the outcome will be the same.
| throw new InterpreterError("Can only shrink wrap Number types"); | ||
| Number value = (Number) number; | ||
| if (value instanceof Float) | ||
| return new Primitive(value.floatValue()); |
There was a problem hiding this comment.
I think this needs to do something similar to int and long, comparing the values instead of the type.
See full function 193 and 195:
beanshell/src/main/java/bsh/Primitive.java
Lines 178 to 198 in 53b0436
I wonder if this would not be sufficient, to just shrink the double result to float if it fits?
There was a problem hiding this comment.
If you do the widen float to double, do the operation, and then narrow you will get a different result than doing the operation in float. Best to keep this the same as Java.
In Java byte and short use int as a carrier type. Arithmetic on any combination of these types will yield an int. Best to keep this the same as Java.
This is a fix for issue #767 where float expressions are widened to doubles.