On Tue, Jul 5, 2011 at 8:49 PM, Don <nospam@nospam.com> wrote:
James Fisher wrote:

On Tue, Jul 5, 2011 at 12:31 PM, James Fisher <jameshfisher@gmail.com <mailto:jameshfisher@gmail.com>> wrote:

   Sorry, I didn't state this very clearly.  Multiplying the
   approximation of PI in std.math should yield the exact double of
   that approximation, as it should just involve increasing the
   exponent by 1.  However, [double the approximation of the constant]
   is not necessarily equal to [the approximation of double the
   constant].  Does that make sense?

I understand what you're getting at, but actually multiplication by powers of 2 is always exact for binary floating point numbers.
The reason is that the rounding is based on the values after the lowest bit of the _significand_. The exponent plays no role.
Multiplication or division by two doesn't change the significand at all, only the exponent, so if the rounding was correct before, it is still correct after the multiplication.

Or to put it another way: PI in binary is a infinitely long string of 1s and zeros. Multiplying it by two only shifts the string left and right, it doesn't change any of the 1s to 0s, etc, so the approximation doesn't change either.

Great explanation, thanks.

(I think this is why the constants in math.d <https://github.com/D-Programming-Language/phobos/blob/master/std/math.d#L206> are each defined separately rather than in terms of each other.)

Hmm. I'm not sure why PI_2 and PI_4 are there. They should be defined in terms of PI. Probably should fix that.

Another thing -- why are some constants defined in decimal, others in hex, and one (E) with the long 'L' suffix?  And is there a significance to the number of decimal/hexadecimal places -- e.g., is this the minimum places required to ensure the closest floating point value for all common hardware accuracies?