boostorg / math

Boost.org math module
http://boost.org/libs/math
Boost Software License 1.0
313 stars 226 forks source link

Overflow/underflow in quaternion and octanion division operator #1202

Open tk-yoshimura opened 2 months ago

tk-yoshimura commented 2 months ago

Overflow or underflow occurs when the divisor is a giant or minute number in quaternion and octanion division.

The following code, which is expected to yield 1, unexpectedly yields NaN.

#include <iostream>
#include <boost/math/quaternion.hpp>

int main(){
    boost::math::quaternion<double> q1(1e-200, 2e-200, 3e-200, 4e-200);
    boost::math::quaternion<double> q2 = q1 / q1;

    std::cout << q2 << std::endl;
}

I consider exponential normalization to be necessary in the following code. denominator underflows or overflows when rhs is a minute or huge number.

Quaternion: https://github.com/boostorg/math/blob/c3afa49c9a66523bd9be47888088337d0229a7cb/include/boost/math/quaternion.hpp#L398-L420

Octanion: https://github.com/boostorg/math/blob/c3afa49c9a66523bd9be47888088337d0229a7cb/include/boost/math/octonion.hpp#L561-L654

mborland commented 2 months ago

While this should get fixed have you tried Boost.QVM (https://www.boost.org/doc/libs/1_86_0/libs/qvm/doc/html/index.html)? I believe it has a much richer set of support than our quaternions (which is the oldest part of the library)

tk-yoshimura commented 2 months ago

Thank you for sharing about QVM.

Here is how I discovered this problem. While implementing complex Bessel functions, I encountered a similar problem with the division of the micro-norm. I verified that boost does not have a similar flaw and reported it because it seems to have the same mistake in quaternion and octonion.