Issues with the sqrt() function in C++ - c++

So, I was writing code in C++, which required an intermediate step to check whether a number was a perfect square. I wrote the following code.
int sqrt_of_t = (int)sqrt(t);
if (sqrt_of_t*sqrt_of_t != t)
{
cout << "NO" << endl;
}
This code gives the correct results in my system, but it fails when passing it through an online judge in Codeforces. The case where it fails doesn't have any overflow associated with it or anything (really small test cases). So, can anyone explain where it went wrong and suggest some alternate method to check if a number is a perfect square or not, which will work on all systems and not show behaviors like this. Here t is an int too.

sqrt() returns a floating point number which you cast to int, which truncates any fractional part. The problem is that floating point cannot represent all integers exactly, so you may end up with something like 19.99999999999999 which you expect to be 20 but is actually 19 when cast to an integer.
To fix it, use rounding instead:
long sqrt_of_t = lrint(sqrt(t));

sqrt, on many systems returns an approximation.
For example, sqrt(25) might return something like 4.99999999.
Hence, 4.99999999 * 4.99999999 is slightly less than 25.
My advice would be to do a binary search across the number space to see if the number is a perfect square. Avoid floating point whenever you need precise results.
bool isPerfectSquare(long long t)
{
bool result = false;
if ((t == 0) || (t == 1)) {
return true;
}
if (t < 0) {
return false;
}
long long low = 1;
long long high = t / 2;
while (low < high)
{
auto mid = (high + low) / 2;
auto sq = mid * mid;
if (sq == t) {
result = true;
break;
}
if (sq < t) {
low = mid + 1;
}
else {
high = mid - 1;
}
}
return result;
}

Here is Knuth's very interesting algorithm for computing integer square roots with only shift and add. It rounds down for non-square inputs.
uint32_t isqrt1(uint32_t x) {
uint32_t r = 0, r2 = 0;
for (int p = 15; p >= 0; --p) {
uint32_t tr2 = r2 + (r << (p + 1)) + (1u << (p << 1));
if (tr2 <= x) {
r2 = tr2;
r |= (1u << p);
}
}
return r;
}
This works by trying to set each bit to 1, high to low, maintaining the square of the prospective root computed so far. Each bit is "or"ed into the result if doing so produces a square no greater than the input value. It can be modified to detect the case where the prospect is an exact square.
bool is_exact_square(uint32_t x) {
if (x == 0) return true;
uint32_t r = 0, r2 = 0;
for (int p = 15; p >= 0; --p) {
uint32_t tr2 = r2 + (r << (p + 1)) + (1u << (p << 1));
if (tr2 == x) return true;
if (tr2 < x) {
r2 = tr2;
r |= (1u << p);
}
}
return false;
}
I'm adding the for general interest. The binary search suggestion is good. Maybe better unless you're working on a machine without fast multiply.

Related

How can I keep only non-zero digits from an integer?

I am currently using the code below that removes all digits equal to zero from an integer.
int removeZeros(int candid)
{
int output = 0;
string s(itoa(candid));
for (int i = s.size(); i != 0; --i)
{
if (s[i] != '0') output = output * 10 + atoi(s[i]);
}
return output;
}
The expected output for e.g. 102304 would be 1234.
Is there a more compact way of doing this by directly working on the integer, that is, not string representation? Is it actually going to be faster?
Here's a way to do it without strings and buffers.
I've only tested this with positive numbers. To make this work with negative numbers is an exercise left up to you.
int removeZeros(int x)
{
int result = 0;
int multiplier = 1;
while (x > 0)
{
int digit = x % 10;
if (digit != 0)
{
int val = digit * multiplier;
result += val;
multiplier *= 10;
}
x = x / 10;
}
return result;
}
For maintainability, I would suggest, don't work directly on the numeric value. You can express your requirements in a very straightforward way using string manipulations, and while it's true that it will likely perform slower than number manipulations, I expect either to be fast enough that you don't have to worry about the performance unless it's in an extremely tight loop.
int removeZeros(int n) {
auto s = std::to_string(n);
s.erase(std::remove(s.begin(), s.end(), '0'), s.end());
return std::stoi(s);
}
As a bonus, this simpler implementation handles negative numbers correctly. For zero, it throws std::invalid_argument, because removing all zeros from 0 doesn't produce a number.
You could try something like this:
template<typename T> T nozeros( T const & z )
{
return z==0 ? 0 : (z%10?10:1)*nozeros(z/10)+(z%10);
}
If you want to take your processing one step further you can do a nice tail recursion , no need for a helper function:
template<typename T> inline T pow10(T p, T res=1)
{
return p==0 ? res : pow10(--p,res*10);
}
template<typename T> T nozeros( T const & z , T const & r=0, T const & zp =0)
{
static int digit =-1;
return not ( z ^ r ) ? digit=-1, zp : nozeros(z/10,z%10, r ? r*pow10(++digit)+zp : zp);
}
Here is how this will work with input 32040
Ret, z, r, zp, digits
-,32040,0,0, -1
-,3204,0,0, -1
-,320,4,0,0, -1
-,32,0,4,4, 0
-,3,2,4, 0
-,0,3,24, 1
-,0,0,324, 2
324,-,-,-, -1
Integer calculations are always faster than actually transforming your integer to string, making comparisons on strings, and looking up strings to turn them back to integers.
The cool thing is that if you try to pass floats you get nice compile time errors.
I claim this to be slightly faster than other solutions as it makes less conditional evaluations which will make it behave better with CPU branch prediction.
int number = 9042100;
stringstream strm;
strm << number;
string str = strm.str();
str.erase(remove(str.begin(), str.end(), '0'), str.end());
number = atoi(str.c_str());
No string representation is used here. I can't say anything about the speed though.
int removezeroes(int candid)
{
int x, y = 0, n = 0;
// I did this to reverse the number as my next loop
// reverses the number while removing zeroes.
while (candid>0)
{
x = candid%10;
n = n *10 + x;
candid /=10;
}
candid = n;
while (candid>0)
{
x = candid%10;
if (x != 0)
y = y*10 + x;
candid /=10;
}
return y;
}
If C++11 is available, I do like this with lambda function:
int removeZeros(int candid){
std::string s=std::to_string(candid);
std::string output;
std::for_each(s.begin(), s.end(), [&](char& c){ if (c != '0') output += c;});
return std::stoi(output);
}
A fixed implementation of g24l recursive solution:
template<typename T> T nozeros(T const & z)
{
if (z == 0) return 0;
if (z % 10 == 0) return nozeros(z / 10);
else return (z % 10) + ( nozeros(z / 10) * 10);
}

To find combination value of large numbers

I want to find (n choose r) for large integers, and I also have to find out the mod of that number.
long long int choose(int a,int b)
{
if (b > a)
return (-1);
if(b==0 || a==1 || b==a)
return(1);
else
{
long long int r = ((choose(a-1,b))%10000007+(choose(a-1,b- 1))%10000007)%10000007;
return r;
}
}
I am using this piece of code, but I am getting TLE. If there is some other method to do that please tell me.
I don't have the reputation to comment yet, but I wanted to point out that the answer by rock321987 works pretty well:
It is fast and correct up to and including C(62, 31)
but cannot handle all inputs that have an output that fits in a uint64_t. As proof, try:
C(67, 33) = 14,226,520,737,620,288,370 (verify correctness and size)
Unfortunately, the other implementation spits out 8,829,174,638,479,413 which is incorrect. There are other ways to calculate nCr which won't break like this, however the real problem here is that there is no attempt to take advantage of the modulus.
Notice that p = 10000007 is prime, which allows us to leverage the fact that all integers have an inverse mod p, and that inverse is unique. Furthermore, we can find that inverse quite quickly. Another question has an answer on how to do that here, which I've replicated below.
This is handy since:
x/y mod p == x*(y inverse) mod p; and
xy mod p == (x mod p)(y mod p)
Modifying the other code a bit, and generalizing the problem we have the following:
#include <iostream>
#include <assert.h>
// p MUST be prime and less than 2^63
uint64_t inverseModp(uint64_t a, uint64_t p) {
assert(p < (1ull << 63));
assert(a < p);
assert(a != 0);
uint64_t ex = p-2, result = 1;
while (ex > 0) {
if (ex % 2 == 1) {
result = (result*a) % p;
}
a = (a*a) % p;
ex /= 2;
}
return result;
}
// p MUST be prime
uint32_t nCrModp(uint32_t n, uint32_t r, uint32_t p)
{
assert(r <= n);
if (r > n-r) r = n-r;
if (r == 0) return 1;
if(n/p - (n-r)/p > r/p) return 0;
uint64_t result = 1; //intermediary results may overflow 32 bits
for (uint32_t i = n, x = 1; i > r; --i, ++x) {
if( i % p != 0) {
result *= i % p;
result %= p;
}
if( x % p != 0) {
result *= inverseModp(x % p, p);
result %= p;
}
}
return result;
}
int main() {
uint32_t smallPrime = 17;
uint32_t medNum = 3001;
uint32_t halfMedNum = medNum >> 1;
std::cout << nCrModp(medNum, halfMedNum, smallPrime) << std::endl;
uint32_t bigPrime = 4294967291ul; // 2^32-5 is largest prime < 2^32
uint32_t bigNum = 1ul << 24;
uint32_t halfBigNum = bigNum >> 1;
std::cout << nCrModp(bigNum, halfBigNum, bigPrime) << std::endl;
}
Which should produce results for any set of 32-bit inputs if you are willing to wait. To prove a point, I've included the calculation for a 24-bit n, and the maximum 32-bit prime. My modest PC took ~13 seconds to calculate this. Check the answer against wolfram alpha, but beware that it may exceed the 'standard computation time' there.
There is still room for improvement if p is much smaller than (n-r) where r <= n-r. For example, we could precalculate all the inverses mod p instead of doing it on demand several times over.
nCr = n! / (r! * (n-r)!) {! = factorial}
now choose r or n - r in such a way that any of them is minimum
#include <cstdio>
#include <cmath>
#define MOD 10000007
int main()
{
int n, r, i, x = 1;
long long int res = 1;
scanf("%d%d", &n, &r);
int mini = fmin(r, (n - r));//minimum of r,n-r
for (i = n;i > mini;i--) {
res = (res * i) / x;
x++;
}
printf("%lld\n", res % MOD);
return 0;
}
it will work for most cases as required by programming competitions if the value of n and r are not too high
Time complexity :- O(min(r, n - r))
Limitation :- for languages like C/C++ etc. there will be overflow if
n > 60 (approximately)
as no datatype can store the final value..
The expansion of nCr can always be reduced to product of integers. This is done by canceling out terms in denominator. This approach is applied in the function given below.
This function has time complexity of O(n^2 * log(n)). This will calculate nCr % m for n<=10000 under 1 sec.
#include <numeric>
#include <algorithm>
int M=1e7+7;
int ncr(int n, int r)
{
r=min(r,n-r);
int A[r],i,j,B[r];
iota(A,A+r,n-r+1); //initializing A starting from n-r+1 to n
iota(B,B+r,1); //initializing B starting from 1 to r
int g;
for(i=0;i<r;i++)
for(j=0;j<r;j++)
{
if(B[i]==1)
break;
g=__gcd(B[i], A[j] );
A[j]/=g;
B[i]/=g;
}
long long ans=1;
for(i=0;i<r;i++)
ans=(ans*A[i])%M;
return ans;
}

Finding square root without using sqrt function?

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))));
}

What's the best way to get the length of the decimal representation of an int in C++?

What's the best way to write
int NumDigits(int n);
in C++ which would return the number of digits in the decimal representation of the input. For example 11->2, 999->3, -1->2 etc etc.
Straightforward and simple, and independent of sizeof(int):
int NumDigits(int n) {
int digits = 0;
if (n <= 0) {
n = -n;
++digits;
}
while (n) {
n /= 10;
++digits;
}
return digits;
}
//Works for positive integers only
int DecimalLength(int n) {
return floor(log10f(n) + 1);
}
The fastest way is probably a binary search...
//assuming n is positive
if (n < 10000)
if (n < 100)
if (n < 10)
return 1;
else
return 2;
else
if (n < 1000)
return 3;
else
return 4;
else
//etc up to 1000000000
In this case it's about 3 comparisons regardless of input, which I suspect is much faster than a division loop or using doubles.
One way is to (may not be most efficient) convert it to a string and find the length of the string. Like:
int getDigits(int n)
{
std::ostringstream stream;
stream<<n;
return stream.str().length();
}
To extend Arteluis' answer, you could use templates to generate the comparisons:
template<int BASE, int EXP>
struct Power
{
enum {RESULT = BASE * Power<BASE, EXP - 1>::RESULT};
};
template<int BASE>
struct Power<BASE, 0>
{
enum {RESULT = 1};
};
template<int LOW = 0, int HIGH = 8>
struct NumDigits
{
enum {MID = (LOW + HIGH + 1) / 2};
inline static int calculate (int i)
{
if (i < Power<10, MID>::RESULT)
return NumDigits<LOW, MID - 1>::calculate (i);
else
return NumDigits<MID, HIGH>::calculate (i);
}
};
template<int LOW>
struct NumDigits<LOW, LOW>
{
inline static int calculate (int i)
{
return LOW + 1;
}
};
int main (int argc, char* argv[])
{
// Example call.
std::cout << NumDigits<>::calculate (1234567) << std::endl;
return 0;
}
numdigits = snprintf(NULL, 0, "%d", num);
int NumDigits(int n)
{
int digits = 0;
if (n < 0) {
++digits;
do {
++digits;
n /= 10;
} while (n < 0);
}
else {
do {
++digits;
n /= 10;
} while (n > 0);
}
return digits;
}
Edit: Corrected edge case behavior for -2^31 (etc.)
Some very over-complicated solutions have been proposed, including the accepted one.
Consider:
#include <cmath>
#include <cstdlib>
int NumDigits( int num )
{
int digits = (int)log10( (double)abs(num) ) + 1 ;
return num >= 0 ? digits : digits + 1 ;
}
Note that it works for for INT_MIN + 1 ... INT_MAX, because abs(INT_MIN) == INT_MAX + 1 == INT_MIN (due to wrap-around), which in-turn is invalid input to log10(). It is possible to add code for that one case.
Here's a simpler version of Alink's answer .
int NumDigits(int32_t n)
{
if (n < 0) {
if (n == std::numeric_limits<int32_t>::min())
return 11;
return NumDigits(-n) + 1;
}
static int32_t MaxTable[9] = { 10,100,1000,10000,100000,1000000,10000000,100000000,1000000000 };
return 1 + (std::upper_bound(MaxTable, MaxTable+9, n) - MaxTable);
}
Another implementation using STL binary search on a lookup table, which seems not bad (not too long and still faster than division methods). It also seem easy and efficient to adapt for type much bigger than int: will be faster than O(digits) methods and just needs multiplication (no division or log function for this hypothetical type). There is a requirement of a MAXVALUE, though. Unless you fill the table dynamically.
[edit: move the struct into the function]
int NumDigits9(int n) {
struct power10{
vector<int> data;
power10() {
for(int i=10; i < MAX_INT/10; i *= 10) data.push_back(i);
}
};
static const power10 p10;
return 1 + upper_bound(p10.data.begin(), p10.data.end(), n) - p10.data.begin();
}
Since the goal is to be fast, this is a improvement on andrei alexandrescu's improvement. His version was already faster than the naive way (dividing by 10 at every digit). The version below is faster at least on x86-64 and ARM for most sizes.
Benchmarks for this version vs alexandrescu's version on my PR on facebook folly.
inline uint32_t digits10(uint64_t v)
{
std::uint32_t result = 0;
for (;;)
{
result += 1
+ (std::uint32_t)(v>=10)
+ (std::uint32_t)(v>=100)
+ (std::uint32_t)(v>=1000)
+ (std::uint32_t)(v>=10000)
+ (std::uint32_t)(v>=100000);
if (v < 1000000) return result;
v /= 1000000U;
}
}
My version of loop (works with 0, negative and positive values):
int numDigits(int n)
{
int digits = n<0; //count "minus"
do { digits++; } while (n/=10);
return digits;
}
If you're using a version of C++ which include C99 maths functions (C++0x and some earlier compilers)
static const double log10_2 = 3.32192809;
int count_digits ( int n )
{
if ( n == 0 ) return 1;
if ( n < 0 ) return ilogb ( -(double)n ) / log10_2 + 2;
return ilogb ( n ) / log10_2 + 1;
}
Whether ilogb is faster than a loop will depend on the architecture, but it's useful enough for this kind of problem to have been added to the standard.
An optimization of the previous division methods. (BTW they all test if n!=0, but most of the time n>=10 seems enough and spare one division which was more expensive).
I simply use multiplication and it seems to make it much faster (almost 4x here), at least on the 1..100000000 range. I am a bit surprised by such difference, so maybe this triggered some special compiler optimization or I missed something.
The initial change was simple, but unfortunately I needed to take care of a new overflow problem. It makes it less nice, but on my test case, the 10^6 trick more than compensates the cost of the added check. Obviously it depends on input distribution and you can also tweak this 10^6 value.
PS: Of course, this kind of optimization is just for fun :)
int NumDigits(int n) {
int digits = 1;
// reduce n to avoid overflow at the s*=10 step.
// n/=10 was enough but we reuse this to optimize big numbers
if (n >= 1000000) {
n /= 1000000;
digits += 6; // because 1000000 = 10^6
}
int s = 10;
while (s <= n) {
s *= 10;
++digits;
}
return digits;
}

How to check if the binary representation of an integer is a palindrome?

How to check if the binary representation of an integer is a palindrome?
Hopefully correct:
_Bool is_palindrome(unsigned n)
{
unsigned m = 0;
for(unsigned tmp = n; tmp; tmp >>= 1)
m = (m << 1) | (tmp & 1);
return m == n;
}
Since you haven't specified a language in which to do it, here's some C code (not the most efficient implementation, but it should illustrate the point):
/* flip n */
unsigned int flip(unsigned int n)
{
int i, newInt = 0;
for (i=0; i<WORDSIZE; ++i)
{
newInt += (n & 0x0001);
newInt <<= 1;
n >>= 1;
}
return newInt;
}
bool isPalindrome(int n)
{
int flipped = flip(n);
/* shift to remove trailing zeroes */
while (!(flipped & 0x0001))
flipped >>= 1;
return n == flipped;
}
EDIT fixed for your 10001 thing.
Create a 256 lines chart containing a char and it's bit reversed char.
given a 4 byte integer,
take the first char, look it on the chart, compare the answer to the last char of the integer.
if they differ it is not palindrome, if the are the same repeat with the middle chars.
if they differ it is not palindrome else it is.
Plenty of nice solutions here. Let me add one that is not the most efficient, but very readable, in my opinion:
/* Reverses the digits of num assuming the given base. */
uint64_t
reverse_base(uint64_t num, uint8_t base)
{
uint64_t rev = num % base;
for (; num /= base; rev = rev * base + num % base);
return rev;
}
/* Tells whether num is palindrome in the given base. */
bool
is_palindrome_base(uint64_t num, uint8_t base)
{
/* A palindrome is equal to its reverse. */
return num == reverse_base(num, base);
}
/* Tells whether num is a binary palindrome. */
bool
is_palindrome_bin(uint64_t num)
{
/* A binary palindrome is a palindrome in base 2. */
return is_palindrome_base(num, 2);
}
The following should be adaptable to any unsigned type. (Bit operations on signed types tend to be fraught with problems.)
bool test_pal(unsigned n)
{
unsigned t = 0;
for(unsigned bit = 1; bit && bit <= n; bit <<= 1)
t = (t << 1) | !!(n & bit);
return t == n;
}
int palidrome (int num)
{
int rev = 0;
num = number;
while (num != 0)
{
rev = (rev << 1) | (num & 1); num >> 1;
}
if (rev = number) return 1; else return 0;
}
I always have a palindrome function that works with Strings, that returns true if it is, false otherwise, e.g. in Java. The only thing I need to do is something like:
int number = 245;
String test = Integer.toString(number, 2);
if(isPalindrome(test)){
...
}
A generic version:
#include <iostream>
#include <limits>
using namespace std;
template <class T>
bool ispalindrome(T x) {
size_t f = 0, l = (CHAR_BIT * sizeof x) - 1;
// strip leading zeros
while (!(x & (1 << l))) l--;
for (; f != l; ++f, --l) {
bool left = (x & (1 << f)) > 0;
bool right = (x & (1 << l)) > 0;
//cout << left << '\n';
//cout << right << '\n';
if (left != right) break;
}
return f != l;
}
int main() {
cout << ispalindrome(17) << "\n";
}
I think the best approach is to start at the ends and work your way inward, i.e. compare the first bit and the last bit, the second bit and the second to last bit, etc, which will have O(N/2) where N is the size of the int. If at any point your pairs aren't the same, it isn't a palindrome.
bool IsPalindrome(int n) {
bool palindrome = true;
size_t len = sizeof(n) * 8;
for (int i = 0; i < len / 2; i++) {
bool left_bit = !!(n & (1 << len - i - 1));
bool right_bit = !!(n & (1 << i));
if (left_bit != right_bit) {
palindrome = false;
break;
}
}
return palindrome;
}
Sometimes it's good to report a failure too;
There are lots of great answers here about the obvious way to do it, by analyzing in some form or other the bit pattern. I got to wondering, though, if there were any mathematical solutions? Are there properties of palendromic numbers that we might take advantage of?
So I played with the math a little bit, but the answer should really have been obvious from the start. It's trivial to prove that all binary palindromic numbers must be either odd or zero. That's about as far as I was able to get with it.
A little research showed no such approach for decimal palindromes, so it's either a very difficult problem or not solvable via a formal system. It might be interesting to prove the latter...
public static bool IsPalindrome(int n) {
for (int i = 0; i < 16; i++) {
if (((n >> i) & 1) != ((n >> (31 - i)) & 1)) {
return false;
}
}
return true;
}
bool PaLInt (unsigned int i, unsigned int bits)
{
unsigned int t = i;
unsigned int x = 0;
while(i)
{
x = x << bits;
x = x | (i & ((1<<bits) - 1));
i = i >> bits;
}
return x == t;
}
Call PalInt(i,1) for binary pallindromes
Call PalInt(i,3) for Octal Palindromes
Call PalInt(i,4) for Hex Palindromes
I know that this question has been posted 2 years ago, but I have a better solution which doesn't depend on the word size and all,
int temp = 0;
int i = num;
while (1)
{ // let's say num is the number which has to be checked
if (i & 0x1)
{
temp = temp + 1;
}
i = i >> 1;
if (i) {
temp = temp << 1;
}
else
{
break;
}
}
return temp == num;
In JAVA there is an easy way if you understand basic binary airthmetic, here is the code:
public static void main(String []args){
Integer num=73;
String bin=getBinary(num);
String revBin=reverse(bin);
Integer revNum=getInteger(revBin);
System.out.println("Is Palindrome: "+((num^revNum)==0));
}
static String getBinary(int c){
return Integer.toBinaryString(c);
}
static Integer getInteger(String c){
return Integer.parseInt(c,2);
}
static String reverse(String c){
return new StringBuilder(c).reverse().toString();
}
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
unsigned int n = 134217729;
unsigned int bits = floor(log(n)/log(2)+1);
cout<< "Number of bits:" << bits << endl;
unsigned int i=0;
bool isPal = true;
while(i<(bits/2))
{
if(((n & (unsigned int)pow(2,bits-i-1)) && (n & (unsigned int)pow(2,i)))
||
(!(n & (unsigned int)pow(2,bits-i-1)) && !(n & (unsigned int)pow(2,i))))
{
i++;
continue;
}
else
{
cout<<"Not a palindrome" << endl;
isPal = false;
break;
}
}
if(isPal)
cout<<"Number is binary palindrome" << endl;
}
The solution below works in python:
def CheckBinPal(b):
b=str(bin(b))
if b[2:]==b[:1:-1]:
return True
else:
return False
where b is the integer
If you're using Clang, you can make use of some __builtins.
bool binaryPalindrome(const uint32_t n) {
return n == __builtin_bitreverse32(n << __builtin_clz(n));
}
One thing to note is that __builtin_clz(0) is undefined so you'll need to check for zero. If you're compiling on ARM using Clang (next generation mac), then this makes use of the assembly instructions for reverse and clz (compiler explorer).
clz w8, w0
lsl w8, w0, w8
rbit w8, w8
cmp w8, w0
cset w0, eq
ret
x86 has instructions for clz (sort of) but not reversing. Still, Clang will emit the fastest code possible for reversing on the target architecture.
Javascript Solution
function isPalindrome(num) {
const binaryNum = num.toString(2);
console.log(binaryNum)
for(let i=0, j=binaryNum.length-1; i<=j; i++, j--) {
if(binaryNum[i]!==binaryNum[j]) return false;
}
return true;
}
console.log(isPalindrome(0))