0

Why is there no difference between double, long double or float?

For instance, the computation of pi in C++ is,

#include <iostream>
#include <quadmath.h>
#include <math.h> 

int main()
{
  float  PI0 = acos(-1.0);
  double PI1 = acos(-1.0);
  long double PI2= acos(-1.0L);

  __float128 x = acos(-1.0);
  char buf[128];
  quadmath_snprintf (buf, sizeof buf, "%*.34Qf",10, x);


  std::cout << "Float=" << PI0 << std::endl;
  std::cout << "Double=" << PI1 << std::endl;
  std::cout << "LongDouble=" << PI2 << std::endl;
  std::cout << "Float128=" << buf << std::endl;

}

In the terminal:

g++ -std=c++14 FileName.cpp -Wall -pedantic -lquadmath && ./a.out 

Output:

Float=3.14159
Double=3.14159
LongDouble=3.14159
Float128=3.1415926535897931159979634685441852

For detail: https://msdn.microsoft.com/en-us/library/cc953fe1.aspx

NAK
  • 341
  • 2
  • 10
  • 5
    It's a presentational problem. Try using [`std::setprecision`](http://en.cppreference.com/w/cpp/io/manip/setprecision) when printing the floating point values. – Some programmer dude Jun 21 '18 at 12:39
  • 1
    Also, to be fully correct you should use the `float` overload of [`acos`](http://en.cppreference.com/w/cpp/numeric/math/acos) for `P0`. As in `float P0 = acos(-1.0f);`. – Some programmer dude Jun 21 '18 at 12:40
  • By setting precision, std::setprecision, still i had the same results for both double and long double. – NAK Jun 21 '18 at 12:45
  • `acos()` in `` (or ``) only accepts a `double` and returns a `double`. If you want versions that work for other floating point types and are using C++11 or later, use `` (or ``). – Peter Jun 21 '18 at 12:51
  • There is a `long double` version of [std::acos](http://en.cppreference.com/w/cpp/numeric/math/acos) in the `` header. Please have in mind that you can't even accurately store the value of `0.1` using floating point types. Strange, right? And the `std::setprecision` doesn't do a thing to _enhance_ the underlying value precision. – Ron Jun 21 '18 at 12:53
  • Ah. I tried both (cgmath and tgmath), getting the same problem..... – NAK Jun 21 '18 at 12:54
  • 3
    `double` and `long double` could be the same type, depending on your platform/compiler. You could check if they are different types for you `static_assert(sizeof(double) != sizeof(long double)); ` – Kaldrr Jun 21 '18 at 12:56
  • 1
    `double` and `long double`, as @Kaldrr said, can be the same size on windows: https://msdn.microsoft.com/en-us/library/9cx8xs15.aspx – José Manuel Ramos Jun 21 '18 at 13:13
  • I am using Ubuntu#16.04. I changed "acos()" to "acosl()" as suggested by @Ramos. I also used printf function: but got the same problem. – NAK Jun 21 '18 at 13:29
  • 1
    What value have you passed to `std::setprecision`? https://wandbox.org/permlink/n8fCNPHYQimYEICm – Bob__ Jun 21 '18 at 13:35
  • Possible duplicate of [What is the role of \*\*std::setprecision()\*\* without \*\*std::fixed\*\* in c++?](https://stackoverflow.com/questions/45084317/what-is-the-role-of-stdsetprecision-without-stdfixed-in-c) – Joseph D. Jun 21 '18 at 14:08

1 Answers1

5

My platform does not have a __float128, but here's an example showing output by precision with float, double, and long double:

#include <cmath> 
#include <iomanip>
#include <iostream>
#include <limits>

int main()
{
  float PI0 = std::acos(-1.0F);
  double PI1 = std::acos(-1.0);
  long double PI2 = std::acos(-1.0L);

  constexpr auto PI0_max_digits10 = std::numeric_limits<decltype(PI0)>::max_digits10;
  constexpr auto PI1_max_digits10 = std::numeric_limits<decltype(PI1)>::max_digits10;
  constexpr auto PI2_max_digits10 = std::numeric_limits<decltype(PI2)>::max_digits10;

  std::cout << "Float=" << std::setprecision(PI0_max_digits10) << PI0 << std::endl;
  std::cout << "Double=" << std::setprecision(PI1_max_digits10) << PI1 << std::endl;
  std::cout << "LongDouble=" << std::setprecision(PI2_max_digits10) << PI2 << std::endl;
}
Eljay
  • 4,648
  • 3
  • 16
  • 27