C++ pow() function changes behaviour when put inside a function - c++

I have been programming in C++ for a while now. I have seen previously that power function gives wrong answer for bigger powers due to precision issues but today while solving coding problems I saw that under the same type of parameters, pow() function gave different values when put inside a function vs when evaluated directly.
#include <iostream>
#include <math.h>
using namespace std;
long long n,d;
long long power(long long x)
{
return pow(100,x);
}
long long powersecond(long long x)
{
return pow(100,(int)x);
}
int main()
{
n = 68; d = 2;
cout << n*power(d) <<endl; // outputs 679932
cout << n*pow(100,d) <<endl; // outputs 680000
cout << n*powersecond(d) <<endl; // outputs 679932
cout << n*pow(100,(int)d) <<endl; // outputs 680000
return 0;
}
Notice that the answer doesn't change even after converting x to integer in powersecond() function.The answer is still 679932 even if d is int instead of long long int.
The compiler I used is gnu gcc compiler in VS Code.

The problem is that the output of pow is a floating point double. In your custom function you convert that output to long long, which will truncate if the value returned by pow is slightly low instead of slightly high. See Is floating point math broken?. When you call pow directly the value is kept as a double even after the multiplication, and output rounding gives you a more accurate result.
You expect the value returned by pow(100,2) to be 10000, but instead it might be 9999.99999999999 because of the way floating point works. When converted to integer, that becomes 9999; multiplied by 68, you have 679932.
On the other hand, 9999.99999999999 multiplied by 68 becomes 679999.999999999. That's close enough to 680000 that the output function << will round it for you. You can get a more exact figure if you apply output formatting.

Always write your own power function whenever needed. Change return type according to your requirement to avoid any kind of confusion.
long long int power(long long int a, long long int x) {
static long long int ans = 1;
if (x < 0)
return 1 / power(a, (-1 * x));
if (x == 1)
return a;
if (x == 0 or a == 1)
return 1;
if (x & 1)
ans = a * power((a * a), x / 2);
else
ans = power((a * a), x / 2);
return ans;
}
Here is recursive version .You can also write iterative version.

Related

How to control implicit conversion from long to int?

I am working on this LeetCode problem to take an integer and reverse it, given that the reversed in is within the signed 32-bit range, in which case we should return 0.
and this code is doing just that, even with numbers like 1534236469/-1534236469. Except when it comes to tricky numbers like -2147483648 where its not recognising it as out of range and instead returning 8 and not 0.
I know this is not the cleanest code, but can you help me recognise what I'm missing?
#include<iostream>
#include<limits>
using namespace std;
class Solution {
public:
int reverse(int x) {
int a, r, y;
string num, fnum;
a = abs(x);
try{
while(a != 0){
r = a % 10;
a = a / 10;
num = to_string(r);
fnum = fnum + num;
y = stoi(fnum);
}
} catch(out_of_range& oor){
return 0;
}
if(x==0){
return 0;
} else if (x<0){
return -y;
} else {
return y;
}
}
};
int main(){
Solution mine;
cout << mine.reverse(-2147483648);
}
[...] when it comes to tricky numbers like -2147483648 where its not recognising it as out of range and instead returning 8 and not 0.
That number is "tricky" because it's equal to std::numeric_limits<int>::min() in your environment and given a two's complement representation of type int, it happens that std::abs(-2147483648) == -2147483648.
Next in your (contrived, I must say, there's no need to use a string here) code, the line num = to_string(r); would result in num = "-8", so that the loop would compose a string like "-8-4-6-3-8-4-7-4-1-2".
When applyed to strings like that, stoi doesn't throw an exception, it just stops parsing (you would have noticed it by passing and inspecting its other parameters).
If you want to check if the result is outside the range of an int, you could use locally a wider type (e.g. long long) and check the boundaries after the calculations or keep using int, but compare all the intermediate values with the limits before any calculation.

Problem when i used some large large value i get wrong output with my function

So I'm new to stackoverflow and coding I was learning about functions in c++ and how the stack frame works etc..
in that I made a function for factorials and used that to calculate binomial coefficients. it worked fine for small values like n=10 and r=5 etc... but for large a medium value like 23C12 it gave 4 as answer.
IDK what is wrong with the code or I forgot to add something.
My code:
#include <iostream>
using namespace std;
int fact(int n)
{
int a = 1;
for (int i = 1; i <= n; i++)
{
a *= i;
}
return a;
}
int main()
{
int n, r;
cin >> n >> r;
if (n >= r)
{
int coeff = fact(n) / (fact(n - r) * fact(r));
cout << coeff << endl;
}
else
{
cout << "please enter valid values. i.e n>=r." << endl;
}
return 0;
}
Thanks for your help!
You're not doing anything "wrong" per se. It's just that factorials quicky become huge numbers.
In your example you're using ints, which are typically 32-bit variables. If you take a look at a table of factorials, you'll note that log2(13!) = 32.535.... So the largest factorial that will fit in a 32-bit number is 12!. For a 64-bit variable, the largest factorial you can store is 20! (since log2(21!) = 65.469...).
When you get 4 as the result that's because of overflow.
If you need to be able to calculate such huge numbers, I suggest a bignum library such as GMP.
Factorials overflow easily. In practice you rarely need bare factorials, but they almost always appear in fractions. In your case:
int coeff = fact(n) / (fact(n - r) * fact(r));
Note the the first min(n,n-r,r) factors of the denominator and numerator are identical. I am not going to provide you the code, but I hope an example will help to understand what to do instead.
Consider n=5, r=3 then coeff is
5*4*3*2*1 / 2*1 * 3*2*1
And before actually carrying out any calculations you can reduce that to
5*4 / 2*1
If you are certain that the final result coeff does fit in an int, you can also calculate it using ints. You just need to take care not to overflow the intermediate terms.

Overflow while calculating combinations

I am trying to calculate the combination C(40, 20) in C++, however the data types in C++ seems unable to correctly handle this calculation even though I have used long long data type. The following is my code:
#include <iostream>
long long fac(int x) {
register long long i,f = 1; // Optimize with regFunction
for(i = 1;i <= x;i++)
f *= i;
std::cout << f << std::endl;
return f;
}
// C(n,r) = n!/r!(n-r)!
long long C(long long n, long long r) {
return fac(n) / (fac(r) * fac(n - r));
}
int main(int argc, char const *argv[]) {
std::cout << C(40, 20) << std::endl;
return 0;
}
Any idea to solve this problem?
Compute C at once by executing division immediately after multiplication:
long long C(long long n, long long r)
{
long long f = 1; // Optimize with regFunction
for(auto i = 0; i < r;i++)
f = (f * (n - i)) / (i + 1);
return f ;
}
Result should be exact (divisions without remainders, until overflows) since any integer factor present in (i+1) is already present in (n -i). (Should not be too difficult to prove)
Your numbers are growing too much and that is a common problem in this kind of calculations and I am afraid there is no straightforward solution. Even if you might reduce a bit the number of multiplications you will make probably still you will end up in an overflow with long long
You might want to check those out:
https://mattmccutchen.net/bigint/
https://gmplib.org/
I know there are different algorithmic approaches on this matter. I remember there were some solutions to use strings to store integer representations and stuff but as #Konrad mentioned this might be a poor approach to the matter.
The problem is that factorials get big very quickly. 40! is too large to be stored in a long long. Luckily you don’t actually need to compute this number here since you can reduce the fraction in the calculation of C(n, r) before computing it. This yields the equation (from Wikipedia):
This works much better since k! (r! in your code) is a much smaller number than n!. However, at some point it will also break down.
Alternatively, you can also use the recurrence definition by implementing a recursive algorithm. However, this will be very inefficient (exponential running time) unless you memoise intermediate results.
A lazy way out would be to use a library that supports multiple precision, for example GNU GMP.
Once you have installed it correctly (available from the repositories on most Linux distributions), it comes down to:
adding #include <gmpxx.h> to your source file
replacing long long with mpz_class
compiling with -lgmpxx -lgmp
The source:
#include <iostream>
#include <gmpxx.h>
mpz_class fac(mpz_class x) {
int i;
mpz_class f(1); // Optimize with regFunction
for(i = 1;i <= x;i++)
f *= i;
std::cout << f << std::endl;
return f;
}
// C(n,r) = n!/r!(n-r)!
mpz_class C(mpz_class n, mpz_class r) {
return fac(n) / (fac(r) * fac(n - r));
}
int main(int argc, char const *argv[]) {
std::cout << C(40, 20) << std::endl;
return 0;
}
Compiling and running:
$ g++ comb.cpp -lgmpxx -lgmp -o comb
$ ./comb
2432902008176640000
2432902008176640000
815915283247897734345611269596115894272000000000
137846528820
If you want to be thorough, you can do a lot more, but this will get you answers.
Even if you used uint64 aka ulonglong, the max value is 18446744073709551615 whereas 40! is 815915283247897734345611269596115894272000000000 which is a bit bigger.
I recommend you to use GMP for this kind of maths

conversion from any base to base 10 c++

I found two ways of conversion from any base to base 10 . the first one is the normal one we do in colleges like 521(base-15) ---> (5*15^2)+(2*15^1)+(1*15^0)=1125+30+1 = 1156 (base-10) . my problem is that i applied both methods to a number (1023456789ABCDE(Base-15)) but i am getting different result . google code jam accepts the value generated from second method only for this particular number (i.e 1023456789ABCDE(Base-15)) . for all other cases both generates same results . whats big deal with this special number ?? can anybody suggest ...
#include <iostream>
#include <math.h>
using namespace std;
int main()
{ //number in base 15 is 1023456789ABCDE
int value[15]={1,0,2,3,4,5,6,7,8,9,10,11,12,13,14};
int base =15;
unsigned long long sum=0;
for (int i=0;i<15;i++)
{
sum+=(pow(base,i)*value[14-i]);
}
cout << sum << endl;
//this prints 29480883458974408
sum=0;
for (int i=0;i<15;i++)
{
sum=(sum*base)+value[i];
}
cout << sum << endl;
//this prints 29480883458974409
return 0;
}
Consider using std::stol(ref) to convert a string into a long.
It let you choose the base to use, here an example for your number wiuth base 15.
int main()
{
std::string s = "1023456789ABCDE";
long n = std::stol(s,0,15);
std::cout<< s<<" in base 15: "<<n<<std::endl;
// -> 1023456789ABCDE in base 15: 29480883458974409
}
pow(base, i) uses floating point and so you loose some precision on some numbers.
Exceeded double precision.
Precision of double, the return value from pow(), is precise for at least DBL_DIG significant decimal digits. DBL_DIG is at least 10 and typically is 15 IEEE 754 double-precision binary.
The desired number 29480883458974409 is 17 digits, so some calculation error should be expected.
In particular, sum += pow(base,i)*value[14-i] is done as a long long = long long + (double * long long) which results in long long = double. The nearest double to 29480883458974409 is 29480883458974408. So it is not an imprecise value from pow() that causes the issue here, but an imprecise sum from the addition.
#Mooing Duck in a comment references code to avoid using pow() and its double limitation`. Following is a slight variant.
unsigned long long ullongpow(unsigned value, unsigned exp) {
unsigned long long result = !!value;
while (exp-- > 0) {
result *= value;
}
return result;
}

What is the C++ function to raise a number to a power?

How do I raise a number to a power?
2^1
2^2
2^3
etc...
pow() in the cmath library. More info here.
Don't forget to put #include<cmath> at the top of the file.
std::pow in the <cmath> header has these overloads:
pow(float, float);
pow(float, int);
pow(double, double); // taken over from C
pow(double, int);
pow(long double, long double);
pow(long double, int);
Now you can't just do
pow(2, N)
with N being an int, because it doesn't know which of float, double, or long double version it should take, and you would get an ambiguity error. All three would need a conversion from int to floating point, and all three are equally costly!
Therefore, be sure to have the first argument typed so it matches one of those three perfectly. I usually use double
pow(2.0, N)
Some lawyer crap from me again. I've often fallen in this pitfall myself, so I'm going to warn you about it.
In C++ the "^" operator is a bitwise XOR. It does not work for raising to a power. The x << n is a left shift of the binary number which is the same as multiplying x by 2 n number of times and that can only be used when raising 2 to a power, and not other integers. The POW function is a math function that will work generically.
You should be able to use normal C methods in math.
#include <cmath>
pow(2,3)
if you're on a unix-like system, man cmath
Is that what you're asking?
Sujal
Use the pow(x,y) function: See Here
Just include math.h and you're all set.
While pow( base, exp ) is a great suggestion, be aware that it typically works in floating-point.
This may or may not be what you want: on some systems a simple loop multiplying on an accumulator will be faster for integer types.
And for square specifically, you might as well just multiply the numbers together yourself, floating-point or integer; it's not really a decrease in readability (IMHO) and you avoid the performance overhead of a function call.
I don't have enough reputation to comment, but if you like working with QT, they have their own version.
#include <QtCore/qmath.h>
qPow(x, y); // returns x raised to the y power.
Or if you aren't using QT, cmath has basically the same thing.
#include <cmath>
double x = 5, y = 7; //As an example, 5 ^ 7 = 78125
pow(x, y); //Should return this: 78125
if you want to deal with base_2 only then i recommend using left shift operator << instead of math library.
sample code :
int exp = 16;
for(int base_2 = 1; base_2 < (1 << exp); (base_2 <<= 1)){
std::cout << base_2 << std::endl;
}
sample output :
1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768
It's pow or powf in <math.h>
There is no special infix operator like in Visual Basic or Python
#include <iostream>
#include <conio.h>
using namespace std;
double raiseToPow(double ,int) //raiseToPow variable of type double which takes arguments (double, int)
void main()
{
double x; //initializing the variable x and i
int i;
cout<<"please enter the number";
cin>>x;
cout<<"plese enter the integer power that you want this number raised to";
cin>>i;
cout<<x<<"raise to power"<<i<<"is equal to"<<raiseToPow(x,i);
}
//definition of the function raiseToPower
double raiseToPow(double x, int power)
{
double result;
int i;
result =1.0;
for (i=1, i<=power;i++)
{
result = result*x;
}
return(result);
}
Many answers have suggested pow() or similar alternatives or their own implementations. However, given the examples (2^1, 2^2 and 2^3) in your question, I would guess whether you only need to raise 2 to an integer power. If this is the case, I would suggest you to use 1 << n for 2^n.
pow(2.0,1.0)
pow(2.0,2.0)
pow(2.0,3.0)
Your original question title is misleading. To just square, use 2*2.
First add #include <cmath> then
you can use pow methode in your code for example :
pow(3.5, 3);
Which 3.5 is base and 3 is exp
Note that the use of pow(x,y) is less efficient than x*x*x y times as shown and answered here https://stackoverflow.com/a/2940800/319728.
So if you're going for efficiency use x*x*x.
I am using the library cmath or math.h in order to make use of the pow() library functions that takes care of the powers
#include<iostream>
#include<cmath>
int main()
{
double number,power, result;
cout<<"\nEnter the number to raise to power: ";
cin>>number;
cout<<"\nEnter the power to raise to: ";
cin>>power;
result = pow(number,power);
cout<<"\n"<< number <<"^"<< power<<" = "<< result;
return 0;
}
use pow() function in cmath, tgmath or math.h library.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int a,b;
cin >> a >> b;
cout << pow(a,b) << endl; // this calculates a^b
return 0;
}
do note that if you give input to power as any data type other than long double then the answer will be promoted to that of double. that is it will take input and give output as double. for long double inputs the return type is long double. for changing the answer to int use,
int c=(int)pow(a,b)
But, do keep in mind for some numbers this may result in a number less than the correct answer. so for example you have to calculate 5^2, then the answer can be returned as 24.99999999999 on some compilers. on changing the data type to int the answer will be 24 rather than 25 the correct answer. So, do this
int c=(int)(pow(a,b)+0.5)
Now, your answer will be correct.
also, for very large numbers data is lost in changing data type double to long long int.
for example you write
long long int c=(long long int)(pow(a,b)+0.5);
and give input a=3 and b=38
then the result will come out to be 1350851717672992000 while the correct answer is 1350851717672992089, this happens because pow() function return 1.35085e+18 which gets promoted to int as 1350851717672992000. I suggest writing a custom power function for such scenarios, like:-
long long int __pow (long long int a, long long int b)
{
long long int q=1;
for (long long int i=0;i<=b-1;i++)
{
q=q*a;
}
return q;
}
and then calling it whenever you want like,
int main()
{
long long int a,b;
cin >> a >> b;
long long int c=__pow(a,b);
cout << c << endl;
return 0;
}
For numbers greater than the range of long long int, either use boost library or strings.
int power (int i, int ow) // works only for ow >= 1
{ // but does not require <cmath> library!=)
if (ow > 1)
{
i = i * power (i, ow - 1);
}
return i;
}
cout << power(6,7); //you can enter variables here