Why does pow(n,2) return 24 when n=5, with my compiler and OS?
Here is what may be happening here. You should be able to confirm this by looking at your compiler's implementation of the pow
function:
Assuming you have the correct #include's, (all the previous answers and comments about this are correct -- don't take the #include
files for granted), the prototype for the standard pow
function is this:
double pow(double, double);
and you're calling pow
like this:
pow(5,2);
The pow
function goes through an algorithm (probably using logarithms), thus uses floating point functions and values to compute the power value.
The pow
function does not go through a naive "multiply the value of x a total of n times", since it has to also compute pow
using fractional exponents, and you can't compute fractional powers that way.
So more than likely, the computation of pow
using the parameters 5 and 2 resulted in a slight rounding error. When you assigned to an int
, you truncated the fractional value, thus yielding 24.
If you are using integers, you might as well write your own "intpow" or similar function that simply multiplies the value the requisite number of times. The benefits of this are:
You won't get into the situation where you may get subtle rounding errors using
pow
.Your
intpow
function will more than likely run faster than an equivalent call topow
.
Why is pow(int, int) so slow?
pow()
works with real floating-point numbers and uses under the hood the formula
pow(x,y) = e^(y log(x))
to calculate x^y
. The int
are converted to double
before calling pow
. (log
is the natural logarithm, e-based)
x^2
using pow()
is therefore slower than x*x
.
Edit based on relevant comments
- Using
pow
even with integer exponents may yield incorrect results (PaulMcKenzie) - In addition to using a math function with double type,
pow
is a function call (whilex*x
isn't) (jtbandes) - Many modern compilers will in fact optimize out pow with constant integer arguments, but this should not be relied upon.
why do I get 24 when adding 2 + 4 in javascript
You're concatenating two strings with the + operator. Try either:
function add_things() {
var first = 2;
var second = 4;
alert(first + second);
}
or
function add_things() {
var first = '2';
var second = '4';
alert(parseInt(first, 10) + parseInt(second, 10));
}
or
function add_things() {
var first = '2';
var second = '4';
alert(Number(first) + Number(second));
}
Note: the second is only really appropriate if you're getting strings from say a property or user input. If they're constants you're defining and you want to add them then define them as integers (as in the first example).
Also, as pointed out, octal is evil. parseInt('010')
will actually come out as the number 8 (10 in octal is 8), hence specifying the radix of 10 is a good idea.
C++ pow unusual type conversion
Floating point numbers are approximations. Occasionally you get a number that can be exactly represented, but don't count on it. 100 should be representable, but in this case it isn't. Something injected an approximation and ruined it for everybody.
When converting from a floating point type to an integer, the integer cannot hold any fractional values so they are unceremoniously dropped. There is no implicit rounding off, the fraction is discarded. 99.9 converts to 99. 99 with a million 9s after it is 99.
So before converting from a floating point type to an integer, round the number, then convert. Unless discarding the fraction is what you want to do.
cout
, and most output routines, politely and silently round floating point values before printing, so if there is a bit of an approximation the user isn't bothered with it.
This inexactness is also why you shouldn't directly compare floating point values. X probably isn't exactly pi, but it might be close enough for your computations, so you perform the comparison with an epsilon, a fudge factor, to tell if you are close enough.
What I find amusing, and burned a lot of time trying to sort out, is would not have even seen this problem if not for using namespace std;
.
(long)pow(10,2)
provides the expected result of 100. (long)std::pow(10,2)
does not. Some difference in the path from 10,2 to 100 taken by pow
and std::pow
results in slightly different results. By pulling the entire std
namespace into their file, OP accidentally shot themselves in the foot.
Why is that?
Up at the top of the file we have using namespace std;
this means the compiler is not just considering double pow(double, double)
when looking for pow
overloads, it can also call std::pow
and std::pow
is a nifty little template making sure that when called with datatypes other than float and double the right conversions are taking place and everything is the same type.
(long)(pow(10,2))
Does not match
double pow(double, double)
as well as it matches a template instantiation of
double std::pow(int, int)
Which, near as I can tell resolves down to
return pow(double(10), double(2));
after some template voodoo.
What the difference between
pow(double(10), double(2))
and
pow(10, 2)
with an implied conversion from int
to double
on the call to pow
is, I do not know. Call in the language lawyers because it's something subtle.
If this is purely a rounding issue then
auto tempa = std::pow(10, 2);
should be vulnerable because tempa should be exactly what std::pow
returns
cout << tempa << endl;
cout << (long) tempa << endl;
and the output should be
100
99
I get
100
100
So immediately casting the return of std::pow(10, 2)
into a long
is different from storing and then casting. Weird. auto tempa
is not exactly what std::pow
returns or there is something else going on that is too deep for me.
My C++ program behaves strange with wrong output?
The inbuild pow()
function is not capable of handling so large number.
Rather we have to use custom function to achieve that.
Here it is
#include <iostream>
#include <cmath>
long long binpow(long long a, long long b, long long m) {
a %= m;
long long res = 1;
while (b > 0) {
if (b & 1)
res = res * a % m;
a = a * a % m;
b >>= 1;
}
return res;
}
int main() {
for (int i = 0; i <= 2700000; ++i) {
if (binpow(i, 12, 27) == 1) {
std::cout << i << std::endl;
}
}
std::cout << "Hello, World!" << std::endl;
return 0;
}
You can read more about that function from here:
https://cp-algorithms.com/algebra/binary-exp.html
Is floating point math broken?
Binary floating point math is like this. In most programming languages, it is based on the IEEE 754 standard. The crux of the problem is that numbers are represented in this format as a whole number times a power of two; rational numbers (such as 0.1
, which is 1/10
) whose denominator is not a power of two cannot be exactly represented.
For 0.1
in the standard binary64
format, the representation can be written exactly as
0.1000000000000000055511151231257827021181583404541015625
in decimal, or0x1.999999999999ap-4
in C99 hexfloat notation.
In contrast, the rational number 0.1
, which is 1/10
, can be written exactly as
0.1
in decimal, or0x1.99999999999999...p-4
in an analogue of C99 hexfloat notation, where the...
represents an unending sequence of 9's.
The constants 0.2
and 0.3
in your program will also be approximations to their true values. It happens that the closest double
to 0.2
is larger than the rational number 0.2
but that the closest double
to 0.3
is smaller than the rational number 0.3
. The sum of 0.1
and 0.2
winds up being larger than the rational number 0.3
and hence disagreeing with the constant in your code.
A fairly comprehensive treatment of floating-point arithmetic issues is What Every Computer Scientist Should Know About Floating-Point Arithmetic. For an easier-to-digest explanation, see floating-point-gui.de.
Side Note: All positional (base-N) number systems share this problem with precision
Plain old decimal (base 10) numbers have the same issues, which is why numbers like 1/3 end up as 0.333333333...
You've just stumbled on a number (3/10) that happens to be easy to represent with the decimal system, but doesn't fit the binary system. It goes both ways (to some small degree) as well: 1/16 is an ugly number in decimal (0.0625), but in binary it looks as neat as a 10,000th does in decimal (0.0001)** - if we were in the habit of using a base-2 number system in our daily lives, you'd even look at that number and instinctively understand you could arrive there by halving something, halving it again, and again and again.
** Of course, that's not exactly how floating-point numbers are stored in memory (they use a form of scientific notation). However, it does illustrate the point that binary floating-point precision errors tend to crop up because the "real world" numbers we are usually interested in working with are so often powers of ten - but only because we use a decimal number system day-to-day. This is also why we'll say things like 71% instead of "5 out of every 7" (71% is an approximation, since 5/7 can't be represented exactly with any decimal number).
So no: binary floating point numbers are not broken, they just happen to be as imperfect as every other base-N number system :)
Side Side Note: Working with Floats in Programming
In practice, this problem of precision means you need to use rounding functions to round your floating point numbers off to however many decimal places you're interested in before you display them.
You also need to replace equality tests with comparisons that allow some amount of tolerance, which means:
Do not do if (x == y) { ... }
Instead do if (abs(x - y) < myToleranceValue) { ... }
.
where abs
is the absolute value. myToleranceValue
needs to be chosen for your particular application - and it will have a lot to do with how much "wiggle room" you are prepared to allow, and what the largest number you are going to be comparing may be (due to loss of precision issues). Beware of "epsilon" style constants in your language of choice. These are not to be used as tolerance values.
What is the C++ function to raise a number to a power?
pow() in the cmath library. More info here.
Don't forget to put #include<cmath>
at the top of the file.
Related Topics
Exporting Classes Containing 'Std::' Objects (Vector, Map etc.) from a Dll
How to Print an Unsigned Char as Hex in C++ Using Ostream
Why Doesn't C++ Support Functions Returning Arrays
How to Check If a C++ String Is an Int
Mismatch Detected For 'Runtimelibrary'
Size_T' VS 'Container::Size_Type'
C++ Implicit Copy Constructor For a Class That Contains Other Objects
How to Programmatically Get the Version of a Dll or Exe File
Requesting Administrator Privileges At Run Time
Determine If a Type Is an Stl Container At Compile Time
Are Variable Length Arrays There in C++
Can Standard Container Templates Be Instantiated With Incomplete Types
Conversion of 2D Array to Pointer-To-Pointer
How to Write a Short Literal in C++