Boost logo

Boost :

From: Daryle Walker (darylew_at_[hidden])
Date: 2000-07-24 18:02:23


on 7/23/00 7:28 AM, John Maddock at John_Maddock_at_[hidden] wrote:

> I noticed the following while looking through your math constants defs:
>
> 1) is the class int_math_const really necessary? I don't really see what
> benefit it brings?

I'm wondering that myself. You can always give the non-integer constants
truncated results, like what happens in a floating-to-integral conversion (e
would be 2, pi would be 3, etc.).

> 2) I wouldn't provide a default implementation for math_const, if
> math_const isn't specialised for a given type then using it should result
> in a compile time error, a simple declaration like:
>
> template <class T> struct math_const;
>
> is sufficient.

I don't think that would work. It could count as a forward declaration,
leading to a link-time error (not compile-time since the compiler could
assume it's just defined elsewhere). If it could result in a compile-time
error, you could not test that type! The is-specialized method works
better, since you could always check it and use it in meta-whatever stuff.

template <typename T>
struct math_const
{
    static bool is_specialized = false;

    // Should we even have fake-methods follow this? Having nothing
    // here would make any use of a non-specialized version choke.
    // We could leave nothing after this, but then you wouldn't get
    // a guide for future implementers. Another alternative would
    // be to define the methods as private, but have them public
    // for all specializations.
};

template <>
struct math_const<double>
{
    static bool is_specialized = true;

    //...
};

// more for float, long double, maybe for int, long, etc.
// ...

> 3) In the definition of math_const<float> you have:
>
> static const T sqrt_two() _THROW0()
> { return
> static_cast<T>(1.41421356237309504880168872420969807857L); }
>
> I think that I'm correct in saying that the value here will be rounded
> twice - once on decimal to binary conversion (to a long double), and then
> once again on conversion to float. However, some compilers will not do the
> second rounding (though according to the standard they should) and instead
> return the long double value. Whatever you may want to check your
> suffixes.

There's another problem: how do we know that the constant is long enough?
Some implementations may consider the literals given sufficient, others can
allow more precision, so a longer constant could be used. Is there a
minimum precision for float, double, and long double? Are floating-point
literals allowed to be longer that the implementation can handle, silently
truncating the extra digits? If so, maybe we could make the literals a
hundred or two digits long to be (currently) safe.

> 4) I'm not all that struck on your choice of names (although I don't
> necessarily have any better idea's!), some possible choices in place of
> math_const would be: numeric_values, math_values, math_constants, or just
> plain "math".

The name "math" would be too vague. The "math_constants" name would be a
nice adaptation of the name currently suggested. It's a general name, so
maybe only really generally important mathematical numbers (zero, one, pi,
e, gamma, etc.) should be in this class. A lot of the different constant
combinations probably shouldn't be in this class, but in similar class,
since a lot of people wouldn't need the derivative constants. (Maybe they
could be kept in the same header file.)

> For the names of members, lets try and keep them as short as possible, how
> about "root2" in place of "sqrt_two", and "r_root2" in place of
> "one_div_sqrt_two". There are a few other names that could have digits
> replace charcaters in parts of their names (I note that you do this already
> for ln_2): for example sin1, cos1 etc. BTW I don't think that you need an
> underscore to separate a digit from an character in these cases (so maybe
> just ln2 ln10 etc).

Actually, boost doesn't seem to use a compact naming style, and these
classes should remain consistent. The longer names provide a better
explanation of what the derivative constants are, and underscores mean the
user doesn't have to attempt inter-caps parsing.

"root2" is bad since:
1. The two words are run together. (I count a number as a word.)
2. It's inaccurate. You mean square root, but the original poster had cube
roots, etc., so "root" by itself is vague.

The "sqrt" part of "sqrt_two" (or "sqrt_2") is tolerable since "sqrt" is
already used by C/C++ as the square root function in the standard library.

I guess "reciprocal_sqrt_2" would be better than "r_root2" or
"one_div_sqrt_two" ("1_div_sqrt_2" is illegal, of course). It better
emphasizes that we want the multiplicative inverse of the square root of
two, not just one divided by two (like we could want negative one, not zero
minus one).

[I pretty much agree with you on part (5).]

-- 

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk