Measured on master (2b4a5256), with DowncastingEnabled off, as a numerical verification evaluates:
(-0.473)^(1/2) -> -6.1e-102 + 0.68775i (the real part should be 0)
(-4)^(1/2) -> -1.8e-101 + 2i
((-0.473)^(1/2))^2 -> -0.473 - 8.4e-102 i (should be -0.473 exactly)
ln(((-0.473)^(1/2))^2) -> -0.7487 - 3.14159 i (ln(-0.473) is -0.7487 + 3.14159 i)
Two causes, both in Number.Pow:
- A negative real to a half power goes through the polar form,
rho^p (cos(p theta) + i sin(p theta)) with theta = pi from Arctan2, and cos(pi/2) at a hundred digits is 6e-102, not zero. The principal root of a negative real is the root of the modulus times i, exactly, and the same for every power that is a whole number of halves ((-4)^(3/2) is -8i; (-8)^(1/3) is not affected — a third is not a multiple of a right angle, and this library's real-root convention for it stays).
- With the downcasting off, the literal
2 arrives as the decimal 2, not the Integer, so z^2 takes the polar form too instead of the exact multiplication z * z — which is what turns (0 + 0.68775i)^2 into -0.473 - 8.4e-102 i: a hair below the negative axis, where ln reads -i pi for the +i pi the number has.
Together they made a right antiderivative read as wrong: u ln(u^2) for u = sqrt(-1 + a x) is sqrt(-1 + a x) ln(((-1 + a x)^(1/2))^2) written back, whose numerical derivative at -1 + a x < 0 disagreed with the integrand by exactly the 2 pi i of the branch — the corpus harness reported the answer wrong at 3 of 6 points while its symbolic derivative is the integrand.
Fix in the PR that found it: a negative real base to a real power that is a whole number of halves is the modulus to that power times i^k, exactly; and a real power that is a whole number is read as the integer it is, so the exact multiplication is used.
Measured on master (
2b4a5256), withDowncastingEnabledoff, as a numerical verification evaluates:Two causes, both in
Number.Pow:rho^p (cos(p theta) + i sin(p theta))withtheta = pifromArctan2, andcos(pi/2)at a hundred digits is6e-102, not zero. The principal root of a negative real is the root of the modulus timesi, exactly, and the same for every power that is a whole number of halves ((-4)^(3/2)is-8i;(-8)^(1/3)is not affected — a third is not a multiple of a right angle, and this library's real-root convention for it stays).2arrives as the decimal2, not theInteger, soz^2takes the polar form too instead of the exact multiplicationz * z— which is what turns(0 + 0.68775i)^2into-0.473 - 8.4e-102 i: a hair below the negative axis, wherelnreads-i pifor the+i pithe number has.Together they made a right antiderivative read as wrong:
u ln(u^2)foru = sqrt(-1 + a x)issqrt(-1 + a x) ln(((-1 + a x)^(1/2))^2)written back, whose numerical derivative at-1 + a x < 0disagreed with the integrand by exactly the2 pi iof the branch — the corpus harness reported the answer wrong at 3 of 6 points while its symbolic derivative is the integrand.Fix in the PR that found it: a negative real base to a real power that is a whole number of halves is the modulus to that power times
i^k, exactly; and a real power that is a whole number is read as the integer it is, so the exact multiplication is used.