-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unit.equals
throws an exception when using Fractions, whilst math.equal
works as expected
#2918
Comments
okay, so after some debugging I think the problem comes from precision when converting the unitary degree to a fraction. I've come up with the following: Because we're using the Fraction parametrisation, at the time we compare such values, we end up in the following piece of code ( inside typed.js ): from: 'number',
to: 'Fraction',
convert: function (x) {
if (!Fraction) {
throwNoFraction(x)
}
const f = new Fraction(x)
if (f.valueOf() !== x) {
throw new TypeError('Cannot implicitly convert a number to a Fraction when there will be a loss of precision ' +
'(value: ' + x + '). ' +
'Use function fraction(x) to convert to Fraction.')
}
return f
} With 'f' and 'x' given by: So the condition if(f.valueOf() !== x){
...
} evaluates to true because f.valueOf() and x still differ by a small margin, and therefore the mentioned error is thrown. But even if this expression evaluates to false, we end up in this final comparison inside equalScalar.js 'Fraction, Fraction': function (x, y) {
return x.equals(y)
}, Where the 'equals' function used comes from this line from fraction.js. And when the such function is called with the below arguments, it returns false: What I came up locally to get the right result is to instead use an equality based on if the modulo of difference is less than the default epsilon. Do we use this solutions in order to get it right ? Any thoughts ? |
Testing this again I now get the same error in both cases The cause is indeed the error that warns about losing precision. The error is thrown because we try to compare a Fraction with a number and there is indeed an inaccuracy when converting the number to a Fraction. I think we can change the strict test |
I don't understand why we compare a fraction with a number... I'm surpise we need to use an epsilon to compare two fractions ... they are exact numbers, comparison should be exact. I guess. |
The reason is that in the following code the unit const math = create(all, { number: 'Fraction' })
math.createUnit('rotation', {definition: '360 deg', aliases: ['tour','tr']})
const a = math.unit(360, 'deg'); // a has a value being a number since deg is defined as number
const b = math.unit(1, 'rotation'); // b has a value being a Fraction since rotation is defined as Fraction
expect(b.equals(a)); |
OK thanks, this is clear ! |
…port for units, see #2918 (#2926) * feat: extend function `fraction` with support for units (see #2918) * fix: update the TypeScript definitions with the new `math.fraction(value: Unit)` support * feat: implement `math.bignumber(value: Unit)` * feat: update type definitions of function `math.bignumber` * fix: linting issue * feat: implement support for `math.number(unit)` (was formerly throwing an exception)
This is solved now by extending the function |
From #2915
Apparently the method
Unit.equals
internally tries to convert the Fraction into a number. For some reason the functionmath.equal(a, b)
does work as expected whereasb.equals(a)
throws this error.It sounds like this is a solvable bug. Anyone able to look into this? Help would be welcome.
The text was updated successfully, but these errors were encountered: