Description
Expected Behavior
Clicking on a +
block with 0.1 and 0.2 as its arguments should show 0.3 as the result.
Actual Behavior
Clicking on a +
block with 0.1 and 0.2 as its arguments shows 0.30000000000000004 as the result.
Similar results can be seen with asin of 0.5
and other mathematical expressions.
Suggestion
For background information, see: https://0.30000000000000004.com/
One could argue that, since 0.1 and 0.2 cannot be accurately represented in IEEE floating point numbers, it's "correct" to show 0.30000000000000004 as the answer when adding those two values. I would argue that doing so is only valuable to a minority of our audience, and makes working with math more difficult for the majority of our audience.
In my opinion we should consider using something like https://github.com/MikeMcl/decimal.js for math blocks in Scratch so that the results of Scratch math expressions are correct without having to consider the details of IEEE floating point format. For example:
let a = Decimal('0.1');
let b = Decimal('0.2');
let c = a.add(b); // same as Decimal.add('0.1', '0.2')
console.log(c.toString()); // shows "0.3"
console.log(c == 0.3); // shows "true"
console.log(c === 0.3); // shows "false"
let a = Decimal('0.5');
let b = a.asin(); // same as Decimal.asin('0.5')
const pi = Decimal.acos(-1);
const radiansToDegrees = Decimal.div(180, pi);
let bDegrees = b.mul(radiansToDegrees);
console.log(bDegrees.toString()); // shows "30"
console.log(bDegrees == 30); // shows "true"
console.log(bDegrees === 30); // shows "false"
One downside is that math operations will be somewhat slower. If we do this, we should do at least two kinds of testing:
- Test several complex projects, especially math-driven ones, to see if performance suffers too much, and
- Check for compatibility problems since there may be projects out there relying on the floating-point behavior, for example with equality or inequality tests.