I'm trying to create long int multiplication function. In math for multiplying 2 numbers for example 123 X 456, I do:
(12 * 10^1 + 3)( 45 * 10^1 + 6) =
(540 * 10^2) + (72 * 10^1) + (135 * 10^1) + 18 = 15129
I created a small program for this algorithm but it didn't work right.
I don't know where my problem is. Can you help me to understand and correct that?
Tnx
int digits(int n) {
int digit = 0;
while (n>0){
n/=10;
digit++;
}
return digit;
}
long int longMult(long int a, long int b) {
long int x,y,w,z;
int digitA = digits(a);
int digitB = digits(b);
if((a==0) || (b==0)) {
return 0;
} else if (digitA < 2 || digitB < 2) {
return a*b;
} else {
int powA = digitA / 2;
int powB = digitB / 2;
//for first number
x = a/(10^powA);
y = a%(10^powA);
//for second number
w = b/(10^powB);
z = b%(10^powB);
return ( longMult(x,w)*(10^(powA*powB)) + longMult(x,z) +
longMult(w,y)*(10^(powA*powB)) + longMult(y,z));
}
}
int main()
{
cout << digits(23) << endl; // for test
cout << longMult(24,24); // must be 576 but output is 96
return 0;
}
The expression
10^powA
does a bitwise exclusive or, and doesn't raise 10 to the power of powA, as you appear to expect.
You may want to define something like
long powli(int b, long e) {return e?b*powli(b,e-1):1;}
Then instead you can use
powli(10,powA)
Edit: There is also a problem with the way the values are combined:
return ( longMult(x,w)*(10^(powA*powB)) + longMult(x,z) +
longMult(w,y)*(10^(powA*powB)) + longMult(y,z));
Look into the maths, because multiplying the exponents makes little sense.
Also the combinations of adjustments to values is wrong, eg (10*a + b)(10*c + d) = 10*10*a*c + 10*a*d + 10*b*d +b*d. So check on your algebra.
Related
this is my first time posting a question. I was hoping to get some help on a very old computer science assignment that I never got around to finishing. I'm no longer taking the class, just want to see how to solve this.
Read in an integer (any valid 64-bit
integer = long long type) and output the same number but with commas inserted.
If the user entered -1234567890, your program should output -1,234,567,890. Commas
should appear after every three significant digits (provided more digits remain) starting
from the decimal point and working left toward more significant digits. If the number
entered does not require commas, do not add any. For example, if the input is 234 you
should output 234. The input 0 should produce output 0. Note in the example above
that the number can be positive or negative. Your output must maintain the case of the
input.
I'm relatively new to programming, and this was all I could come up with:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
long long n;
cout << "Enter an integer:" << endl;
cin >> n;
int ones = n % 10;
int tens = n / 10 % 10;
int hund = n / 100 % 10;
int thous = n / 1000 % 10;
int tthous = n / 10000 % 10;
cout << tthous << thous << "," << hund << tens << ones << endl;
return 0;
}
The original assignment prohibited the use of strings, arrays, and vectors, so please refrain from giving suggestions/solutions that involve these.
I'm aware that some sort of for-loop would probably be required to properly insert the commas in the necessary places, but I just do not know how to go about implementing this.
Thank you in advance to anyone who offers their help!
Just to give you an idea how to solve this, I've maiden a simple implementation. Just keep in mind that is just a simple example:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
long long n = -1234567890;
if ( n < 0 )
cout << '-';
n = abs(n);
for (long long i = 1000000000000; i > 0; i /= 1000) {
if ( n / i <= 0 ) continue;
cout << n / i ;
n = n - ( n / i) * i;
if ( n > 0 )
cout << ',';
}
return 0;
}
http://coliru.stacked-crooked.com/a/150f75db89c46e99
The easy solution would be to use ios::imbue to set a locale that would do all the work for you:
std::cout.imbue(std::locale(""));
std::cout << n << std::endl;
However, if the restraints don't allow for strings or vectors I doubt that this would be a valid solution. Instead you could use recursion:
void print(long long n, int counter) {
if (n > 0) {
print(n / 10, ++counter);
if (counter % 3 == 0) {
std::cout << ",";
}
std::cout << n%10;
}
}
void print(long long n) {
if (n < 0) {
std::cout << "-";
n *= -1;
}
print(n, 0);
}
And then in the main simply call print(n);
A small template class comma_sep may be a solution, the usage may be as simple as:
cout << comma_sep<long long>(7497592752850).sep() << endl;
Which outputs:
7,497,592,752,850
Picked from here:
https://github.com/arloan/libimsux/blob/main/comma_sep.hxx
template <class I = int, int maxdigits = 32>
class comma_sep
char buff[maxdigits + maxdigits / 3 + 2];
char * p;
I i;
char sc;
public:
comma_sep(I i, char c = ',') : p(buff), i(i), sc(c) {
if (i < 0) {
buff[0] = '-';
*++p = '\0';
}
}
const char * sep() {
return _sep(std::abs(i));
}
private:
const char * _sep(I i) {
I r = i % 1000;
I n = i / 1000;
if (n > 0) {
_sep(n);
p += sprintf(p, "%c%03d", sc, (int)r);
*p = '\0';
} else {
p += sprintf(p, "%d", (int)r);
*p = '\0';
}
return buff;
}
};
The above class handles only integeral numbers, float/double numbers need to use a partial specialized version:
template<int maxd>
class comma_sep<double, maxd> {
comma_sep<int64_t, maxd> _cs;
char fs[64];
double f;
public:
const int max_frac = 12;
comma_sep(double d, char c = ',') : _cs((int64_t)d, c) {
double np;
f = std::abs(modf(d, &np));
}
const char * sep(int frac = 3) {
if (frac < 1 || frac > max_frac) {
throw std::invalid_argument("factional part too too long or invalid");
}
auto p = _cs.sep();
strcpy(fs, p);
char fmt[8], tmp[max_frac+3];
sprintf(fmt, "%%.%dlf", frac);
sprintf(tmp, fmt, f);
return strcat(fs, tmp + 1);
}
};
The two above classes can be improved by adding type-traits like std::is_integral and/or std::is_floating_point, though.
I am calculating combination(15, 7) in C++.
I first used the following code and get the wrong answer due to a type promotion error.
#include <iostream>
int main()
{
int a = 15;
double ans = 1;
for(int i = 1; i <= 7; i++)
ans *= (a + 1 - i) / i;
std::cout << (int) ans;
return 0;
}
Output: 2520
So I changed ans *= (a + 1 - i) / i; to ans *= (double)(a + 1 - i) / i; and still get the wrong answer.
#include <iostream>
int main()
{
int a = 15;
double ans = 1;
for(int i = 1; i <= 7; i++)
ans *= (double) (a + 1 - i) / i;
std::cout << (int) ans;
return 0;
}
Output: 6434
Finally, I tried ans = ans * (a + 1 - i) / i, which gives the right answer.
#include <iostream>
int main()
{
int a = 15;
double ans = 1;
for(int i = 1; i <= 7; i++)
ans = ans * (a + 1 - i) / i;
std::cout << (int) ans;
return 0;
}
Output: 6435
Could someone tell me why the second one did not work?
If you print out ans without casting it to (int) you'll see the second result is 6434.9999999999990905052982270717620849609375. That's pretty darn close to the right answer of 6535, so it's clearly not a type promotion error any more.
No, this is classic floating point inaccuracy. When you write ans *= (double) (a + 1 - i) / i you are doing the equivalent of:
ans = ans * ((double) (a + 1 - i) / i);
Compare this to the third version:
ans = ans * (a + 1 - i) / i;
The former performs division first followed by multiplication. The latter operates left to right and so the multiplication precedes the division. This change in order of operations causes the results of the two to be slightly different. Floating point calculations are extremely sensitive to order of operations.
Quick fix: Don't truncate the result; round it.
Better fix: Don't use floating point for integral arithmetic. Save the divisions until after all the multiplications are done. Use long, long long, or even a big number library.
First one did not work because you have integer division there.
Difference btw second one and third one is this:
ans = ans * (double(a + 1 - i) / i); // second is equal to this
vs:
ans = (ans * (a + 1 - i)) / i; // third is equal to this
so difference is in order of multiplication and division. If you round double to integer instead of simply dropping fractional part you will get the same result.
std::cout << int( ans + 0.5 ) << std::endl;
This is my code:
#include<cmath>
#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
int t;long long a, b;long long x; //declartion
cin>>t; //1≤T≤1001≤T≤100
if(t<1||t>100)
exit(0);
for(int i=0;i<t;i++){
long long c=0;
cin>>a>>b;
if(a>b||a<1||a>pow(10,9)||b<1) //1≤A≤B≤109
exit(0);
for(long long y=a;y<=b;y++){
x= floor(sqrt(y));
if(pow(x,2)==y){
c++;
}
}cout<<c<<endl;
}
return 0;`
}
Watson gives two integers (AA and BB) to Sherlock and asks if he can count the number of square integers between AA and BB (both inclusive).
Please tell me why I am getting error time?
[From comments]
Your code appears to run slower than the allowed time line. You can use the following algorithm to speed up.
1. sz = 0, arr[sqrt(1000 * 1000 * 1000) + 5]
2. While sz * sz < (1000 * 1000 * 1000)
2.1 arr[sz] = sz * sz
2.2 sz = sz + 1
3. Read T, repeat for all T
3.1 Read aa and bb
3.2 Use binary search to find upperbound of aa and bb in arr.
3.3 Print the difference of indices
If I boil down to following lines of code in C++:
int ai = isqrt(aa), bi = isqrt(bb);
return bi - ai + 1;
You can find the algorithm for isqrt # Methods_of_computing_square_roots
int isqrt(int num) {
int res = 0;
int bit = 1 << 30;
while (bit > num)
bit >>= 2;
while (bit != 0) {
if (num >= res + bit) {
num -= res + bit;
res = (res >> 1) + bit;
}
else
res >>= 1;
bit >>= 2;
}
return res;
}
I was finding out the algorithm for finding out the square root without using sqrt function and then tried to put into programming. I end up with this working code in C++
#include <iostream>
using namespace std;
double SqrtNumber(double num)
{
double lower_bound=0;
double upper_bound=num;
double temp=0; /* ek edited this line */
int nCount = 50;
while(nCount != 0)
{
temp=(lower_bound+upper_bound)/2;
if(temp*temp==num)
{
return temp;
}
else if(temp*temp > num)
{
upper_bound = temp;
}
else
{
lower_bound = temp;
}
nCount--;
}
return temp;
}
int main()
{
double num;
cout<<"Enter the number\n";
cin>>num;
if(num < 0)
{
cout<<"Error: Negative number!";
return 0;
}
cout<<"Square roots are: +"<<sqrtnum(num) and <<" and -"<<sqrtnum(num);
return 0;
}
Now the problem is initializing the number of iterations nCount in the declaratione ( here it is 50). For example to find out square root of 36 it takes 22 iterations, so no problem whereas finding the square root of 15625 takes more than 50 iterations, So it would return the value of temp after 50 iterations. Please give a solution for this.
There is a better algorithm, which needs at most 6 iterations to converge to maximum precision for double numbers:
#include <math.h>
double sqrt(double x) {
if (x <= 0)
return 0; // if negative number throw an exception?
int exp = 0;
x = frexp(x, &exp); // extract binary exponent from x
if (exp & 1) { // we want exponent to be even
exp--;
x *= 2;
}
double y = (1+x)/2; // first approximation
double z = 0;
while (y != z) { // yes, we CAN compare doubles here!
z = y;
y = (y + x/y) / 2;
}
return ldexp(y, exp/2); // multiply answer by 2^(exp/2)
}
Algorithm starts with 1 as first approximation for square root value.
Then, on each step, it improves next approximation by taking average between current value y and x/y. If y = sqrt(x), it will be the same. If y > sqrt(x), then x/y < sqrt(x) by about the same amount. In other words, it will converge very fast.
UPDATE: To speed up convergence on very large or very small numbers, changed sqrt() function to extract binary exponent and compute square root from number in [1, 4) range. It now needs frexp() from <math.h> to get binary exponent, but it is possible to get this exponent by extracting bits from IEEE-754 number format without using frexp().
Why not try to use the Babylonian method for finding a square root.
Here is my code for it:
double sqrt(double number)
{
double error = 0.00001; //define the precision of your result
double s = number;
while ((s - number / s) > error) //loop until precision satisfied
{
s = (s + number / s) / 2;
}
return s;
}
Good luck!
Remove your nCount altogether (as there are some roots that this algorithm will take many iterations for).
double SqrtNumber(double num)
{
double lower_bound=0;
double upper_bound=num;
double temp=0;
while(fabs(num - (temp * temp)) > SOME_SMALL_VALUE)
{
temp = (lower_bound+upper_bound)/2;
if (temp*temp >= num)
{
upper_bound = temp;
}
else
{
lower_bound = temp;
}
}
return temp;
}
As I found this question is old and have many answers but I have an answer which is simple and working great..
#define EPSILON 0.0000001 // least minimum value for comparison
double SquareRoot(double _val) {
double low = 0;
double high = _val;
double mid = 0;
while (high - low > EPSILON) {
mid = low + (high - low) / 2; // finding mid value
if (mid*mid > _val) {
high = mid;
} else {
low = mid;
}
}
return mid;
}
I hope it will be helpful for future users.
if you need to find square root without using sqrt(),use root=pow(x,0.5).
Where x is value whose square root you need to find.
//long division method.
#include<iostream>
using namespace std;
int main() {
int n, i = 1, divisor, dividend, j = 1, digit;
cin >> n;
while (i * i < n) {
i = i + 1;
}
i = i - 1;
cout << i << '.';
divisor = 2 * i;
dividend = n - (i * i );
while( j <= 5) {
dividend = dividend * 100;
digit = 0;
while ((divisor * 10 + digit) * digit < dividend) {
digit = digit + 1;
}
digit = digit - 1;
cout << digit;
dividend = dividend - ((divisor * 10 + digit) * digit);
divisor = divisor * 10 + 2*digit;
j = j + 1;
}
cout << endl;
return 0;
}
Here is a very simple but unsafe approach to find the square-root of a number.
Unsafe because it only works by natural numbers, where you know that the base respectively the exponent are natural numbers. I had to use it for a task where i was neither allowed to use the #include<cmath> -library, nor i was allowed to use pointers.
potency = base ^ exponent
// FUNCTION: square-root
int sqrt(int x)
{
int quotient = 0;
int i = 0;
bool resultfound = false;
while (resultfound == false) {
if (i*i == x) {
quotient = i;
resultfound = true;
}
i++;
}
return quotient;
}
This a very simple recursive approach.
double mySqrt(double v, double test) {
if (abs(test * test - v) < 0.0001) {
return test;
}
double highOrLow = v / test;
return mySqrt(v, (test + highOrLow) / 2.0);
}
double mySqrt(double v) {
return mySqrt(v, v/2.0);
}
Here is a very awesome code to find sqrt and even faster than original sqrt function.
float InvSqrt (float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x;
i = 0x5f375a86 - (i>>1);
x = *(float*)&i;
x = x*(1.5f - xhalf*x*x);
x = x*(1.5f - xhalf*x*x);
x = x*(1.5f - xhalf*x*x);
x=1/x;
return x;
}
After looking at the previous responses, I hope this will help resolve any ambiguities. In case the similarities in the previous solutions and my solution are illusive, or this method of solving for roots is unclear, I've also made a graph which can be found here.
This is a working root function capable of solving for any nth-root
(default is square root for the sake of this question)
#include <cmath>
// for "pow" function
double sqrt(double A, double root = 2) {
const double e = 2.71828182846;
return pow(e,(pow(10.0,9.0)/root)*(1.0-(pow(A,-pow(10.0,-9.0)))));
}
Explanation:
click here for graph
This works via Taylor series, logarithmic properties, and a bit of algebra.
Take, for example:
log A = N
x
*Note: for square-root, N = 2; for any other root you only need to change the one variable, N.
1) Change the base, convert the base 'x' log function to natural log,
log A => ln(A)/ln(x) = N
x
2) Rearrange to isolate ln(x), and eventually just 'x',
ln(A)/N = ln(x)
3) Set both sides as exponents of 'e',
e^(ln(A)/N) = e^(ln(x)) >~{ e^ln(x) == x }~> e^(ln(A)/N) = x
4) Taylor series represents "ln" as an infinite series,
ln(x) = (k=1)Sigma: (1/k)(-1^(k+1))(k-1)^n
<~~~ expanded ~~~>
[(x-1)] - [(1/2)(x-1)^2] + [(1/3)(x-1)^3] - [(1/4)(x-1)^4] + . . .
*Note: Continue the series for increased accuracy. For brevity, 10^9 is used in my function which expresses the series convergence for the natural log with about 7 digits, or the 10-millionths place, for precision,
ln(x) = 10^9(1-x^(-10^(-9)))
5) Now, just plug in this equation for natural log into the simplified equation obtained in step 3.
e^[((10^9)/N)(1-A^(-10^-9)] = nth-root of (A)
6) This implementation might seem like overkill; however, its purpose is to demonstrate how you can solve for roots without having to guess and check. Also, it would enable you to replace the pow function from the cmath library with your own pow function:
double power(double base, double exponent) {
if (exponent == 0) return 1;
int wholeInt = (int)exponent;
double decimal = exponent - (double)wholeInt;
if (decimal) {
int powerInv = 1/decimal;
if (!wholeInt) return root(base,powerInv);
else return power(root(base,powerInv),wholeInt,true);
}
return power(base, exponent, true);
}
double power(double base, int exponent, bool flag) {
if (exponent < 0) return 1/power(base,-exponent,true);
if (exponent > 0) return base * power(base,exponent-1,true);
else return 1;
}
int root(int A, int root) {
return power(E,(1000000000000/root)*(1-(power(A,-0.000000000001))));
}
I need to use pow in my c++ program and if i call the pow() function this way:
long long test = pow(7, e);
Where
e is an integer value with the value of 23.
I always get 821077879 as a result. If i calculate it with the windows calculator i get 27368747340080916343.. Whats wrong here? ):
I tried to cast to different types but nothing helped here... What could be the reason for this? How i can use pow() correctly?
Thanks!
The result is doesn't fit in long long.
If you want to deal with very big numbers then use a library like GMP
Or store it as a floating point (which won't be as precise).
Applying modulo:
const unsigned int b = 5; // base
const unsigned int e = 27; // exponent
const unsigned int m = 7; // modulo
unsigned int r = 1; // remainder
for (int i = 0; i < e; ++i)
r = (r * b) % m;
// r is now (pow(5,27) % 7)
723 is too big to fit into a long long (assuming it's 64 bits). The value is getting truncated.
Edit: Oh, why didn't you say that you wanted pow(b, e) % m instead of just pow(b, e)? That makes things a whole lot simpler, because you don't need bigints after all. Just do all your arithmetic mod m. Pubby's solution works, but here's a faster one (O(log e) instead of O(e)).
unsigned int powmod(unsigned int b, unsigned int e, unsigned int m)
{
assert(m != 0);
if (e == 0)
{
return 1;
}
else if (e % 2 == 0)
{
unsigned int squareRoot = powmod(b, e / 2, m);
return (squareRoot * squareRoot) % m;
}
else
{
return (powmod(b, e - 1, m) * b) % m;
}
}
See it live: https://ideone.com/YsG7V
#include<iostream>
#include<cmath>
int main()
{
long double ldbl = pow(7, 23);
double dbl = pow(7, 23);
std::cout << ldbl << ", " << dbl << std::endl;
}
Output: 2.73687e+19, 2.73687e+19