On 01/18/2018 03:19 PM, Vladimir V. Kisil wrote:
From time to time I am asking myself either .is_zero() needs to call .normal() first and then make the test. This would look more natural in my opinion.
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(). 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.