Re: A g++ bug ... or not ?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 7 Sep 2018 at 16:43, Xi Ruoyao wrote:
>
> On 2018-09-07 17:03 +0200, Marc Glisse wrote:
> > On Sat, 8 Sep 2018, sisyphus1@xxxxxxxxxxxxxxx wrote:
> >
> > > Hi,
> > >
> > > The demo program:
> > >
> > > /****/
> > > /* try.c */
> > > #include <stdio.h>
> > > #include <math.h>
> > >
> > > int main(void) {
> > >
> > > int x = -1074;
> > >
> > > printf("%e\n", pow (2.0, (double)x));
> > > printf("%e\n", pow (2.0, x));
> > >
> > > return 0;
> > > }
> > >
> > > /****/
> > >
> > > If I build that program (using g++ version 7.3.0) with "g++ -ansi -o try
> > > try.c" I get output of:
> > >
> > > 4.940656e-324
> > > 0.000000e+000
> > >
> > > whereas I expected output to be:
> > >
> > > 4.940656e-324
> > > 4.940656e-324
> > >
> > > I guess that means that either my expectation is buggy, or something else is
> > > buggy.
>
> The "buggy" thing is
> <https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/Other-Builtins.html>:
>
>   Built-in Function: double __builtin_powi (double, int)
>   Returns the first argument raised to the power of the second. Unlike the pow
>   function no guarantees about precision and rounding are made.
>
> GCC's <cmath> header do different thing for C++11 and C++03.  In C++03,
> `double std::pow(double, int)` is implemented by `__builtin_powi`.  In C++11,
> it is implemented by casting the second parameter to double, and then call
> `pow(double, double)` from libc.
>
> The C++11 behavior is defined by 26.8 [c.math] para 11:
>
> > Moreover, there shall be additional overloads sufficient to ensure:
> > 1. If any argument corresponding to a double parameter has type long
> > double, then all arguments corresponding to double parameters are
> > effectively cast to long double.
> > 2. Otherwise, if any argument corresponding to a double parameter has
> > type double or an integer type, then all arguments corresponding to
> > double parameters are effectively cast to double.
> > 3. Otherwise, all arguments corresponding to double parameters are
> > effectively cast to float.
>
> And libstdc++ is doing right thing (casting the `int` parameter to
> `double`).  But C++03 is not so clear and does not define what should
> libstdc++ do.  Libstdc++ chooses to call __builtin_powi.  Unfortunately
> it is not so precise.
>
> > > Note 1:
> > > If the "-ansi" switch is omitted, then the output matches my expectation.
>
> "-ansi" means "-std=c++98".  Now GCC is defaulted to C++14.
>
> > Don't use -ansi, use -std= . Most likely you did not mean to use
> > -std=c++98.
> >
> > The exact set of overloads of pow in the C++ standard has varied with
> > time, https://en.cppreference.com/w/cpp/numeric/math/pow gives some idea.
> >
> > > Note 2:
> > > If cmath is #included instead of math.h, then the output matches my
> > > expectation.
> >
> > If you include cmath and not math.h, you should use std::pow.
>
> Yes.  std::pow gives the same "buggy" output.
>
> But, I wonder why don't we change the C++98/03 `pow` behavior to be same
> as C++11?  This is still standard and is more precise.
>
> Jonathan how do you think?

Maybe. I think that might resolve
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78851 too



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux