binary gcd algorithm - not working - c++

I read the binary gcd algorithm and tried to implement it .It worked. This is my code
int gcd2(int a, int b) {
int sh;
if (a == 0)
return b;
if (b == 0)
return a;
for (sh = 0; !((a | b) & 1); sh++) {
a >>= 1;
b >>= 1;
}
while (!(a & 1)) {
a >>= 1;
}
while(b) {
while (!(b & 1)) {
b >>= 1;
}
if (a > b) {
int t = a;
a = b;
b = t;
}
b = b - a;
}
return a << sh;
}
But doesn't work if I replace the last if with
if (b > a)
{
int t = a;
a = b;
b = t;
}
b = a -b;
I just thought that both should work since they are doing the same.But it doesn't work.
Can anyone explain it please?
Thanks in advance!

it is not the same: if you choose your second way, there is the chance that a always stays bigger then b. then you never get to svap variables, and b is always less then a after b=a-b, if b is positive
i think using
a=a-b
instead of
b=a-b
could do it

Related

C++ Merge Overlapping Strings

Let's say that I have string A: "info_mesh", and I want to add it string B: "mesh_foo".
However, I want string "info_mesh_foo", not string "info_meshmesh_foo".
I can't just say:
std::string A = "randomstuffoverlap", B = "overlapwithmorestuff"
std::string C = A + B;
Because I would end up with:
C = "randomstuffoverlapoverlapwithmorestuff",
when I want:
C = "randomstuffoverlapwithmorestuff"
without the "overlap" mentioned twice, as if the created string had a "mesh" of two strings.
However, I also would want this to work if:
std::string A = "juststuff", B = "unrelatedstuff", C;
//std::string C should be made equal to "juststuffunrelatedstuff".
(so there is No shared substring between them)
How would I go about doing this?
Thanks in advance.
Try this;
std::string A = "randomstuffoverlap", B = "overlapwithmorestuff", C;
size_t pos = A.find_last_of(B[0]);
if (pos != std::string::npos)
{
std::string::difference_type d = A.size() - pos;
if (A.substr(pos) == B.substr(0, d))
C = A + B.substr(d);
else
C = A + B;
}
else
C = A + B;
std::cout << C << std::endl;
Well, starting with the maximum possible (full overlap), loop down until it fits, and then return the result from overlapping them:
std::string overlap(std::string_view a, std::string_view b) {
for (auto n = std::min(a.size(), b.size());; --n) {
if (b.endswith(a.substr(0, n))) // b.substr(b.size() - n) == a.substr(0, n)
return std::string(b) + a.substr(n);
else if (a.endswith(b.substr(0, n))) // a.substr(a.size() - n) == b.substr(0, n)
return std::string(a) + b.substr(n);
}
If you cannot use C++20 std::string_view::endswith(), use the alternative in the comment.
This has taken me a while, but I have this function:
string overlapjoin(string a, string b) {
for (long long x = (b.length()<= a.length())? b.length(): a.length(); x > 0; --x)
if (a.substr(a.length() - x, a.length() - 1) == b.substr(0, x))
return(a.substr(0, a.length() - x) + b);
return(a + b);
}
Which can also be expressed as, if you want a limit to shared characters:
string overlapjoin(string a, string b, int maxlength) {
for (long long x = maxlength; x > 0; --x)
if (a.substr(a.length() - x, a.length() - 1) == b.substr(0, x))
return(a.substr(0, a.length() - x) + b);
return(a + b);
}

getNthRoots function wrong answers

So i have a function
Vector getNthRoots(double a, double b, double c, int n)
{
Vector v;
int i;
v.length = 0;
double m, a2, b2, c2;
if (n % 2 == 0)
{
a2 = a;
b2 = b;
c2 = c;
if (a<0)
a2 = a*(-1);
if (b<0)
b2 = b*(-1);
if (c<0)
c2 = c*(-1);
m = floor(pow(max(a2, b2, c2),1/n));
for (i = 1; i <= m; i++)
if (pow(i, n) >= min(a2, b2, c2) && pow(i, n) <= max(a2, b2, c2))
{
v.values[v.length] = i;
v.length++;
v.values[v.length] = (-1)*i;
v.length++;
}
return v;
}
else {
for (i = ceil(pow(min(a, b, c),1/n)); i <= floor(pow(max(a, b, c),1/n)); i++)
if (pow(i, n) >= min(a, b, c) && pow(i, n) <= max(a, b, c))
{
v.values[v.length] = i;
v.length++;
}
return v;
}
}
This function is supposed to give you the numbers at power n (number^n) which are in the interval of min(a,b,c) and max(a,b,c);
Other functions/headers
double max(double a, double b, double c)
{
if (a >= b && a >= c)
return a;
if (b >= a && b >= c)
return b;
if (c >= a && c >= b)
return c;
return a;
}
double min(double a, double b, double c)
{
if (a <= b && a <= c)
return a;
if (b <= a && b <= c)
return b;
if (c <= a && c <= b)
return c;
return a;
}
#include <iostream>
#include <cmath>
using namespace std;
#define MAX_ARRAY_LENGTH 100
struct Vector
{
unsigned int length;
int values[MAX_ARRAY_LENGTH];
};
It seems i can`t receive the good answer . For example
for getNthRoots(32,15,37,5) it should return a vector [2] because 2^5 =32 which belongs to interval [15,37] but i don`t receive anything
or getNthRoots(32,1,7,5) it should return a vector [1,2] but i only receive 1 as answer
I am guessing here is the problem for (i = ceil(pow(min(a, b, c),1/n)); i <= floor(pow(max(a, b, c),1/n)); i++)but i don`t know how i could fix it
1/n evaluates to 0, because it is evaluated as an integer expression. Try replacing all the "1/n"s with "1.0/n"s.
Take care to handle the case where n is 0.

Mod power or totient logic issue

Here is some code I adapted that deals with the euler totient function and a power mod function. Every n, f2 is always 3 instead of a variety of numbers. Does anyone see an error? phi(n) and modpow(n) both seem to work fine.
#include <iostream>
using namespace std;
int gcd(int a, int b)
{
while (b != 0)
{
int c = a % b;
a = b;
b = c;
}
return a;
}
int phi(int n)
{
int x = 0;
for (int i=1; i<=n; i++)
{
if (gcd(n, i) == 1)
x++;
}
return x;
}
int modpow(int base, int exp, int mod) // from stackoverflow
{
base %= mod;
long long result = 1;
while (exp > 0)
{
if (exp & 1)
result = (result * base) % mod;
base = (base * base) % mod;
exp >>= 1;
}
return result;
}
int f2(int n) // f(f(n)) mod n
{
long long a = modpow(2, n, phi(n)) + 1;
return (modpow(2, a, n) + 1) % n;
}
// ...
int main()
{
int n = 520001;
while (true)
{
cout << "f2 " << f2(n) << endl;
if (f2(n) == 0)
{
// ...
}
n += 2;
}
return 0;
}
Values of f2(n) should be 9, 458278, 379578, ...
base*base will exceed the size of an int if base >= 65536. Try this fix, seems to work:
int modpow(int base, int exp, int mod) // from stackoverflow
{
base %= mod;
long long result = 1;
while (exp > 0)
{
if (exp & 1)
result = (result * base) % mod;
base = (int)(((long long)base * (long long)base) % mod);
exp >>= 1;
}
return (int) result;
}

Project Euler 009 Problems

In Project Euler's problem 9, I encounter a problem: infinite loops.
Here is my code:
#include <iostream>
#include <cmath>
bool isPythagorean(int a, int b, int c);
int main(){
int a;
int aa;
int b;
int bb;
int c;
for(a = 0; a <= 1000; a++){ /*a loop*/
aa = a;
for(b = aa; b <= 1000; b++){ /*b loop*/
bb = b;
for(c = bb; c <= 1000; c++){
if(isPythagorean(a,b,c)){
if(a + b + c == 1000){
std::cout << (a * b) * c;
return 0;
}
else
continue;
}
}
}
return 1;
}
bool isPythagorean(int a, int b, int c){
int Pa = (int) pow(a, 2);
int Pb = (int) pow(b, 2);
int Pc = (int) pow(c, 2);
if(a < b && b < c){
if(Pa + Pb == Pc)
return true;
else
return false;
}
else
return false;
}
Courtesy of everyone who has helped the idiot writing this, the code has been changed, but the error still stands:
When the code is run, nothing is output to the terminal. Could anyone kindly tell me what is going wrong here?
(I am such an idiot; My thanks go to everyone that is even looking at this.)
Thank you, istrandjev for noticing a whole host of bad pieces of code.
Thank you, Blastfurnace for noticing that stupid error.
I don't get much of the logic you are trying to apply. What is a%1==0&&b%1==0&c%1==0 checking? You can simply write it if(true), you know. Also when is the cycle supposed to end? How is a triplet supposed to be Pythagorean if one of the conditions is a > c and then you want to have a*a + b*b == c*c?

How to add two numbers without using ++ or + or another arithmetic operator

How do I add two numbers without using ++ or + or any other arithmetic operator?
It was a question asked a long time ago in some campus interview. Anyway, today someone asked a question regarding some bit-manipulations, and in answers a beautiful quide Stanford bit twiddling was referred. I spend some time studying it and thought that there actually might be an answer to the question. I don't know, I could not find one. Does an answer exist?
This is something I have written a while ago for fun. It uses a two's complement representation and implements addition using repeated shifts with a carry bit, implementing other operators mostly in terms of addition.
#include <stdlib.h> /* atoi() */
#include <stdio.h> /* (f)printf */
#include <assert.h> /* assert() */
int add(int x, int y) {
int carry = 0;
int result = 0;
int i;
for(i = 0; i < 32; ++i) {
int a = (x >> i) & 1;
int b = (y >> i) & 1;
result |= ((a ^ b) ^ carry) << i;
carry = (a & b) | (b & carry) | (carry & a);
}
return result;
}
int negate(int x) {
return add(~x, 1);
}
int subtract(int x, int y) {
return add(x, negate(y));
}
int is_even(int n) {
return !(n & 1);
}
int divide_by_two(int n) {
return n >> 1;
}
int multiply_by_two(int n) {
return n << 1;
}
int multiply(int x, int y) {
int result = 0;
if(x < 0 && y < 0) {
return multiply(negate(x), negate(y));
}
if(x >= 0 && y < 0) {
return multiply(y, x);
}
while(y > 0) {
if(is_even(y)) {
x = multiply_by_two(x);
y = divide_by_two(y);
} else {
result = add(result, x);
y = add(y, -1);
}
}
return result;
}
int main(int argc, char **argv) {
int from = -100, to = 100;
int i, j;
for(i = from; i <= to; ++i) {
assert(0 - i == negate(i));
assert(((i % 2) == 0) == is_even(i));
assert(i * 2 == multiply_by_two(i));
if(is_even(i)) {
assert(i / 2 == divide_by_two(i));
}
}
for(i = from; i <= to; ++i) {
for(j = from; j <= to; ++j) {
assert(i + j == add(i, j));
assert(i - j == subtract(i, j));
assert(i * j == multiply(i, j));
}
}
return 0;
}
Or, rather than Jason's bitwise approach, you can calculate many bits in parallel - this should run much faster with large numbers. In each step figure out the carry part and the part that is sum. You attempt to add the carry to the sum, which could cause carry again - hence the loop.
>>> def add(a, b):
while a != 0:
# v carry portion| v sum portion
a, b = ((a & b) << 1), (a ^ b)
print b, a
return b
when you add 1 and 3, both numbers have the 1 bit set, so the sum of that 1+1 carries. The next step you add 2 to 2 and that carries into the correct sum four. That causes an exit
>>> add(1,3)
2 2
4 0
4
Or a more complex example
>>> add(45, 291)
66 270
4 332
8 328
16 320
336
Edit:
For it to work easily on signed numbers you need to introduce an upper limit on a and b
>>> def add(a, b):
while a != 0:
# v carry portion| v sum portion
a, b = ((a & b) << 1), (a ^ b)
a &= 0xFFFFFFFF
b &= 0xFFFFFFFF
print b, a
return b
Try it on
add(-1, 1)
to see a single bit carry up through the entire range and overflow over 32 iterations
4294967294 2
4294967292 4
4294967288 8
...
4294901760 65536
...
2147483648 2147483648
0 0
0L
int Add(int a, int b)
{
while (b)
{
int carry = a & b;
a = a ^ b;
b = carry << 1;
}
return a;
}
You could transform an adder circuit into an algorithm. They only do bitwise operations =)
Well, to implement an equivalent with boolean operators is quite simple: you do a bit-by-bit sum (which is an XOR), with carry (which is an AND). Like this:
int sum(int value1, int value2)
{
int result = 0;
int carry = 0;
for (int mask = 1; mask != 0; mask <<= 1)
{
int bit1 = value1 & mask;
int bit2 = value2 & mask;
result |= mask & (carry ^ bit1 ^ bit2);
carry = ((bit1 & bit2) | (bit1 & carry) | (bit2 & carry)) << 1;
}
return result;
}
You've already gotten a couple bit manipulation answers. Here's something different.
In C, arr[ind] == *(arr + ind). This lets us do slightly confusing (but legal) things like int arr = { 3, 1, 4, 5 }; int val = 0[arr];.
So we can define a custom add function (without explicit use of an arithmetic operator) thusly:
unsigned int add(unsigned int const a, unsigned int const b)
{
/* this works b/c sizeof(char) == 1, by definition */
char * const aPtr = (char *)a;
return (int) &(aPtr[b]);
}
Alternately, if we want to avoid this trick, and if by arithmetic operator they include |, &, and ^ (so direct bit manipulation is not allowed) , we can do it via lookup table:
typedef unsigned char byte;
const byte lut_add_mod_256[256][256] = {
{ 0, 1, 2, /*...*/, 255 },
{ 1, 2, /*...*/, 255, 0 },
{ 2, /*...*/, 255, 0, 1 },
/*...*/
{ 254, 255, 0, 1, /*...*/, 253 },
{ 255, 0, 1, /*...*/, 253, 254 },
};
const byte lut_add_carry_256[256][256] = {
{ 0, 0, 0, /*...*/, 0 },
{ 0, 0, /*...*/, 0, 1 },
{ 0, /*...*/, 0, 1, 1 },
/*...*/
{ 0, 0, 1, /*...*/, 1 },
{ 0, 1, 1, /*...*/, 1 },
};
void add_byte(byte const a, byte const b, byte * const sum, byte * const carry)
{
*sum = lut_add_mod_256[a][b];
*carry = lut_add_carry_256[a][b];
}
unsigned int add(unsigned int a, unsigned int b)
{
unsigned int sum;
unsigned int carry;
byte * const aBytes = (byte *) &a;
byte * const bBytes = (byte *) &b;
byte * const sumBytes = (byte *) ∑
byte * const carryBytes = (byte *) &carry;
byte const test[4] = { 0x12, 0x34, 0x56, 0x78 };
byte BYTE_0, BYTE_1, BYTE_2, BYTE_3;
/* figure out endian-ness */
if (0x12345678 == *(unsigned int *)test)
{
BYTE_0 = 3;
BYTE_1 = 2;
BYTE_2 = 1;
BYTE_3 = 0;
}
else
{
BYTE_0 = 0;
BYTE_1 = 1;
BYTE_2 = 2;
BYTE_3 = 3;
}
/* assume 4 bytes to the unsigned int */
add_byte(aBytes[BYTE_0], bBytes[BYTE_0], &sumBytes[BYTE_0], &carryBytes[BYTE_0]);
add_byte(aBytes[BYTE_1], bBytes[BYTE_1], &sumBytes[BYTE_1], &carryBytes[BYTE_1]);
if (carryBytes[BYTE_0] == 1)
{
if (sumBytes[BYTE_1] == 255)
{
sumBytes[BYTE_1] = 0;
carryBytes[BYTE_1] = 1;
}
else
{
add_byte(sumBytes[BYTE_1], 1, &sumBytes[BYTE_1], &carryBytes[BYTE_0]);
}
}
add_byte(aBytes[BYTE_2], bBytes[BYTE_2], &sumBytes[BYTE_2], &carryBytes[BYTE_2]);
if (carryBytes[BYTE_1] == 1)
{
if (sumBytes[BYTE_2] == 255)
{
sumBytes[BYTE_2] = 0;
carryBytes[BYTE_2] = 1;
}
else
{
add_byte(sumBytes[BYTE_2], 1, &sumBytes[BYTE_2], &carryBytes[BYTE_1]);
}
}
add_byte(aBytes[BYTE_3], bBytes[BYTE_3], &sumBytes[BYTE_3], &carryBytes[BYTE_3]);
if (carryBytes[BYTE_2] == 1)
{
if (sumBytes[BYTE_3] == 255)
{
sumBytes[BYTE_3] = 0;
carryBytes[BYTE_3] = 1;
}
else
{
add_byte(sumBytes[BYTE_3], 1, &sumBytes[BYTE_3], &carryBytes[BYTE_2]);
}
}
return sum;
}
All arithmetic operations decompose to bitwise operations to be implemented in electronics, using NAND, AND, OR, etc. gates.
Adder composition can be seen here.
For unsigned numbers, use the same addition algorithm as you learned in first class, but for base 2 instead of base 10. Example for 3+2 (base 10), i.e 11+10 in base 2:
1 ‹--- carry bit
0 1 1 ‹--- first operand (3)
+ 0 1 0 ‹--- second operand (2)
-------
1 0 1 ‹--- total sum (calculated in three steps)
If you're feeling comedic, there's always this spectacularly awful approach for adding two (relatively small) unsigned integers. No arithmetic operators anywhere in your code.
In C#:
static uint JokeAdder(uint a, uint b)
{
string result = string.Format(string.Format("{{0,{0}}}{{1,{1}}}", a, b), null, null);
return result.Length;
}
In C, using stdio (replace snprintf with _snprintf on Microsoft compilers):
#include <stdio.h>
unsigned int JokeAdder(unsigned int a, unsigned int b)
{
return snprintf(NULL, 0, "%*.*s%*.*s", a, a, "", b, b, "");
}
Here is a compact C solution. Sometimes recursion is more readable than loops.
int add(int a, int b){
if (b == 0) return a;
return add(a ^ b, (a & b) << 1);
}
#include<stdio.h>
int add(int x, int y) {
int a, b;
do {
a = x & y;
b = x ^ y;
x = a << 1;
y = b;
} while (a);
return b;
}
int main( void ){
printf( "2 + 3 = %d", add(2,3));
return 0;
}
short int ripple_adder(short int a, short int b)
{
short int i, c, s, ai, bi;
c = s = 0;
for (i=0; i<16; i++)
{
ai = a & 1;
bi = b & 1;
s |= (((ai ^ bi)^c) << i);
c = (ai & bi) | (c & (ai ^ bi));
a >>= 1;
b >>= 1;
}
s |= (c << i);
return s;
}
## to add or subtract without using '+' and '-' ##
#include<stdio.h>
#include<conio.h>
#include<process.h>
void main()
{
int sub,a,b,carry,temp,c,d;
clrscr();
printf("enter a and b:");
scanf("%d%d",&a,&b);
c=a;
d=b;
while(b)
{
carry=a&b;
a=a^b;
b=carry<<1;
}
printf("add(%d,%d):%d\n",c,d,a);
temp=~d+1; //take 2's complement of b and add it with a
sub=c+temp;
printf("diff(%d,%d):%d\n",c,d,temp);
getch();
}
The following would work.
x - (-y)
This can be done recursively:
int add_without_arithm_recursively(int a, int b)
{
if (b == 0)
return a;
int sum = a ^ b; // add without carrying
int carry = (a & b) << 1; // carry, but don’t add
return add_without_arithm_recursively(sum, carry); // recurse
}
or iteratively:
int add_without_arithm_iteratively(int a, int b)
{
int sum, carry;
do
{
sum = a ^ b; // add without carrying
carry = (a & b) << 1; // carry, but don’t add
a = sum;
b = carry;
} while (b != 0);
return a;
}
Code to implement add,multiplication without using +,* operator;
for subtraction pass 1's complement +1 of number to add function
#include<stdio.h>
unsigned int add(unsigned int x,unsigned int y)
{
int carry=0;
while (y != 0)
{
carry = x & y;
x = x ^ y;
y = carry << 1;
}
return x;
}
int multiply(int a,int b)
{
int res=0;
int i=0;
int large= a>b ? a :b ;
int small= a<b ? a :b ;
for(i=0;i<small;i++)
{
res = add(large,res);
}
return res;
}
int main()
{
printf("Sum :: %u,Multiply is :: %d",add(7,15),multiply(111,111));
return 0;
}
The question asks how to add two numbers so I don't understand why all the solutions offers the addition of two integers? What if the two numbers were floats i.e. 2.3 + 1.8 are they also not considered numbers? Either the question needs to be revised or the answers.
For floats I believe the numbers should be broken into their components i.e. 2.3 = 2 + 0.3 then the 0.3 should be converted to an integer representation by multiplying with its exponent factor i.e 0.3 = 3 * 10^-1 do the same for the other number and then add the integer segment using one of the bit shift methods given as a solution above handling situations for carry over to the unit digits location i.e. 2.7 + 3.3 = 6.0 = 2+3+0.7+0.3 = 2 + 3 + 7x10^-1 + 3x10^-1 = 2 + 3 + 10^10^-1 (this can be handled as two separate additions 2+3=5 and then 5+1=6)
With given answers above, it can be done in single line code:
int add(int a, int b) {
return (b == 0) ? a : add(a ^ b, (a & b) << 1);
}
You can use double negetive to add two integers for example:
int sum2(int a, int b){
return -(-a-b);
}
Without using any operators adding two integers can be done in different ways as follows:
int sum_of_2 (int a, int b){
int sum=0, carry=sum;
sum =a^b;
carry = (a&b)<<1;
return (b==0)? a: sum_of_2(sum, carry);
}
// Or you can just do it in one line as follows:
int sum_of_2 (int a, int b){
return (b==0)? a: sum_of_2(a^b, (a&b)<<1);
}
// OR you can use the while loop instead of recursion function as follows
int sum_of_2 (int a, int b){
if(b==0){
return a;
}
while(b!=0){
int sum = a^b;
int carry = (a&b)<<1;
a= sum;
b=carry;
}
return a;
}
int add_without_arithmatic(int a, int b)
{
int sum;
char *p;
p = (char *)a;
sum = (int)&p[b];
printf("\nSum : %d",sum);
}