[Development] Qt pi
Edward Welbourne
edward.welbourne at qt.io
Wed Jan 11 15:35:35 CET 2017
Hi all,
In the course of testing 5.8.0, I was puzzled by an example hard-coding
a value for pi, rather than re-using one from some public header as I
expected. To my surprise, the standard library only provides M_PI as a
POSIX extension. It turns out we do have a qmath.h that, sensibly
enough, does
#ifndef M_PI
#define M_PI (3.14159265358979323846)
#endif
Despite this, 302 other places in my Qt-dev source tree supply their own
values for pi. There is some diversity of values. Let's start with the
correctly-rounded ones:
3.14159
3.14159265 (enough for float - see below)
3.14159265358979
3.141592653589793 (enough for double - see below)
3.1415926535897932
3.141592653589793238
3.14159265358979323846 (same as M_PI in qmath.h)
3.1415926535897932384626433832795
3.14159265358979323846264338327950288
3.14159265358979323846264338327950288419717
3.14159265359
3.1415927
Then the truncated ones that aren't correct roundings (in each case, the
last digit needs +1):
3.1415
3.141592
3.1415926
3.1415926535
3.141592653589
Finally, the values that look suspiciously like they were meant to be
pi, but aren't (inserting a space after the last matching digit):
3.1415 2 (missing 9) In several parameters to sin(...)
3.14159 62 (last two digits swapped) In some JS benchmarks
3.14159265358979 23846 (missing 3) In an ECMA JS test
I am fairly sure the parameters to sin were meant to use pi; and I
suspect changing the JS tests is out-of-scope as they look like imports
(i.e. third-party).
Wikipedia gives the following first 49 digits (followed by a 0):
3.1415926535897932384626433832795028841971693993751
Experiment with gcc on 64-bit Intel reveals that there is no point
supplying more than the following digits, for each type:
long double: 3.1415926535897932385
double: 3.141592653589793
float: 3.1415927
So our M_PI is almost good. It coincides with what Linux's <math.h>
provides, except that we put parentheses round it - can anyone give me a
good reason for that ? I doubt it matters. However, neither M_PI puts
an L suffix on it, so its last four digits are effectively ignored
(because a floating literal is double by default).
It looks like it would make sense to:
i) Change qmath.h's M_PI to (3.14159265358979323846L)
i.e. make it a long double, let context downgrade it as needed
ii) Change all other hand-crafted approximations to use M_PI.
Can anyone offer me a sane reason to not do this ?
We have have little arithmetic irregularities creeping in from our
inconsistencies ...
Eddy.
More information about the Development
mailing list