| Home | Libraries | People | FAQ | More

## Calculation of the Type of the Result

The functions in this library are all overloaded to accept mixed floating point (or mixed integer and floating point type) arguments. So for example:

    foo(1.0, 2.0);
    foo(1.0f, 2);
    foo(1.0, 2L);

etc, are all valid calls, as long as "foo" is a function taking two floating-point arguments. But that leaves the question:

"Given a special function with N arguments of types T1, T2, T3 ... TN, then what type is the result?"

If all the arguments are of the same (floating point) type then the result is the same type as the arguments.

Otherwise, the type of the result is computed using the following logic:

1. Any arguments that are not template arguments are disregarded from further analysis.
2. For each type in the argument list, if that type is an integer type then it is treated as if it were of type `double` for the purposes of further analysis.
3. If any of the arguments is a user-defined class type, then the result type is the first such class type that is constructible from all of the other argument types.
4. If any of the arguments is of type `long double`, then the result is of type `long double`.
5. If any of the arguments is of type `double`, then the result is of type `double`.
6. Otherwise the result is of type `float`.

For example:

    cyl_bessel(2, 3.0);

Returns a `double` result, as does:

    cyl_bessel(2, 3.0f);

as in this case the integer first argument is treated as a `double` and takes precedence over the `float` second argument. To get a `float` result we would need all the arguments to be of type float:

    cyl_bessel_j(2.0f, 3.0f);

When one or more of the arguments is not a template argument then it doesn't effect the return type at all, for example:

    sph_bessel(2, 3.0f);

returns a `float`, since the first argument is not a template argument and so doesn't effect the result: without this rule functions that take explicitly integer arguments could never return `float`.

And for user-defined types, typically Boost.Multiprecision,

All of the following return a `boost::multiprecision::cpp_bin_quad_float` result:

    cyl_bessel_j(0, boost::multiprecision::cpp_bin_quad_float(2));

    cyl_bessel_j(boost::multiprecision::cpp_bin_quad_float(2), 3);

    cyl_bessel_j(boost::multiprecision::cpp_bin_quad_float(2), boost::multiprecision::cpp_bin_quad_float(3));

but rely on the parameters provided being exactly representable, avoiding loss of precision from construction from `double`.

| Tip
All new projects should use Boost.Multiprecision.

During development of Boost.Math, NTL A Library for doing Number Theory was invaluable to create highly precise tables.

All of the following return an `NTL::RR` result:

    cyl_bessel_j(0, NTL::RR(2));

    cyl_bessel_j(NTL::RR(2), 3);

    cyl_bessel_j(NTL::quad_float(2), NTL::RR(3));

In the last case, `quad_float` is convertible to `RR`, but not vice-versa, so the result will be an `NTL::RR`. Note that this assumes that you are using a patched NTL library.

These rules are chosen to be compatible with the behaviour of ISO/IEC 9899:1999 Programming languages - C and with the Draft Technical Report on C++ Library Extensions, 2005-06-24, section 5.2.1, paragraph 5.