Schaki
Schaki

Reputation: 1791

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.

Upvotes: 4

Views: 1115

Answers (2)

SirGuy
SirGuy

Reputation: 10770

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).

Upvotes: 5

user3344003
user3344003

Reputation: 21617

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.

Upvotes: 0

Related Questions