Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ “类型”的实现;“长双”;使用GCC和C++;11_C++_Double - Fatal编程技术网

C++ “类型”的实现;“长双”;使用GCC和C++;11

C++ “类型”的实现;“长双”;使用GCC和C++;11,c++,double,C++,Double,我已经尝试过在long double上搜索信息,到目前为止,我知道编译器的实现方式有所不同 在Ubuntu(XUbuntu)Linux 12.10上使用GCC时,我发现: double PId = acos(-1); long double PIl = acos(-1); std::cout.precision(100); std::cout << "PId " << sizeof(double) << " : " << PId <<

我已经尝试过在long double上搜索信息,到目前为止,我知道编译器的实现方式有所不同

在Ubuntu(XUbuntu)Linux 12.10上使用GCC时,我发现:

double PId = acos(-1);
long double PIl = acos(-1);
std::cout.precision(100);

std::cout << "PId " << sizeof(double) << " : " << PId << std::endl;
std::cout << "PIl " << sizeof(long double)  << " : " << PIl << std::endl;
有人知道他们为什么输出(几乎)相同的东西吗?

试试:

long double PIl = std::acos(-1.0L);
这会让你传递一个长的双精度数,而不仅仅是一个整数

请注意,大多数这些数字都是垃圾。 如果将数字与实际PI进行比较,则使用8字节的双精度运算可以获得15个精度数字

3.1415926535897932384626433
你会发现只有前15个数字合适

如注释中所述,您可能无法获得双倍精度,因为实现可能只使用80位表示,然后取决于它为尾数保留了多少位。

根据,只有将
长双精度
传递给它时,它才会返回
长双精度。您还必须像baboon建议的那样使用
std::acos
。这对我很有用:

#include <cmath>
#include <iostream>

int main() {

  double PId = acos((double)-1);
  long double PIl = std::acos(-1.0l);
  std::cout.precision(100);

  std::cout << "PId " << sizeof(double) << " :  " << PId << std::endl;
  std::cout << "PIl " << sizeof(long double)  << " : " << PIl << std::endl;
}

最后一行不是输出的一部分,它包含pi的正确数字,精确到该精度。

要获得正确的有效数字,请使用。在C++11中,我们有十进制有效位(与给出有效位的有效位相反)


acos
只要不将长双精度作为参数传递,就不会返回长双精度。.旁注:g++-4.6.3要求使用
std::acos
而不是
acos
来显示差异(至少在我的ubuntu x86机器上)啊,是的,谢谢,我打印了一些额外的字符。(13)这是预期的吗?我本以为应该打印出两倍长度的东西?@EdwardBird不,这完全取决于实现将为尾数保留多少位。按照@bamboon的建议,使用std::acos。然后1.0l可以正常工作。对于MinGW来说不是这样的:
错误:'acos'不是'std'的成员。
它需要使用
std::numeric\u limits::digits10+1
。例如,
std::numeric_limits::digits10+1==3
@MaximeGroushkin C++11添加了保证往返的
std::numeric_limits::digits10
。在g++中,这被路由到
\uu glibcxx\u max\u digits(\uu FLT\u MANT\u DIG\uuu)
,其中arg是从配置中获取的宏。对于浮点类型,结果是数字10+2。对于整数类型,
max_digits10
设置为0(为什么?)。对于以上代码,我应该编辑为
max\u digits10
。此外,digits10一直都存在,即在C++11之前。我将进一步了解digits10和max_digits10的完整版本。我想知道标准的g++是否犯了错误。我可以说,出于显示目的,
digits10
是正确的。使用
max_digits10
提供的额外数字不准确,但必须确保读取后加载足够的位,以便将十进制重写为
digits10
仍能保持准确性。仍然不确定整数类型是怎么回事。标准很明确:以10为基数的数字的个数可以由类型T表示而不改变,也就是说,任何有这么多十进制数字的数字都可以转换为类型T的值并返回到十进制形式,而不会因四舍五入或溢出而改变。例如,任何3位数字都不能用
uint8\u t
表示,而任何2位数字都可以。
#include <cmath>
#include <iostream>

int main() {

  double PId = acos((double)-1);
  long double PIl = std::acos(-1.0l);
  std::cout.precision(100);

  std::cout << "PId " << sizeof(double) << " :  " << PId << std::endl;
  std::cout << "PIl " << sizeof(long double)  << " : " << PIl << std::endl;
}
PId 8  : 3.141592653589793115997963468544185161590576171875
PIl 12 : 3.14159265358979323851280895940618620443274267017841339111328125

         3.14159265358979323846264338327950288419716939937510582097494459
#include <cmath>
#include <iostream>
#include <limits>

int
main()
{
  std::cout.precision(std::numeric_limits<float>::digits10);
  double PIf = acos(-1.0F);
  std::cout << "PIf " << sizeof(float) << " :  " << PIf << std::endl;

  std::cout.precision(std::numeric_limits<double>::digits10);
  double PId = acos(-1.0);
  std::cout << "PId " << sizeof(double) << " :  " << PId << std::endl;

  std::cout.precision(std::numeric_limits<long double>::digits10);
  long double PIl = std::acos(-1.0L);
  std::cout << "PIl " << sizeof(long double)  << " : " << PIl << std::endl;
}
PIf 4 :  3.14159
PId 8 :  3.14159265358979
PIl 16 : 3.14159265358979324