简体   繁体   中英

C++11 round off error using pow() and std::complex

Running the following

#include <iostream>
#include <complex>

int main()
{
  std::complex<double> i (0,1);
  std::complex<double> comp =pow(i, 2  );
  std::cout<<comp<<std::endl;
  return 0;
}

gives me the expected result (-1,0) without c++11. However, compiling with c++11 gives the highly annoying (-1,1.22461e-016).

What to do, and what is best practice?

Of course this can be fixed manually by flooring etc., but I would appreciate to know the proper way of addressing the problem.

SYSTEM: Win8.1, using Desktop Qt 5.1.1 (Qt Creator) with MinGW 4.8 32 bit. Using c++11 by adding the flag QMAKE_CXXFLAGS += -std=c++11 in the Qt Creator .pro file.

In C++11 we have a few new overloads of pow(std::complex) . GCC has two nonstandard overloads on top of that, one for raising to an int and one for raising to an unsigned int .

One of the new standard overloads (namely std::complex</*Promoted*/> pow(const std::complex<T> &, const U &) ) causes an ambiguity when calling pow(i, 2) with the non-standard ones. Their solution is to #ifdef the non-standard ones out in the presence of C++11 and you go from calling the specialized function (which uses successive squaring) to the generic method (which uses pow(double,double) and std::polar ).

You need to get into a different mode when you are using floating point numbers. Floating points are APPROXIMATIONS of real numbers.

1.22461e-016 is

0.0000000000000000122461

An engineer would say that IS zero. You will always get such variations (unless you stick to operations on sums of powers of 2 with the same general range.

A value as simple 0.1 cannot be represented exactly with floating point numbers.

The general problem you present has to parts: 1. Dealing with floating point numbers in processing 2. Displaying flooding point numbers.

For the processing, I would wager that doing:

comp = i * i ;

Would give you want you want.

Pow (x, y) is going to do

exp (log (x) * y) 

For output, switch to using an F format.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM