I know how to obtain the square root of a number using the sqrt function.
How can I obtain the cube root of a number?
sqrt stands for "square root", and "square root" means raising to the power of 1/2. There is no such thing as "square root with root 2", or "square root with root 3". For other roots, you change the first word; in your case, you are seeking how to perform cube rooting.
Before C++11, there is no specific function for this, but you can go back to first principles:
Square root: std::pow(n, 1/2.) (or std::sqrt(n))
Cube root: std::pow(n, 1/3.) (or std::cbrt(n) since C++11)
Fourth root: std::pow(n, 1/4.)
etc.
If you're expecting to pass negative values for n, avoid the std::pow solution — it doesn't support negative inputs with fractional exponents, and this is why std::cbrt was added:
std::cout << std::pow(-8, 1/3.) << '\n'; // Output: -nan
std::cout << std::cbrt(-8) << '\n'; // Output: -2
N.B. That . is really important, because otherwise 1/3 uses integer division and results in 0.
in C++11 std::cbrt was introduced as part of math library, you may refer
include <cmath>
std::pow(n, 1./3.)
Also, in C++11 there is cbrt in the same header.
Math for Dummies.
The nth root of x is equal to x^(1/n), so use std::pow. But I don't see what this has to with operator overloading.
Just to point this out, though we can use both ways but
long long res = pow(1e9, 1.0/3);
long long res2 = cbrt(1e9);
cout<<res<<endl;
cout<<res2<<endl;
returns
999
1000
So, in order to get the correct results with pow function we need to add an offset of 0.5 with the actual number or use a double data type i.e.
long long res = pow(1e9+0.5, 1.0/3)
double res = pow(1e9, 1.0/3)
more detailed explanation here C++ pow unusual type conversion
Actually the round must go for the above solutions to work.
The Correct solution would be
ans = round(pow(n, 1./3.));
The solution for this problem is
cube_root = pow(n,(float)1/3);
and you should #include <math.h> library file
Older standards of C/C++ don't support cbrt() function.
When we write code like cube_root = pow(n,1/3); the compiler thinks 1/3 = 0 (division problem in C/C++), so you need to do typecasting using (float)1/3 in order to get the correct answer
#include<iostream.h>
#include<conio.h>
#include<math.h>
using namespace std;
int main(){
float n = 64 , cube_root ;
clrscr();
cube_root = pow(n , (float)1/3);
cout<<"cube root = "<<cube_root<<endl;
getch();
return 0;
}
cube root = 4
You can try this C algorithm :
// return a number that, when multiplied by itself twice, makes N.
unsigned cube_root(unsigned n){
unsigned a = 0, b;
for (int c = sizeof(unsigned) * CHAR_BIT / 3 * 3 ; c >= 0; c -= 3) {
a <<= 1;
b = 3 * a * (a + 1) + 1;
if (n >> c >= b)
n -= b << c, ++a;
}
return a;
}
I would discourage any of the above methods as they didn't work for me. I did pow(64, 1/3.) along with pow(64, 1./3.) but the answer I got was 3
Here's my logic.
ans = pow(n, 1/3.);
if (pow(ans, 3) != n){
ans++;
}
Related
why did we use the temp variable ? what does it mean in the for loop ?
#include <iostream>
using namespace std;
int main()
{
float a, x, sqrt;
double temp;
cout << "type a number: " << endl;
cin >> a;
x = 1.5;
sqrt = 0.5 * (x + (a / x));
cout << sqrt << endl;
for (int i = 0; i < a; i++) {
temp = sqrt;
sqrt = 0.5 * (sqrt + (a / sqrt));
if (temp == sqrt) {
return 0;
}
cout << sqrt << endl;
}
return 0;
}
Temp is normally just a variable name used for something that will be deleted soon or will soon become out of scope.
In this code, it is just used to check if sqrt had changed, if sqrt had not changed it can return 0. So it is temporarily storing what sqrt used to be, so then we can compare what it is now with what it used to be later.
It seems that you are using the temp variable to store the initial value of the "sqrt" variable at the start of each loop iteration, before calculating a new value for "sqrt" and comparing it against its initial value (stored in temp).
Based on your program, it will run loop until the loop condition no longer applies, or until the formula "0.5 * (sqrt + (a / sqrt));" outputs the same as its input, meaning sqrt is no longer changing.
It seems the program tries to find an approximation of the square root of a.
sqrt will become an ever better approximation.
It starts with an estimate of 1.5 and then iteratively uses the formula
sqrt + a/sqrt
next sqrt = -------------
2
When sqrt is larger/smaller than the real square root of a,
a / sqrt is smaller/larger the the real square root.
So taking the average gives a better approximation.
It sets a raw boundary of steps to a itself.
Every approximation is printed.
The old and new sqrt value need to be compared. If they are equal one should stop too. For that temp stores a copy of the (old) sqrt.
When there are no changes to sqrt (it is a/sqrt, close to the real square root) it would continue emitting the same value, when not exiting the program with return 0;.
You see that x, the initial guess of 1.5, is not really need as variable, especially with such no-name moniker. Also the approximation formula applied redundantly on x. Of course you do not want to start every approximation sequence by outputing 1.5, but it could have been written neater.
To some extend this question is about maths, not coding.
The coding part:
The loop stops when sqrt does not change after applying
sqrt = 0.5 * (sqrt + (a / sqrt));
temp stores the value of sqrt before applying that formula and is compared to sqrt after updating it.
The maths part can be investigated with the help of eg Wolfram Alpha. Merely typing the above equation (= -> == and sqrt -> s to not be confused with the square root function) will tell us some information, among it also that sqrt = - sqrt(a) is an integer solution (ie a fixpoint of iteratively applying the update again and again.
TL;DR: The code calculates the square root of a by applying the same update to sqrt until sqrt does not change. To detect if sqrt changes, the value before (temp) and after is compared.
I am trying to write a simple gradient descent algorithm in C++ (for 10,000 iterations). Here is my program:
#include<iostream>
#include<cmath>
using namespace std;
int main(){
double learnrate=10;
double x=10.0; //initial start value
for(int h=1; h<=10000; h++){
x=x-learnrate*(2*x + 100*cos(100*x));
}
cout<<"The minimum is at y = "<<x*x + sin(100*x)<<" and at x = "<<x;
return 0;
}
The output ends up being: y=nan and x=nan. I tried looking at the values of x and y by putting them into a file, and after a certain amount of iterations, I am getting all nans (for x and y). edit: I picked the learning rate (or step size) to be 10 as an experiment, I will use much smaller values afterwards.
There must be something wrong with your formula. Already the first 10 values of x are increasing like hell:
-752.379
15290.7
-290852
5.52555e+06
-1.04984e+08
1.9947e+09
-3.78994e+10
7.20088e+11
-1.36817e+13
2.59952e+14
No matter what starting value you choose the absolute value of the next x will be bigger.
|next_x| = | x - 20 * x - 100 * cos(100*x) |
For example consider what happens when you choose a very small starting value (|x|->0), then
|next_x| = | 0 - 20 * 0 - 100 * cos ( 0 ) | = 100
Because at h=240 the variable "x" exceeds the limits of double type (1.79769e+308). This is a diverging arithmetic progression. You need to reduce your learn rate.
A couple of more things:
1- Do not use "using namespace std;" it is bad practice.
2- You can use "std::isnan() function to identify this situation.
Here is an example:
#include <iomanip>
#include <limits>
int main()
{
double learnrate = 10.0;
double x = 10.0; //initial start value
std::cout<<"double type maximum=" << std::numeric_limits<double>::max()<<std::endl;
bool failed = false;
for (int h = 1; h <= 10000; h++)
{
x = x - learnrate*(2.0*x + 100.0 * std::cos(100.0 * x));
if (std::isnan(x))
{
failed = true;
std::cout << " Nan detected at h=" << h << std::endl;
break;
}
}
if(!failed)
std::cout << "The minimum is at y = " << x*x + std::sin(100.0*x) << " and at x = " << x;
return 0;
}
Print x before the call to the cosine function and you will see that the last number printed before NaN (at h = 240) is:
-1.7761e+307
This means that the value is going to infinity, which cannot be represented (thus Not a Number).
It overflows the double type.
If you use long double, you will succeed in 1000 iterations, but you will still overflow the type with 10000 iterations.
So the problem is that the parameter learnrate is just too big. You should do let steps, while using a data type with larger range, as I suggested above.
The "learn rate" is far too high. Change it to 1e-4, for example, and the program works, for an initial value of 10 at least. When the learnrate is 10, the iterations jump too far past the solution.
At its best, gradient descent is not a good algorithm. For serious applications you want to use something better. Much better. Search for Brent optimizer and BFGS.
Can someone explain me why in c++ happens such a thing:
double tmp;
... // I do some operations with tmp
// after which it has to be equal to one
cout << tmp; // prints 1
cout << trunc(tmp); // prints 0
cout << trunc(tmp*10); // prints 9
I am using this for separation part right of decimal part from the number for example if i have: 5.010 ... i want to have 0.010 .. so I am using:
double remainder = tmp - trunc(tmp);
I am posting the whole code....the suggestion with floor does not worked
short getPrecision(double num, short maxPrecision) {
// Retrieve only part right of decimal point
double tmp = fabs(num - trunc(num));
double remainder = tmp;
// Count number of decimal places
int c = 0;
while (remainder > 0 && c < maxPrecision) {
tmp *= 10;
remainder = tmp - trunc(tmp);
c++;
}
return c;
}
When I run this function for example with 5.1 the remanider is 0 instead of 1
After some calculations it has to be one? Well, it could as well be 0.99999999999999999. Floating point operations are not precise, you should always take that into account.
Please see picture at http://en.cppreference.com/w/cpp/numeric/math/trunc. The chart there explains the inconsistency with truncing 1. Probably the same applies to 10 as well
This should help you achieving what you need:
double remainder = tmp - floor(tmp);
I am in the midst of solving a simple combination problem whose solution is 2^(n-1).
The only problem is 1 <= n <= 2^31 -1 (max value for signed 32 bit integer)
I tried using Java's BigInteger class but It times out for numbers 2^31/10^4 and greater, so that clearly doesn't work out.
Furthermore, I am limited to using only built-in classes for Java or C++.
Knowing I require speed, I chose to build a class in C++ which does arithmetic on strings.
Now, when I do multiplication, my program multiplies similarly to how we multiply on paper for efficiency (as opposed to repeatedly adding the strings).
But even with that in place, I can't multiply 2 by itself 2^31 - 1 times, it is just not efficient enough.
So I started reading texts on the problem and I came to the solution of...
2^n = 2^(n/2) * 2^(n/2) * 2^(n%2) (where / denotes integer division and % denotes modulus)
This means I can solve exponentiation in a logarithmic number of multiplications. But to me, I can't get around how to apply this method to my code? How do I choose a lower bound and what is the most efficient way to keep track of the various numbers that I need for my final multiplication?
If anyone has any knowledge on how to solve this problem, please elaborate (example code is appreciated).
UPDATE
Thanks to everyone for all your help! Clearly this problem is meant to be solved in a realistic way, but I did manage to outperform java.math.BigInteger with a power function that only performs ceil(log2(n)) iterations.
If anyone is interested in the code I've produced, here it is...
using namespace std;
bool m_greater_or_equal (string & a, string & b){ //is a greater than or equal to b?
if (a.length()!=b.length()){
return a.length()>b.length();
}
for (int i = 0;i<a.length();i++){
if (a[i]!=b[i]){
return a[i]>b[i];
}
}
return true;
}
string add (string& a, string& b){
if (!m_greater_or_equal(a,b)) return add(b,a);
string x = string(a.rbegin(),a.rend());
string y = string(b.rbegin(),b.rend());
string result = "";
for (int i = 0;i<x.length()-y.length()+1;i++){
y.push_back('0');
}
int carry = 0;
for (int i =0;i<x.length();i++){
char c = x[i]+y[i]+carry-'0'-'0';
carry = c/10;
c%=10;
result.push_back(c+'0');
}
if (carry==1) result.push_back('1');
return string(result.rbegin(),result.rend());
}
string multiply (string&a, string&b){
string row = b, tmp;
string result = "0";
for (int i = a.length()-1;i>=0;i--){
for (int j= 0;j<(a[i]-'0');j++){
tmp = add(result,row);
result = tmp;
}
row.push_back('0');
}
return result;
}
int counter = 0;
string m_pow (string&a, int exp){
counter++;
if(exp==1){
return a;
}
if (exp==0){
return "1";
}
string p = m_pow(a,exp/2);
string res;
if (exp%2==0){
res = "1"; //a^exp%2 is a^0 = 1
} else {
res = a; //a^exp%2 is a^1 = a
}
string x = multiply(p,p);
return multiply(x,res);
//return multiply(multiply(p,p),res); Doesn't work because multiply(p,p) is not const
}
int main(){
string x ="2";
cout<<m_pow(x,5000)<<endl<<endl;
cout<<counter<<endl;
return 0;
}
As mentioned by #Oli's answer, this is not a question of computing 2^n as that's trivially just a 1 followed by 0s in binary.
But since you want to print them out in decimal, this becomes a question of how to convert from binary to decimal for very large numbers.
My answer to that is that it's not realistic. (I hope this question just stems from curiosity.)
You mention trying to compute 2^(2^31 - 1) and printing that out in decimal. That number is 646,456,993 digits long.
Java BigInteger can't do it. It's meant for small numbers and uses O(n^2) algorithms.
As mentioned in the comments, there are no built-in BigNum libraries in C++.
Even Mathematica can't handle it: General::ovfl : Overflow occurred in computation.
Your best bet is to use the GMP library.
If you're just interested in seeing part of the answer:
2^(2^31 - 1) = 2^2147483647 =
880806525841981676603746574895920 ... 7925005662562914027527972323328
(total: 646,456,993 digits)
This was done using a close-sourced library and took roughly 37 seconds and 3.2 GB of memory on a Core i7 2600K # 4.4 GHz including the time needed to write all 646 million digits to a massive text file.
(It took notepad longer to open the file than needed to compute it.)
Now to answer your question of how to actually compute such a power in the general case, #dasblinkenlight has the answer to that which is a variant of Exponentiation by Squaring.
Converting from binary to decimal for large numbers is a much harder task. The standard algorithm here is Divide-and-Conquer conversion.
I do not recommend you try to implement the latter - as it's far beyond the scope of starting programmers. (and is also somewhat math-intensive)
You don't need to do any multiplication at all. 2^(n-1) is just 1 << (n-1), i.e. 1 followed by (n-1) zeros (in binary).
The easiest way to apply this method in your code is to apply it the most direct way - recursively. It works for any number a, not only for 2, so I wrote code that takes a as a parameter to make it more interesting:
MyBigInt pow(MyBigInt a, int p) {
if (!p) return MyBigInt.One;
MyBigInt halfPower = pow(a, p/2);
MyBigInt res = (p%2 == 0) ? MyBigInt.One : a;
return res * halfPower * halfPower;
}
i have written a c++ code for generating first and last k digits of a number as large as 10^9. (k<=9).
cin>>n>>k;
cout << (unsigned long)floor(pow(10.0, modf(n*log10((double)n), &dummy) + k - 1)) << " "; // code that prints the first k digits
long long int ans = foo(n,k); // function that prints the last k digits
if(ans==0)
{
for(int i=0;i<k;i++) cout << "0";
}
else{
stringstream ss;
string s;
ss<<ans;
ss>>s;
if(s.size()!=k)
{
for(int i=0;i<(k-s.size());i++)
s="0"+s;
}
cout<<s;
}
where function foo() is:
long long int foo(int n, int k) // code of the function
{
long long int m=1;
for(; k > 0; k--) m*=10;
long long int r=1, t=n % m;
while(n)
{
if (n % 2)
r = r * t % m;
t = t * t % m;
n >>= 1;
}
return r;
}
this gives me output as:
if given 9 and 3 as inputs, it gives first and last 3 digits of 9 to the power 9 (9^9) i.e. 387 and 489. But I m still missing out some test cases.
Can anyone please help me finding out the test case for which my code wouldn't work ?
1 ≤ n ≤ 109, 1 ≤ k ≤ 9
the problem statement: http://www.codechef.com/problems/MARCHA4/
If n^n <= 10^9, in which case your code seems to work fine. However, if you allow bigger n, say 11^11, and ask for the last 4 digits of that, which are 0611, your code will only print 611. Basically, it doesn't print any leading zeroes when it should.
This doesn't really answer the question, and its almost trivially easy, but I figure it might be worth sharing. If there were a "long comment" capability I'd be using it.
EDIT: just noticed using str instead of repr will eliminate the L on its own
def firstAndLastDig(k, num):
s = str(num)
return (s[:k], s[-k:])
def firstAndLastDigSelfExp(k,n):
return firstAndLastDig(k,n**n)
Overflow is not an issue (the only thing is dealing with the L if you use repr instead of str),
firstAndLastDigSelfExp(6,12)
('891610', '448256')
firstAndLastDigSelfExp(42,491)
('209417336844579728122309696211520194012462', '160453713040914743773217804810667483135091')
And neither are leading zeroes
>>> firstAndLastDigSelfExp(4,9)
('3874', '0489')
This isn't do say the modular logs and stuff aren't cool - on the contrary I really liked reading about how you did this without generating the entire number. I didn't know about modf at all until reading OP's question and the body of foo is very interesting.
I think the problem is using floating point. Finding the first digit of a number actually requires perfect precision.
Unfortunately, the contest judge evidently doesn't understand that "number of significant digits" != "number of correct digits".
Perhaps there is some clever way to exactly compute (n*n, n = 10*9) without exhausting memory, but finding the first digits of a very good estimate is simply not the same as finding the first digits of the answer.
Assume that k = 9. Now, m = 1e9, and t <= 1e9 - 1.
t * t then may be as high as 1e18 - 2e9 + 1, which needs ... 59.8 bits.
Ok, not a problem with a 64-bit long long int, which has 63 bits of magnitude (and 1 of sign), but I'll leave this here so others don't repeat the same analysis.
Are you told that n is a positive integer? For example, (-8)^(-8) is perfectly well expressible in decimal but your program can't handle it.