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.
Given a 32-bit hex like 0x7f000002, how do I get the full value of this number printed in binary without using bitset or defining any float variables to use union?
I know that it is supposed to display
+10000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0 for this particular 32-bit hex number.
But I don't know how to get there without using those 2 aforementioned function/variable.
You can appeal directly to what the bits in a floating point number mean: https://en.wikipedia.org/wiki/Single-precision_floating-point_format
The last 23 bits store the mantissa, and the eight bits before store the biased exponent (with the one bit before that being the signbit). The number is essentially "1.<mantissa> * 2**(<exponent> + bias)", and multiplying by a power of two is essentially shifting the binary radix point, or adding zeros to the left or right in the binary string.
Taking all that into account (+ edge cases for subnormal numbers and inf and NaN), you can make this function:
std::string floatbits_to_binaryfloatstring(std::uint32_t floatbits) {
bool signbit = floatbits >> 31;
int exponent = (floatbits >> 23) & 0xff;
std::uint32_t fraction = floatbits & 0x7fffffu;
std::string result;
result += signbit ? '-' : '+';
if (exponent == 0xff) {
if (fraction == 0) {
result += "inf";
} else {
result += "NaN";
}
} else if (exponent == 0) {
if (fraction == 0) {
result += "0.0";
} else {
// Subnormal
result += "0.";
result.append(125, '0');
for (int i = 23; i-- > 0;) {
result += (fraction >> i) & 1 ? '1' : '0';
}
// Remove trailing zeroes
result.erase(result.find_last_of('1') + 1u, result.npos);
}
} else {
fraction |= 0x800000u; // Make implicit bit explicit
exponent -= 127 + 23;
// The number is "fraction * 2**(exponent)" in binary
if (exponent <= -24) {
result += "0.";
result.append(-exponent - 24, '0');
for (int i = 24; i-- > 0;) {
result += (fraction >> i) & 1 ? '1' : '0';
}
} else if (exponent >= 0) {
for (int i = 24; i-- > 0;) {
result += (fraction >> i) & 1 ? '1' : '0';
}
result.append(exponent, '0');
result += '.';
} else {
int point = 24 + exponent;
for (int i = 24; i-- > 0;) {
result += (fraction >> i) & 1 ? '1' : '0';
if (--point == 0) result += '.';
}
}
// Remove trailing zeroes
result.erase(result.find_last_not_of('0') + 1u, result.npos);
if (result.back() == '.') result += '0';
}
return result;
}
Example: https://wandbox.org/permlink/9jtWfFJeEmTl6i1i
I haven't tested this thoroughly, there might be some mistake somewhere.
Since this is a weird format in the first place, there probably isn't a prebuilt solution for this. hexfloat is close, but in hex and with binary p notation instead
I am trying to implement a Division Binary Algorithm.
The code has some Logical Errors which I am still trying to figure out how to fix them.
myuint operator/(const myuint<T>& x)
{
myuint<T> temp;
myuint<T> result;
int count = 0;
for(int i = bits.size() - 1 ; i >= 0; --i)
{
temp.bits.push_back(bits[i]);
if(temp >= x)
{
count++;
*this = *this - x;
temp = 0;
}
}
result = count;
return result;
}
I am also overloading the >=, >, and == operators for the division.
The logical problem most probably is in the for loop . What should I do? Thanks
Full code can be accessible from here
== EDIT
What I am trying to achieve is this.
*this is 10100 (20 in decimal)
x is 100 (4 in decimal)
Get the first Bit (1).
Compare it to x
If the bit is greater than the value of x, count++, subtract x from *this. And then Start the loop again which a different *this size.
If the bit is small, then we move to the bit next to it so, now we have 2 bits (10) and we compare it to x.
Then I return the value of count which represents this number of divisions to reach 0.
Not a full answer, but here is the algorithm that you need to implement:
myuint div(const myuint& x, const myuint& y)
{
if (y == 0)
throw "division by zero";
myuint res = 0;
myuint one = 1;
unsigned int xLength = x.bitLength();
unsigned int yLength = y.bitLength();
while (xLength > yLength)
{
res += one << (xLength - yLength - 1);
x -= y << (xLength - yLength - 1);
xLength = x.bitLength();
}
if (x >= y)
return res+1;
return res;
}
So, I found a simple implementation of how to go around Binary Division.
The idea is that you subtract the LSH from the RHS until LHS is smaller RHS and keep a hold for the many times you subtracted RHS from LSH.
myuint operator/(const myuint<T>& x)
{
myuint<T> LHS = *this;
myuint<T> RHS = x;
myuint<T> result;
int count = 0;
bool flag = true;
if(LHS == RHS)
{
return 1;
}
else
{
do
{
if(LHS >= RHS)
{
LHS = LHS - RHS;
count++;
}
else if(LHS < RHS)
{
flag = false;
}
}while(flag);
}
result = count;
return result;
}
This may not be the most efficient way. But it gets the job done.
I'm trying to code a function using C++ and Xcode as compiler that will test if a is palindrome or not. The code works well when the argument is a "C++ born" type (such as int, long, double etc.) but I want to use the function for larger values. So I used an argument of type BigInteger. But the compiler gives an error on the line
BigInteger q = x - floor(x.toLong()/10)*10
saying that Conversion from 'double' to 'const BigInteger' is ambiguous. Here is the whole code :
#include <iostream>
#include "BigInteger.hh"
using namespace std;
bool isPalindrom(BigInteger x){
long ch = ceil(log10(x.toUnsignedLong())), n[ch];
// cout << floor(log10(x)) + 1 << endl;
for (int i = 0; i <= ch; i++){
BigInteger q = x - floor(x.toLong()/10)*10;
n[i] = q.toInt();
// cout << n[i] << endl;
x /= 10;
}
for (long i = 0; i <= ceil(ch); i++){
if (n[i] != n[ch - i]){
return false;
}
}
return true;
}
How can I solve this problem?
There's little point in using BigInteger if you're going to convert to longs all the time.
You can write that thing using only BigInteger operations, in exactly the same way as you would with primitive integers:
bool isPalindrome(BigInteger x){
std::vector<int> digits;
while (x > 0)
{
digits.push_back((x % 10).toInt());
x /= 10;
}
size_t sz = digits.size();
for (size_t i = 0; i < sz; i++){
if (digits[i] != digits[sz - i - 1]){
return false;
}
}
return true;
}
perhaps
BigInteger q (static_cast<long>(x - floor(x.toLong()/10)*10));
might make the compiler happier. Look inside BigInteger.hh for the public constructors. Notice that floor gives a double, hence the substraction gives also a double, and BigInteger has no constructor for that.
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))