Hi Vitaly, On 18.01.2018 15:48, Vitaly Magerya wrote:
It will, but usually if you've called normal() on something you don't want to throw the result away, you want to store it. This is because normal() is slow (GCDs and stuff). Auto-normal()ing in is_zero() and throwing away the result is a waste, and can be a major performance hit for some applications.
On a related note: when testing for zero you don't really need the full normal() calculation, which involves canceling common divisors of numerator and denominator -- you can keep those in; if you have any in the final result, then the expression is not a zero anyway. Basically, there's a place for normal() equivalent which never calls gcd().
It's better to keep .is_zero() lightweight. Adding clever things not only makes it slow, it also might be a slippery road: Where should one stop? How clever should we make it? (Cf. Richardson's theorem.)
On another related note: there's a flag that tells you if an expression is expanded (status_flag::expanded), which presumably exists so that expand() repeated twice would be a quick no-op. There's no such flag for normal() though, and I'd argue it's much more needed there than in expand(). With such a flag you could pretty much put normal() all over the place without fearing for wasted computation: performance-minded code would have already normal()ized whatever it's passing into is_zero() and the like, so no performance penalty there, and more careless code would get the benefit of always obtaining correct results even when it forgot to normal()ize it's expressions.
This sounds very reasonable. Would you like to try your hand at a patch? All my best, -richy.