C++ pow()函数在C/C++;不同的平台或编译器?

C++ pow()函数在C/C++;不同的平台或编译器?,c++,precision,terminology,pow,C++,Precision,Terminology,Pow,调试内置的pow()函数的输出花了一天时间。我的编译器和联机编译器的输出不同。说来话长。我写了以下文字来再现这种情况 代码: 输出单位: 我认为pow()函数有时会给出错误的输出,但它在所有编译器中的实现都是相同的。因为我认为它有一个既定的标准 我的问题是: C/C++中pow()函数的实现是否因平台或编译器而异 对于pow()函数没有任何既定的标准吗 这个错误叫什么?(比如,未定义的行为) 我想指出的第一件事是,您正在使用res打印结果,并且在循环中多次将结果相加,这意味着在第二次迭代时,您

调试内置的
pow()
函数的输出花了一天时间。我的编译器和联机编译器的输出不同。说来话长。我写了以下文字来再现这种情况

代码: 输出单位: 我认为
pow()
函数有时会给出错误的输出,但它在所有编译器中的实现都是相同的。因为我认为它有一个既定的标准

我的问题是:
  • C/C++中
    pow()
    函数的实现是否因平台或编译器而异

  • 对于
    pow()
    函数没有任何既定的标准吗
  • 这个错误叫什么?(比如,未定义的行为)

    • 我想指出的第一件事是,您正在使用res打印结果,并且在循环中多次将结果相加,这意味着在第二次迭代时,您的结果是错误的


      将res=0移动到for循环中

      我想指出的第一件事是,您正在使用res打印结果,并且在循环中多次将结果相加,这意味着在第二次迭代时,您的结果是错误的


      将res=0移动到for循环中

      影响浮点运算结果的因素很多,如舍入、运算顺序等。即使使用相同的
      pow()
      代码,不同的硬件、不同的编译器甚至不同的编译选项也可能会给出不同的结果,这就是为什么二进制比较没有意义

      有标准的
      std::pow
      和浮点数

      但正如一些问题评论所指出的,标准并没有规定所有内容,编译器/代码有时甚至不遵循标准。大多数情况下,这是精度和速度之间的平衡


      数字错误/浮点精度错误/精度错误-不确定。未定义的行为通常是意外的,而且远远不正确。但是来自不同pow()的所有结果都是正确的

      影响浮点运算结果的因素很多,如舍入、运算顺序等。即使使用相同的
      pow()
      代码,不同的硬件、不同的编译器甚至不同的编译选项也可能会给出不同的结果,这就是为什么二进制比较没有意义

      有标准的
      std::pow
      和浮点数

      但正如一些问题评论所指出的,标准并没有规定所有内容,编译器/代码有时甚至不遵循标准。大多数情况下,这是精度和速度之间的平衡


      数字错误/浮点精度错误/精度错误-不确定。未定义的行为通常是意外的,而且远远不正确。但是来自不同pow()的所有结果都是正确的

      更有趣的是:在同一个编译器上,
      pow
      std::pow
      之间可能存在细微的差异。我一直不知道为什么。顺便说一下,
      #包括使用名称空间std使您面临不必要的风险。请看这里:我注意到您从前面的问题中提取了我的代码(没有属性),并使它变得更糟。(a) );(b) 不要使用命名空间std编写
      (c)不要为此使用
      位集
      。@LightnessRacesinOrbit起初我没有注意到它,因为它在这里几乎不重要。但后来我注意到了这一点,并开始准备如何将你归因于我。我非常抱歉。我没有问你原来的名字。你能告诉我你的名字吗?更有趣的是:在同一个编译器上,
      pow
      std::pow
      之间可能有细微的差别。我一直不知道为什么。顺便说一下,
      #包括使用名称空间std使您面临不必要的风险。请看这里:我注意到您从前面的问题中提取了我的代码(没有属性),并使它变得更糟。(a) );(b) 不要使用命名空间std编写
      (c)不要为此使用
      位集
      。@LightnessRacesinOrbit起初我没有注意到它,因为它在这里几乎不重要。但后来我注意到了这一点,并开始准备如何将你归因于我。我非常抱歉。我没有问你原来的名字。你能告诉我你的名字吗?这只是一个累积的结果。怎么了?没什么。乔尔误解了问题和代码,只是得到了累积的结果。怎么了?没什么。Joel误解了问题和代码。pow()函数没有既定的标准吗?这个错误叫什么?@Eric
      -ffast math
      不会对我的代码进行任何更改。谢谢。这可能不会影响已编译的库。这可能很有趣。pow()函数没有既定的标准吗?这个错误叫什么?@Eric
      -ffast math
      不会对我的代码进行任何更改。谢谢。这可能不会影响已编译的库。这可能很有趣。
      #include <bits/stdc++.h>
      using namespace std;
      
      // This function just prints the binary representation as it is in memory
      // A modified version of Lightness Races in Orbit's code given here: https://stackoverflow.com/a/37861479/3555000
      // I thank Lightness Races in Orbit for the contribution
      void print_binary(long double y)
      {
          const long double x = y;
          unsigned char     a[sizeof(long double)];
      
          copy(
              reinterpret_cast<const unsigned char*>(&x),
              reinterpret_cast<const unsigned char*>(&x) + sizeof(long double),
              &a[0]
          );
          for (auto el : a)
          {
              bitset<8>k(el);
              cout << k.to_string() ;
          }
      
          cout << endl;
      }
      
      int main()
      {
          int a[] = {20,29,31}, res=0; //Took three numbers and initialized the result
          for(int i = 0; i<3; i++)
          {
              cout<<"i = "<<i<< ", a["<<i<< "] = "<<a[i]<<"\npow(" << a[i] <<","<<i+1 << "):\nBinary: ";
              long double temp = pow(a[i],i+1);
              print_binary(temp);
              res+=temp;
              cout<<setprecision(50)<<fixed<< "Decimal: " <<temp <<", Result = "<<res<<endl;
          }
          return 0;
      }
      
      i = 0, a[0] = 20
      pow(20,1):
      Binary: 000000000000000000000000000000000000000000000000000000001010000000000011010000000110100000000000
      Decimal: 20.00000000000000000000000000000000000000000000000000, Result = 20
      i = 1, a[1] = 29
      pow(29,2):
      Binary: 111111011111111111111111111111111111111111111111001111111101001000001000010000000110100000000000
      Decimal: 840.99999999999999983346654630622651893645524978637695, Result = 860
      i = 2, a[2] = 31
      pow(31,3):
      Binary: 111111101111111111111111111111111111111111111111101111011110100000001101010000000110100000000000
      Decimal: 29790.99999999999999644728632119949907064437866210937500, Result = 30650
      
      i = 0, a[0] = 20
      pow(20,1):
      Binary: 000000000000000000000000000000000000000000000000000000001010000000000011010000000000000000000000
      Decimal: 20.00000000000000000000000000000000000000000000000000, Result = 20
      i = 1, a[1] = 29
      pow(29,2):
      Binary: 000000000000000000000000000000000000000000000000010000001101001000001000010000000000000000000000
      Decimal: 841.00000000000000000000000000000000000000000000000000, Result = 861
      i = 2, a[2] = 31
      pow(31,3):
      Binary: 000000000000000000000000000000000000000000000000101111101110100000001101010000000000000000000000
      Decimal: 29791.00000000000000000000000000000000000000000000000000, Result = 30652