


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:

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, 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.