runtime error: left shift of negative value -1 - c++

In fact I am trying this question:
5.4 in 《Cracking the coding interview:189 programming questions and solutions,fifth edition》
the question is:
Given a positive integer, print the next smallest and the next largest number that have the same number of 1 bits in their binary representation.
There is an exact same question, but the answers are all wrong.
Moreover, the purpose of my question is to understand why the code cannot pass the ub checker, not just to get ideas for solving the problem.
0
What does "last executed input" mean on leetcode? Is it an example of the input that caused the error, and if so, why are there no warnings from the three compilers, even if I turn on all -Wall?
1
Why is the book wrong?
Here is the code from the book:
class Solution {
public:
int getNext(int n)
{
int c = n;
int c0 = 0;
int c1 = 0;
while (((c & 1) == 0) && (c != 0))
{
c0++;
c >>= 1;
}
while ((c & 1) == 1)
{
c1++;
c >>= 1;
}
if (c0 + c1 == 31 || c0 + c1 == 0) { return -1; }
int p = c0 + c1;
n |= (1 << p);
n &= ~((1 << p) - 1);
n |= (1 << (c1 - 1)) - 1;
return n;
}
int getPrev(int n)
{
int temp = n;
int c0 = 0;
int c1 = 0;
while ((temp & 1) == 1)
{
c1++;
temp >>= 1;
}
if (temp == 0)return -1;
while (((temp & 1) == 0 )&& (temp != 0))
{
c0++;
temp >>= 1;
}
int p = c0 + c1;
n &= ((~0) << (p + 1));
int mask = (1 << (c1 + 1)) - 1;
n |= mask << (c0 - 1);
return n;
}
vector<int> findClosedNumbers(int num) {
int m = getNext(num);
int n = getPrev(num);
return {m,n};
}
};
The error output is
Line 43: Char 14: runtime error: left shift of negative value -1 (solution.cpp)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:53:14
I find this and it said "Left Shifting a negative value is Undefined Behavior"
But why I used all the Wall flags I can think of at https://godbolt.org/, but I didn't get any prompts.
Is there some flag to show this just like the UndefinedBehaviorSanitizer?
2.
Someone's answer can't pass
The link mentioned in this answer cannot pass lc, what's the problem with it?
code:
class Solution {
public:
vector<int> findClosedNumbers(int num) {
int m = getNextLarger(num);
int n = getNextSmaller(num);
return { m,n };
}
int getNextLarger(int num) {
if (num == 0 || num == -1)
return num;
// (1) add 1 to the last set bit
int largeNum = num + (num & ~(num - 1));
// (2) move the changed bits to the least significant bits. (right side)
int flipBits = num & ~largeNum;
int lastBits = 0;
while (flipBits != 0) {
flipBits &= flipBits - 1;
lastBits <<= 1;
lastBits |= 1;
}
lastBits >>= 1;
// (2.1) move bits to maintain the same number of set bits.
largeNum |= lastBits;
return largeNum;
}
//Unhandled exception at 0x0033F4B9 in leetcode.exe: 0xC00000FD: Stack overflow
int getNextSmaller(int num) { //with num=2
return ~getNextLarger(~num);
}
};

why the func can passed in msvc, clang, and gcc ,but just cannot pass the UndefinedBehaviorSanitizer?
Because the compiler didn't know at compile time, what value the operand would be at runtime. If compilers were able to detect all UB at compile time, then UB sanitisers wouldn't exist since they would be unnecessary.

Related

Looking for nbit adder in c++

I was trying to build 17bit adder, when overflow occurs it should round off should appear just like int32.
eg: In int32 add, If a = 2^31 -1
int res = a+1
res= -2^31-1
Code I tried, this is not working & is there a better way. Do I need to convert decimal to binary & then perform 17bit operation
int addOvf(int32_t result, int32_t a, int32_t b)
{
int max = (-(0x01<<16))
int min = ((0x01<<16) -1)
int range_17bit = (0x01<<17);
if (a >= 0 && b >= 0 && (a > max - b)) {
printf("...OVERFLOW.........a=%0d b=%0d",a,b);
}
else if (a < 0 && b < 0 && (a < min - b)) {
printf("...UNDERFLOW.........a=%0d b=%0d",a,b);
}
result = a+b;
if(result<min) {
while(result<min){ result=result + range_17bit; }
}
else if(result>min){
while(result>max){ result=result - range_17bit; }
}
return result;
}
int main()
{
int32_t res,x,y;
x=-65536;
y=-1;
res =addOvf(res,x,y);
printf("Value of x=%0d y=%0d res=%0d",x,y,res);
return 0;
}
You have your constants for max/min int17 reversed and off by one. They should be
max_int17 = (1 << 16) - 1 = 65535
and
min_int17 = -(1 << 16) = -65536.
Then I believe that max_int_n + m == min_int_n + (m-1) and min_int_n - m == max_int_n - (m-1), where n is the bit count and m is some integer in [min_int_n, ... ,max_int_n]. So putting that all together the function to treat two int32's as though they are int17's and add them would be like
int32_t add_as_int17(int32_t a, int32_t b) {
static const int32_t max_int17 = (1 << 16) - 1;
static const int32_t min_int17 = -(1 << 16);
auto sum = a + b;
if (sum < min_int17) {
auto m = min_int17 - sum;
return max_int17 - (m - 1);
} else if (sum > max_int17) {
auto m = sum - max_int17;
return min_int17 + (m - 1);
}
return sum;
}
There is probably some more clever way to do that but I believe the above is correct, assuming I understand what you want.

c++ Decimal to binary, then use operation, then back to decimal

I have an array with x numbers: sets[ ](long numbers) and a char array operations[ ] with x-1 numbers. For each number from sets[ ], its binary form(in 64bits) would be the same as a set of numbers( these numbers being from 0 to 63 ), 1's and 0's representing whether it is inside a subset or not ( 1 2 4 would be 1 1 0 1, since 3 is missing)
ex: decimal 5 --->000...00101 , meaning that this subset will only have those 2 last numbers inside it(#63 and #61)
now,using the chars i get in operations[], i should work with them and the binaries of these numbers as if they were operations on subsets(i hope subset is the right word), these operations being :
U = reunion ---> 101 U 010 = 111
A = intersection ---> 101 A 001 = 001
\ = A - B ---> 1110 - 0011 = 1100
/ = B-A ---> like the previous one
so basically I'd have to read numbers, make them binary, use them as if they were sets and use operations accordingly, then return the result of all these operations on them.
my code :
include <iostream>
using namespace std;
void makeBinaryVector(int vec[64], long xx)
{
// put xx in binary form in array "vec[]"
int k = 63;
long x = xx;
if(xx == 0)
for(int i=0;i<64;i++)
vec[i] = 0;
while(x != 0)
{
vec[k] = x % 2;
x = x / 2;
k--;
}
}
void OperationInA(int A[64], char op, int B[64])
{
int i;
if(op == 'U') //reunion
for(i=0;i<64;i++)
if(B[i] == 1)
A[i] = 1;
if(op == 'A') //intersection
for(i=0;i<64;i++)
{
if((B[i] == 1) && (A[i] == 1))
A[i] = 1;
else
A[i] = 0;
}
if(op == '\\') //A-B
for(i=0;i<64;i++)
{
if( (A[i] == 0 && B[i] == 0) || (A[i] == 0 && B[i] == 1) )
A[i] = 0;
else
if((A[i] == 1) && (B[i] == 1))
A[i] = 0;
else
if((A[i] == 1) && (B[i] == 0))
A[i] = 1;
}
if(op == '/') //B-A
for(i=0;i<64;i++)
{
if(B[i] == 0)
A[i] = 0;
else
if((B[i] == 1) && (A[i] == 0))
A[i] = 1;
else
if((B[i] == 1) && (A[i] == 1))
A[i] = 0;
}
}
unsigned long setOperations(long sets[], char operations[], unsigned int x)
{
unsigned int i = 1; //not 0, since i'll be reading the 1st number separately
unsigned int j = 0;
unsigned int n = x;
int t;
long a = sets[0];
int A[64];
for(t=0;t<64;t++)
A[t] = 0;
makeBinaryVector(A, a); //hold in A the first number, binary, and the results of operations
long b;
int B[64];
for(t=0;t<64;t++) //Hold the next number in B[], in binary form
B[t] = 0;
char op;
while(i < x && j < (x-1) )
{
b = sets[i];
makeBinaryVector(B, b);
op = operations[j];
OperationInA(A, op, B);
i++; j++;
}
//make array A a decimal number
unsigned int base = 1;
long nr = 0;
for(t=63; t>=0; t--)
{
nr = nr + A[t] * base;
base = base * 2;
}
return nr;
}
long sets[100];
char operations[100];
long n,i;
int main()
{
cin>>n;
for(i=0;i<n;i++)
cin>>sets[i];
for(i=0;i<n-1;i++)
cin>>operations[i];
cout<<setOperations(sets,operations,n);
return 0;
}
So everything seems fine, except when im trying this :
sets = {5, 2, 1}
operations = {'U' , '\'}
5 U 2 is 7(111), and 7 \ 1 is 6 (111 - 001 = 110 --> 6)
the result should be 6, however when i Input them like that the result is 4 (??)
however, if i simply input {7,1} and { \ } the result is 6,as it should be. but if i input them like i first mentioned {5,2,1} and {U,} then its gonna output 4.
I can't seem to understand or see what im doing wrong...
You don't have to "convert to binary numbers".
There's no such thing as 'binary numbers'. You can just perform the operations on the variables.
For the reunion, you can use the bitwise OR operator '|', and for the intersection, you can use the bitwise AND operator '&'.
Something like this:
if (op == 'A')
result = a & b;
else if (op == 'U')
result = a | b;
else if (op == '\\')
result = a - b;
else if (op == '/')
result = b - a;
Use bitwise operators on integers as shown in #Hugal31's answer.
Note that integer size is usually 32bit, not 64bit. On a 64bit system you need long long for 64bit integer. Use sizeof operator to check. int is 4 bytes (32bit) and long long is 8 bytes (64bit).
For the purpose of homework etc., your conversion to vector cannot be right. You should test it to see if it outputs the correct result. Otherwise use this:
void makebinary(int vec[32], int x)
{
int bitmask = 1;
for (int i = 31; i >= 0; i--)
{
vec[i] = (x & bitmask) ? 1 : 0;
bitmask <<= 1;
}
}
Note the use of shift operators. To AND the numbers you can do something like the following:
int vx[32];
int vy[32];
makebinary(vx, x);
makebinary(vy, y);
int result = 0;
int j = 1;
for (int i = 31; i >= 0; i--)
{
int n = (vx[i] & vy[i]) ? 1 : 0;
result += n * j;
j <<= 1;
}
This is of course pointless because you can just say int result = X & Y;

How to take input 128 bit unsigned integer in c++

I am new to c++. I want to take input a unsigned 128 bit integer using scanf and print it using printf. As I am new to c++ , I only know these two methods for input output. Can someone help me out?
You could use boost, but this library set must be installed yourself:
#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
int main()
{
using namespace boost::multiprecision;
uint128_t v = 0;
std::cin >> v; // read
std::cout << v << std::endl; // write
return 0;
}
If you want to get along without boost, you can store the value into two uint64_t as such:
std::string input;
std::cin >> input;
uint64_t high = 0, low = 0, tmp;
for(char c : input)
{
high *= 10;
tmp = low * 10;
if(tmp / 10 != low)
{
high += ((low >> 32) * 10 + ((low & 0xf) * 10 >> 32)) >> 32;
}
low = tmp;
tmp = low + c - '0';
high += tmp < low;
low = tmp;
}
Printing then, however, gets more ugly:
std::vector<uint64_t> v;
while(high | low)
{
uint64_t const pow10 = 100000000;
uint64_t const mod = (((uint64_t)1 << 32) % pow10) * (((uint64_t)1 << 32) % pow10) % pow10;
tmp = high % pow10;
uint64_t temp = tmp * mod % pow10 + low % pow10;
v.push_back((tmp * mod + low) % pow10);
low = low / pow10 + tmp * 184467440737 + tmp * /*0*/9551616 / pow10 + (temp >= pow10);
high /= pow10;
}
std::vector<uint64_t>::reverse_iterator i = v.rbegin();
while(i != v.rend() && *i == 0)
{
++i;
}
if(i == v.rend())
{
std::cout << 0;
}
else
{
std::cout << *i << std::setfill('0');
for(++i; i != v.rend(); ++i)
{
std::cout << std::setw(8) << *i;
}
}
Above solution works up to (including)
340282366920938463463374516198409551615
= 0x ffff ffff ffff ffff ffff ad06 1410 beff
Above, there is an error.
Note: pow10 can be varied, then some other constants need to be adjusted, e. g. pow10 = 10:
low = low / pow10 + tmp * 1844674407370955161 + tmp * 6 / pow10 + (temp >= pow10);
and
std::cout << std::setw(1) << *i; // setw also can be dropped in this case
Increasing results in reducing the maximum number for which printing still works correctly, decreasing raises the maximum. With pow10 = 10, maximum is
340282366920938463463374607431768211425
= ffff ffff ffff ffff ffff ffff ffff ffe1
I don't know where the error for the very highest numbers comes from, yet, possibly some unconsidered overflow. Any suggestions appreciated, then I'll improve the algorithm. Until then, I'd reduce pow10 to 10 and introduce a special handling for the highest 30 failing numbers:
std::string const specialValues[0] = { /*...*/ };
if(high == 0xffffffffffffffff && low > 0xffffffffffffffe1)
{
std::cout << specialValues[low - 0xffffffffffffffe2];
}
else
{
/* ... */
}
So at least, we can handle all valid 128-bit values correctly.
You can try from_string_128_bits and to_string_128_bits with 128 bits unsigned integers in C :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
__uint128_t from_string_128_bits(const char *str) {
__uint128_t res = 0;
for (; *str; res = res * 10 + *str++ - '0');
return res;
}
static char *to_string_128_bits(__uint128_t num) {
__uint128_t mask = -1;
size_t a, b, c = 1, d;
char *s = malloc(2);
strcpy(s, "0");
for (mask -= mask / 2; mask; mask >>= 1) {
for (a = (num & mask) != 0, b = c; b;) {
d = ((s[--b] - '0') << 1) + a;
s[b] = "0123456789"[d % 10];
a = d / 10;
}
for (; a; s = realloc(s, ++c + 1), memmove(s + 1, s, c), *s = "0123456789"[a % 10], a /= 10);
}
return s;
}
int main(void) {
__uint128_t n = from_string_128_bits("10000000000000000000000000000000000001");
n *= 7;
char *s = to_string_128_bits(n);
puts(s);
free(s); // string must be freed
// print 70000000000000000000000000000000000007
}

Miller-Rabin Primality test FIPS 186-3 implementation

Im trying to implement the Miller-Rabin primality test according to the description in FIPS 186-3 C.3.1. No matter what I do, I cannot get it to work. The instructions are pretty specific, and I dont think I missed anything, and yet Im getting true for non-prime values.
What did I do wrong?
template <typename R, typename S, typename T>
T POW(R base, S exponent, const T mod){
T result = 1;
while (exponent){
if (exponent & 1)
result = (result * base) % mod;
exponent >>= 1;
base = (base * base) % mod;
}
return result;
}
// used uint64_t to prevent overflow, but only testing with small numbers for now
bool MillerRabin_FIPS186(uint64_t w, unsigned int iterations = 50){
srand(time(0));
unsigned int a = 0;
uint64_t W = w - 1; // dont want to keep calculating w - 1
uint64_t m = W;
while (!(m & 1)){
m >>= 1;
a++;
}
// skipped getting wlen
// when i had this function using my custom arbitrary precision integer class,
// and could get len(w), getting it and using it in an actual RBG
// made no difference
for(unsigned int i = 0; i < iterations; i++){
uint64_t b = (rand() % (W - 3)) + 2; // 2 <= b <= w - 2
uint64_t z = POW(b, m, w);
if ((z == 1) || (z == W))
continue;
else
for(unsigned int j = 1; j < a; j++){
z = POW(z, 2, w);
if (z == W)
continue;
if (z == 1)
return 0;// Composite
}
}
return 1;// Probably Prime
}
this:
std::cout << MillerRabin_FIPS186(33) << std::endl;
std::cout << MillerRabin_FIPS186(35) << std::endl;
std::cout << MillerRabin_FIPS186(37) << std::endl;
std::cout << MillerRabin_FIPS186(39) << std::endl;
std::cout << MillerRabin_FIPS186(45) << std::endl;
std::cout << MillerRabin_FIPS186(49) << std::endl;
is giving me:
0
1
1
1
0
1
The only difference between your implementation and Wikipedia's is that you forgot the second return composite statement. You should have a return 0 at the end of the loop.
Edit: As pointed out by Daniel, there is a second difference. The continue is continuing the inner loop, rather than the outer loop like it's supposed to.
for(unsigned int i = 0; i < iterations; i++){
uint64_t b = (rand() % (W - 3)) + 2; // 2 <= b <= w - 2
uint64_t z = POW(b, m, w);
if ((z == 1) || (z == W))
continue;
else{
int continueOuter = 0;
for(unsigned int j = 1; j < a; j++){
z = POW(z, 2, w);
if (z == W)
continueOuter = 1;
break;
if (z == 1)
return 0;// Composite
}
if (continueOuter) {continue;}
}
return 0; //This is the line you're missing.
}
return 1;// Probably Prime
Also, if the input is even, it will always return probably prime since a is 0. You should add an extra check at the start for that.
In the inner loop,
for(unsigned int j = 1; j < a; j++){
z = POW(z, 2, w);
if (z == W)
continue;
if (z == 1)
return 0;// Composite
}
you should break; instead of continue; when z == W. By continueing, in the next iteration of that loop, if there is one, z will become 1 and the candidate is possibly wrongly declared composite. Here, that happens for 17, 41, 73, 89 and 97 among the primes less than 100.

Implement division with bit-wise operator

How can I implement division using bit-wise operators (not just division by powers of 2)?
Describe it in detail.
The standard way to do division is by implementing binary long-division. This involves subtraction, so as long as you don't discount this as not a bit-wise operation, then this is what you should do. (Note that you can of course implement subtraction, very tediously, using bitwise logical operations.)
In essence, if you're doing Q = N/D:
Align the most-significant ones of N and D.
Compute t = (N - D);.
If (t >= 0), then set the least significant bit of Q to 1, and set N = t.
Left-shift N by 1.
Left-shift Q by 1.
Go to step 2.
Loop for as many output bits (including fractional) as you require, then apply a final shift to undo what you did in Step 1.
Division of two numbers using bitwise operators.
#include <stdio.h>
int remainder, divisor;
int division(int tempdividend, int tempdivisor) {
int quotient = 1;
if (tempdivisor == tempdividend) {
remainder = 0;
return 1;
} else if (tempdividend < tempdivisor) {
remainder = tempdividend;
return 0;
}
do{
tempdivisor = tempdivisor << 1;
quotient = quotient << 1;
} while (tempdivisor <= tempdividend);
/* Call division recursively */
quotient = quotient + division(tempdividend - tempdivisor, divisor);
return quotient;
}
int main() {
int dividend;
printf ("\nEnter the Dividend: ");
scanf("%d", &dividend);
printf("\nEnter the Divisor: ");
scanf("%d", &divisor);
printf("\n%d / %d: quotient = %d", dividend, divisor, division(dividend, divisor));
printf("\n%d / %d: remainder = %d", dividend, divisor, remainder);
getch();
}
int remainder =0;
int division(int dividend, int divisor)
{
int quotient = 1;
int neg = 1;
if ((dividend>0 &&divisor<0)||(dividend<0 && divisor>0))
neg = -1;
// Convert to positive
unsigned int tempdividend = (dividend < 0) ? -dividend : dividend;
unsigned int tempdivisor = (divisor < 0) ? -divisor : divisor;
if (tempdivisor == tempdividend) {
remainder = 0;
return 1*neg;
}
else if (tempdividend < tempdivisor) {
if (dividend < 0)
remainder = tempdividend*neg;
else
remainder = tempdividend;
return 0;
}
while (tempdivisor<<1 <= tempdividend)
{
tempdivisor = tempdivisor << 1;
quotient = quotient << 1;
}
// Call division recursively
if(dividend < 0)
quotient = quotient*neg + division(-(tempdividend-tempdivisor), divisor);
else
quotient = quotient*neg + division(tempdividend-tempdivisor, divisor);
return quotient;
}
void main()
{
int dividend,divisor;
char ch = 's';
while(ch != 'x')
{
printf ("\nEnter the Dividend: ");
scanf("%d", &dividend);
printf("\nEnter the Divisor: ");
scanf("%d", &divisor);
printf("\n%d / %d: quotient = %d", dividend, divisor, division(dividend, divisor));
printf("\n%d / %d: remainder = %d", dividend, divisor, remainder);
_getch();
}
}
I assume we are discussing division of integers.
Consider that I got two number 1502 and 30, and I wanted to calculate 1502/30. This is how we do this:
First we align 30 with 1501 at its most significant figure; 30 becomes 3000. And compare 1501 with 3000, 1501 contains 0 of 3000. Then we compare 1501 with 300, it contains 5 of 300, then compare (1501-5*300) with 30. At so at last we got 5*(10^1) = 50 as the result of this division.
Now convert both 1501 and 30 into binary digits. Then instead of multiplying 30 with (10^x) to align it with 1501, we multiplying (30) in 2 base with 2^n to align. And 2^n can be converted into left shift n positions.
Here is the code:
int divide(int a, int b){
if (b != 0)
return;
//To check if a or b are negative.
bool neg = false;
if ((a>0 && b<0)||(a<0 && b>0))
neg = true;
//Convert to positive
unsigned int new_a = (a < 0) ? -a : a;
unsigned int new_b = (b < 0) ? -b : b;
//Check the largest n such that b >= 2^n, and assign the n to n_pwr
int n_pwr = 0;
for (int i = 0; i < 32; i++)
{
if (((1 << i) & new_b) != 0)
n_pwr = i;
}
//So that 'a' could only contain 2^(31-n_pwr) many b's,
//start from here to try the result
unsigned int res = 0;
for (int i = 31 - n_pwr; i >= 0; i--){
if ((new_b << i) <= new_a){
res += (1 << i);
new_a -= (new_b << i);
}
}
return neg ? -res : res;
}
Didn't test it, but you get the idea.
This solution works perfectly.
#include <stdio.h>
int division(int dividend, int divisor, int origdiv, int * remainder)
{
int quotient = 1;
if (dividend == divisor)
{
*remainder = 0;
return 1;
}
else if (dividend < divisor)
{
*remainder = dividend;
return 0;
}
while (divisor <= dividend)
{
divisor = divisor << 1;
quotient = quotient << 1;
}
if (dividend < divisor)
{
divisor >>= 1;
quotient >>= 1;
}
quotient = quotient + division(dividend - divisor, origdiv, origdiv, remainder);
return quotient;
}
int main()
{
int n = 377;
int d = 7;
int rem = 0;
printf("Quotient : %d\n", division(n, d, d, &rem));
printf("Remainder: %d\n", rem);
return 0;
}
Implement division without divison operator:
You will need to include subtraction. But then it is just like you do it by hand (only in the basis of 2). The appended code provides a short function that does exactly this.
uint32_t udiv32(uint32_t n, uint32_t d) {
// n is dividend, d is divisor
// store the result in q: q = n / d
uint32_t q = 0;
// as long as the divisor fits into the remainder there is something to do
while (n >= d) {
uint32_t i = 0, d_t = d;
// determine to which power of two the divisor still fits the dividend
//
// i.e.: we intend to subtract the divisor multiplied by powers of two
// which in turn gives us a one in the binary representation
// of the result
while (n >= (d_t << 1) && ++i)
d_t <<= 1;
// set the corresponding bit in the result
q |= 1 << i;
// subtract the multiple of the divisor to be left with the remainder
n -= d_t;
// repeat until the divisor does not fit into the remainder anymore
}
return q;
}
The below method is the implementation of binary divide considering both numbers are positive. If subtraction is a concern we can implement that as well using binary operators.
Code
-(int)binaryDivide:(int)numerator with:(int)denominator
{
if (numerator == 0 || denominator == 1) {
return numerator;
}
if (denominator == 0) {
#ifdef DEBUG
NSAssert(denominator == 0, #"denominator should be greater then 0");
#endif
return INFINITY;
}
// if (numerator <0) {
// numerator = abs(numerator);
// }
int maxBitDenom = [self getMaxBit:denominator];
int maxBitNumerator = [self getMaxBit:numerator];
int msbNumber = [self getMSB:maxBitDenom ofNumber:numerator];
int qoutient = 0;
int subResult = 0;
int remainingBits = maxBitNumerator-maxBitDenom;
if (msbNumber >= denominator) {
qoutient |=1;
subResult = msbNumber - denominator;
}
else {
subResult = msbNumber;
}
while (remainingBits>0) {
int msbBit = (numerator & (1 << (remainingBits-1)))>0 ? 1 : 0;
subResult = (subResult << 1) |msbBit;
if (subResult >= denominator) {
subResult = subResult-denominator;
qoutient = (qoutient << 1) | 1;
}
else {
qoutient = qoutient << 1;
}
remainingBits--;
}
return qoutient;
}
-(int)getMaxBit:(int)inputNumber
{
int maxBit =0;
BOOL isMaxBitSet = NO;
for (int i=0; i<sizeof(inputNumber)*8; i++) {
if (inputNumber & (1 << i) ) {
maxBit = i;
isMaxBitSet=YES;
}
}
if (isMaxBitSet) {
maxBit += 1;
}
return maxBit;
}
-(int)getMSB:(int)bits ofNumber:(int)number
{
int numbeMaxBit = [self getMaxBit:number];
return number >> (numbeMaxBit -bits);
}
For integers:
public class Division {
public static void main(String[] args) {
System.out.println("Division: " + divide(100, 9));
}
public static int divide(int num, int divisor) {
int sign = 1;
if((num > 0 && divisor < 0) || (num < 0 && divisor > 0))
sign = -1;
return divide(Math.abs(num), Math.abs(divisor), Math.abs(divisor)) * sign;
}
public static int divide(int num, int divisor, int sum) {
if (sum > num) {
return 0;
}
return 1 + divide(num, divisor, sum + divisor);
}
}
With the usual caveats about C's behaviour with shifts, this ought to work for unsigned quantities regardless of the native size of an int...
static unsigned int udiv(unsigned int a, unsigned int b) {
unsigned int c = 1, result = 0;
if (b == 0) return (unsigned int)-1 /*infinity*/;
while (((int)b > 0) && (b < a)) { b = b<<1; c = c<<1; }
do {
if (a >= b) { a -= b; result += c; }
b = b>>1; c = c>>1;
} while (c);
return result;
}
This is my solution to implement division with only bitwise operations:
int align(int a, int b) {
while (b < a) b <<= 1;
return b;
}
int divide(int a, int b) {
int temp = b;
int result = 0;
b = align(a, b);
do {
result <<= 1;
if (a >= b) {
// sub(a,b) is a self-defined bitwise function for a minus b
a = sub(a,b);
result = result | 1;
}
b >>= 1;
} while (b >= temp);
return result;
}
Unsigned Long Division (JavaScript) - based on Wikipedia article: https://en.wikipedia.org/wiki/Division_algorithm:
"Long division is the standard algorithm used for pen-and-paper division of multi-digit numbers expressed in decimal notation. It shifts gradually from the left to the right end of the dividend, subtracting the largest possible multiple of the divisor (at the digit level) at each stage; the multiples then become the digits of the quotient, and the final difference is then the remainder.
When used with a binary radix, this method forms the basis for the (unsigned) integer division with remainder algorithm below."
Function divideWithoutDivision at the end wraps it to allow negative operands. I used it to solve leetcode problem "Product of Array Except Self"
function longDivision(N, D) {
let Q = 0; //quotient and remainder
let R = 0;
let n = mostSignificantBitIn(N);
for (let i = n; i >= 0; i--) {
R = R << 1;
R = setBit(R, 0, getBit(N, i));
if (R >= D) {
R = R - D;
Q = setBit(Q, i, 1);
}
}
//return [Q, R];
return Q;
}
function mostSignificantBitIn(N) {
for (let i = 31; i >= 0; i--) {
if (N & (1 << i))
return i ;
}
return 0;
}
function getBit(N, i) {
return (N & (1 << i)) >> i;
}
function setBit(N, i, value) {
return N | (value << i);
}
function divideWithoutDivision(dividend, divisor) {
let negativeResult = (dividend < 0) ^ (divisor < 0);
dividend = Math.abs(dividend);
divisor = Math.abs(divisor);
let quotient = longDivision(dividend, divisor);
return negativeResult ? -quotient : quotient;
}
All these solutions are too long. The base idea is to write the quotient (for example, 5=101) as 100 + 00 + 1 = 101.
public static Point divide(int a, int b) {
if (a < b)
return new Point(0,a);
if (a == b)
return new Point(1,0);
int q = b;
int c = 1;
while (q<<1 < a) {
q <<= 1;
c <<= 1;
}
Point r = divide(a-q, b);
return new Point(c + r.x, r.y);
}
public static class Point {
int x;
int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int compare(Point b) {
if (b.x - x != 0) {
return x - b.x;
} else {
return y - b.y;
}
}
#Override
public String toString() {
return " (" + x + " " + y + ") ";
}
}
Since bit wise operations work on bits that are either 0 or 1, each bit represents a power of 2, so if I have the bits
1010
that value is 10.
Each bit is a power of two, so if we shift the bits to the right, we divide by 2
1010 --> 0101
0101 is 5
so, in general if you want to divide by some power of 2, you need to shift right by the exponent you raise two to, to get that value
so for instance, to divide by 16, you would shift by 4, as 2^^4 = 16.