RSA Algorithm For Numbers and Char values - c++

I'm not a programming expert. I'm new to cryptography and I had gone through the security algorithm RSA. I wrote the code like this:
#include<math.h>
#include<iostream>
#include<cmath>
#include<Windows.h>
using namespace std;
class rsacrypto
{
long publickey;
long privatekey;
long modl; //Modulus
public :
rsacrypto(); //To be used to just generate private and public keys.
rsacrypto(long &,long &,long &);//To be used just to generate private and public keys.
rsacrypto(long key,long modulus) // Should be used when a data is to be encrypted or decrypted using a key.
{
publickey = privatekey = key;
modl = modulus;
}
long ret_publickey()
{
return publickey;
}
long ret_privatekey()
{
return privatekey;
}
long ret_modulus()
{
return modl;
}
void encrypt(char *);
void decrypt(char *);
int genrndprimes(int, int);
int genrndnum(int, int);
int totient(int);
int gcd (int, int);
int mulinv(int, int);
boolean isPrime(long);
};
rsacrypto::rsacrypto()
{
long p1,p2; //Prime numbers
long n = 0; //Modulus
long phi =0; //Totient value.
long e = 0; //Public key exponent.
long d = 0; //Private key exponent.
p1 = genrndprimes(1,10);
Sleep(1000);
p2 = genrndprimes(1,10);
n = p1*p2;
phi = (p1-1)*(p2-1);
e = genrndnum(2,(phi-1));
while(gcd(e,phi)!=1)
{
e = genrndnum(2,(phi-1));
}
d = mulinv(e, phi);
cout<<"Public Key=("<<e<<","<<n<<")"<<"\n";
cout<<"Private Key=("<<d<<","<<n<<")"<<"\n";
privatekey = e;
publickey = d;
modl = n;
int m=11;
int en=0, decr=0;
//Encryption
en=(long)pow((double)m,d)%n;
cout<<en<<"\n";
//Decryption
decr=(long)pow((double)en,e)%n;
cout<<decr;
}
/*
void rsacrypto::encrypt(char *dat)
{
long siz = strlen(dat);
for(long i=0;i<siz;i++)
{
dat[i]=(long)pow((double)dat[i],publickey)%modl;
cout<<i<<"="<<dat[i]<<"\n";
}
}
void rsacrypto::decrypt(char *datn)
{
long sizz = strlen(datn);
for(long i=0;i<sizz;i++)
{
datn[i]=(long)pow((double)datn[i],privatekey)%modl;
}
cout<<datn;
}*/
int rsacrypto::mulinv(int a, int b)
{
int b0 = b, t, q;
int x0 = 0, x1 = 1;
if (b == 1) return 1;
while (a > 1) {
q = a / b;
t = b, b = a % b, a = t;
t = x0, x0 = x1 - q * x0, x1 = t;
}
if (x1 < 0) x1 += b0;
return x1;
}
int rsacrypto::genrndprimes(int a, int b){
long pivot;
do{
pivot= rand() % b + a;
if (isPrime(pivot))
return pivot;
} while (1==1);
}
boolean rsacrypto::isPrime(long pivot) {
if(pivot <= 1)
return false;
int root = sqrt((double)pivot);
//start at 2 because all numbers are divisible by 1
for(int x = 2; x <= root; x++) //You only need to check up to and including the root
{
if(pivot % x == 0)
return false;
}
return true;
}
int rsacrypto::genrndnum(int a, int b){
long pivot;
pivot= rand() % b + a;
return pivot;
}
int rsacrypto::gcd ( int a, int b )
{
int c;
while ( a != 0 ) {
c = a; a = b%a; b = c;
}
return b;
}
void main()
{
rsacrypto m;
system("pause");
}
But I would like to make this code work for hexa decimal values. I don't know how to do that. I'm not a programming expert. Any help would be sinscierly appreciated. Thankyou.

I guess your problem is to transfer the double values (hex decimal values) into char values first. Then you can use the existing code to encrypt/decrypt the char values.
There are two ways to convert the double values into char values:
Convert each double into two char's as its printable/readable form, e.g., 123.455 -> "123.456";
I refer some code from this discussion:
#include <sstream>
stringstream ss;
ss << myDouble;
const char* str = ss.str().c_str();
ss >> myOtherDouble;
Convert each double into two char's as its byte form;
Please see this discussion:
Use a union:
union {
double d[2];
char b[sizeof(double) * 2];
};
Or reinterpret_cast:
char* b = reinterpret_cast<double*>(d);
Now, after converting your double values into char values, we can directly utilize the existing code to encrypt our data.

Related

Why am I getting a logic error in this Karatsuba Multiplication?

I've read many blogs and examples of code but I'm trying to implement the Karatsuba multiplication through a way that is currently not logically working. Only single digit number multiplications are working, but any digits longer than 1 are displaying completely wrong answers.
It should be able to take in long numbers of input, but I'm not allowed to use long int storage type.
Also, it's meant to be able to multiply numbers of different base (1-10) however I'm unsure on how to do that so initially I'm just attempting base 10.
This is my code so far:
#include <iostream>
#include <string>
#include <algorithm>
#include <cmath>
#include <sstream>
int compareSize(string integer1, string integer2)
{
int length = 0;
if (integer1.length() > integer2.length())
{
//allocating int 1's length as final length if bigger than int 2
length = integer1.length();
}
else if (integer2.length() > integer1.length())
{
//allocating int 2's length as final length if bigger than int 1
length = integer2.length();
}
else
{
length = integer1.length();
}
return length;
}
int multiplication( string I1, string I2, int B){
int length = compareSize(I1, I2);
//converting the strings into integers
stringstream numberOne(I1);
int digitOne = 0;
numberOne >> digitOne;
stringstream numberTwo(I2);
int digitTwo = 0;
numberTwo >> digitTwo;
//checking if numbers are single digits
if ( (10 > digitOne) || (10 > digitTwo) ) {
//cout<<(digitOne * digitTwo)<<endl;
return (digitOne * digitTwo);
}
int size = ( length % 2) + (length / 2);
int power = pow(10, size);
int a = digitOne / power;
int c = digitTwo / power;
int b = digitOne - (a * power);
int d = digitTwo - (c * power);
int p2 = b * d;
int p0 = a * c;
int p1 = (b + a) * (d + c);
//int final = p1 - p2 - p0;
int sum = ((a*d) + (b*c)) ;
int p = (p0*(pow(10,length))) + (sum * (pow(10,length)) + p2);
//int p = ( p2 * (pow(10,size*2)) + ( p1 - (p2+p0)) * pow(10,size) + p0 ) * 100;
// int p = (p2 * (long long)(pow(10, 2 * size))) + p0 + ((p1 - p0 - p2) * power);
return p;
}
int main(){
string int1, int2;
int base;
cout<<"Enter I1, I2 and B: ";
cin>> int1 >> int2 >> base;
cout<<" "<<multiplication(int1, int2, base)<<endl;
return 0;
}
The main problem is
int p = (p0*(pow(10,length))) + (sum * (pow(10,length)) + p2);
It should be
int p = (p0*(pow(10,length))) + (sum * (pow(10,length - 1)) + p2);
You shouldn't use std::pow for integers GCC C++ pow accuracy. I replaced it with my own version:
#include <iostream>
#include <string>
#include <algorithm>
#include <sstream>
int pow(int b, int e) {
if (e == 0) return 1;
if (e == 1) return b;
if (e % 2 == 0) return pow(b * b, e / 2);
return b * pow(b * b, e / 2);
}
int multiplication(std::string I1, std::string I2) {
int length = std::max(I1.length(), I2.length());
int digitOne = std::stoi(I1);
int digitTwo = std::stoi(I2);
if ( (10 > digitOne) || (10 > digitTwo) ) {
return (digitOne * digitTwo);
}
int size = ( length % 2) + (length / 2);
int power = pow(10, size);
int a = digitOne / power;
int c = digitTwo / power;
int b = digitOne - (a * power);
int d = digitTwo - (c * power);
int p2 = b * d;
int p0 = a * c;
int sum = ((a*d) + (b*c)) ;
int p = (p0*(pow(10,length))) + (sum * (pow(10,length - 1)) + p2);
return p;
}
int main(){
std::string int1, int2;
std::cout<<"Enter I1 and I2: ";
std::cin>> int1 >> int2;
std::cout<<" "<<multiplication(int1, int2)<<'\n';
return 0;
}

for loop calculates the same value each time

I am trying to implement a recurrence relation that will return me the kth term. But I am receiving the same output when I change the k value. Here is my code:
int recurrence(int a, int b, int k, int u0, int u1) {
int u = u0;
int uu = u1;
for (int i = 0; i < k; i++)
uu = a*u1 + b*u0;
return uu;
}
int recurrence2(int a1, int b1, int k1, int u4, int u5) {
int u = u4;
int uu = u5;
for (int i = 0; i < k1; i++)
uu = a1*u5 + b1*u4;
return uu;
}
int main() {
int h;
h = recurrence(7, 1, 5, 3, 5 );
int g;
g = recurrence2(17, 11, 2, 1, 2);
cout << "The result is: " << h;
cout << "The result is : " << g;
}
You evaluate the same values in expression in the loop, so result would not change regardless how many times you execute it. Looks like this is what you need:
int recurrence(int a, int b, int k, int u0, int u1)
{
for (int i = 0; i < k; i++) {
auto tmp = a*u1 + b*u0;
u0 = u1;
u1 = tmp;
}
return u1;
}
or simpler:
int recurrence(int a, int b, int k, int u0, int u1)
{
for (int i = 0; i < k; i++) {
u0 = a*u1 + b*u0;
std::swap( u1, u0 );
}
return u1;
}
second function needs to be changed the same way.
PS you asked how could you maintain state of variables for further invocations, best way is to have class that maintains it:
class Recurrence {
int m_a;
int m_b;
int m_u0;
int m_u1;
public:
Recurrence( int a, int b, int u0, int u1 ) :
m_a( a ),
m_b( b ),
m_u0( u0 ),
m_u1( u1 )
{
}
int value() const { return m_u1; }
void interate()
{
m_u0 = m_a * m_u1 + m_b * m_u0;
std::swap( m_u0, m_u1 );
}
void interateN( int n )
{
for( int i = 0; i < n; ++i ) iterate();
}
};
int main()
{
Recurence recurence( 7, 1, 3, 5 );
recurence.iterateN( 5 );
int h = recurence.value();
recurence.iterateN( 5 ); // continue
...
}
In reality you may want to have that class more generic - for example use different number of arguments, different types, store them in array etc. This code just to show you the idea.

How to multiply a number with 3.5 without using any standard operator like *,-,/,% etc?

The Question is pretty straight forward.I am given a number and I want to multiply it with 3.5 i.e to make number n=3.5n .I am not allowed to use any operator like
+,-,*,/,% etc.But I can use Bitwise operators.
I have tried by myself but It is not giving precise result like my program gives output 17 for 5* 3.5 which is clearly wrong.How can I modify my program to show correct result.
#include<bits/stdc++.h>
using namespace std;
double Multiply(int n)
{
double ans=((n>>1)+ n + (n<<1));
return ans;
}
int main()
{
int n; // Enter the number you want to multiply with 3.5
cin>>n;
double ans=Multiply(n);
cout<<ans<<"\n";
return 0;
}
Sorry I cannot comment yet. The problem with your question is that bitwise operations are usually only done on ints. This is mainly because of the way that numbers are stored.
When you have a normal int, you have a sign bit followed by data bits, pretty simple and straight forward but once you get to floating point numbers that simple patern is different. Here is a good explanation stackoverflow.
Also, the way I would solve your problem without using +/-/*// and so on would be
#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;
}
Source
From your solution, you may handle odd numbers manually:
double Multiply(unsigned int n)
{
double = n + (n << 1) + (n >> 1) + ((n & 1) ? 0.5 : 0.);
return ans;
}
but it still use +
One solution would be to use fma() from <cmath>:
#include <cmath>
double Multiply(int n)
{
return fma(x, 3.5, 0.0);
}
LIVE DEMO
Simply.
First realize that 3.5 = 112 / 32 = (128 - 16) / 32.
Than you do:
int x128 = ur_num << 7;
int x16 = ur_num << 4;
to subtract them use:
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));
}
and than just simply do:
int your_res = subtract(x128, x16) >> 5;

Passing Extra Data Into a Function

I am using the dlib optimization library for C++ specifically the following function:
template <
typename search_strategy_type,
typename stop_strategy_type,
typename funct,
typename funct_der,
typename T
>
double find_max (
search_strategy_type search_strategy,
stop_strategy_type stop_strategy,
const funct& f,
const funct_der& der,
T& x,
double max_f
);
Functions f and der are designed to take a vector of the data parameters being modified to obtain the maximum value of my function. However my function being maximized has four parameters (one is my dataset and the other is fixed by me). However I can't pass these as inputs to my f and der functions because of the format they are supposed to have. How do I get this data into my functions? I am currently trying the below (I hard set variable c but for vector xgrequ I read data from a file each time I process the function.
//Function to be minimized
double mleGPD(const column_vector& p)
{
std::ifstream infile("Xm-EVT.csv");
long double swapRet;
std::string closeStr;
std::vector<double> histRet;
//Read in historical swap data file
if (infile.is_open())
{
while (!infile.eof())
{
infile >> swapRet;
histRet.push_back(swapRet);
}
}
sort(histRet.begin(), histRet.end());
std::vector<double> negRet;
//separate out losses
for (unsigned c = 0; c < histRet.size(); c++)
{
if (histRet[c] < 0)
{
negRet.push_back(histRet[c]);
}
}
std::vector<double> absValRet;
//make all losses positive to fit with EVT convention
for (unsigned s = 0; s < negRet.size(); s++)
{
absValRet.push_back(abs(negRet[s]));
}
std::vector<double> xminusu, xmu, xgrequ;
int count = absValRet.size();
double uPercent = .9;
int uValIndex = ceil((1 - uPercent)*count);
int countAbove = count - uValIndex;
double c = (double)absValRet[uValIndex - 1];
//looking at returns above u
for (unsigned o = 0; o < uValIndex; ++o)
{
xmu.push_back(absValRet[o] - c);
if (xmu[o] >= 0)
{
xgrequ.push_back(absValRet[o]);
xminusu.push_back(xmu[o]);
}
}
double nu = xgrequ.size();
double sum = 0.0;
double a = p(0);
double b = p(1);
for (unsigned h = 0; h < nu; ++h)
{
sum += log((1 / b)*pow(1 - a*((xgrequ[h] - c) / b), -1 + (1 / a)));
}
return sum;
}
//Derivative of function to be minimized
const column_vector mleGPDDer(const column_vector& p)
{
std::ifstream infile("Xm-EVT.csv");
long double swapRet;
std::string closeStr;
std::vector<double> histRet;
//Read in historical swap data file
if (infile.is_open())
{
while (!infile.eof())
{
infile >> swapRet;
histRet.push_back(swapRet);
}
}
sort(histRet.begin(), histRet.end());
std::vector<double> negRet;
//separate out losses
for (unsigned c = 0; c < histRet.size(); c++)
{
if (histRet[c] < 0)
{
negRet.push_back(histRet[c]);
}
}
std::vector<double> absValRet;
//make all losses positive to fit with EVT convention
for (unsigned s = 0; s < negRet.size(); s++)
{
absValRet.push_back(abs(negRet[s]));
}
std::vector<double> xminusu, xmu, xgrequ;
int count = absValRet.size();
double uPercent = .9;
int uValIndex = ceil((1 - uPercent)*count);
int countAbove = count - uValIndex;
double c = (double)absValRet[uValIndex - 1];
//looking at returns above u
for (unsigned o = 0; o < uValIndex; ++o)
{
xmu.push_back(absValRet[o] - c);
if (xmu[o] >= 0)
{
xgrequ.push_back(absValRet[o]);
xminusu.push_back(xmu[o]);
}
}
column_vector res(2);
const double a = p(0);
const double b = p(1);
double nu = xgrequ.size();
double sum1 = 0.0;
double sum2 = 0.0;
for (unsigned h = 0; h < nu; ++h)
{
sum1 += ((xgrequ[h]-c)/b)/(1-a*((xgrequ[h]-c)/b));
sum2 += log(1 - a*((xgrequ[h] - c) / b));
}
res(0) = sum1;//df/da
res(1) = sum2;//df/db
return res;
}
Here is what my actual function call looks like:
//Dlib max finding
column_vector start(2);
start = .1, .1; //starting point for a and b
find_max(bfgs_search_strategy(), objective_delta_stop_strategy(1e-6), mleGPD, mleGPDDer, start,100);
std::cout << "solution" << start << std::endl;
This kind of API is very common. It's almost always possible to for f and der to any callable, not just static functions. that is, you can pass a custom class object with operator () to it.
For example
struct MyF {
//int m_state;
// or other state variables, such as
std::vector<double> m_histRet;
// (default constructors will do)
double operator()(const column_vector& p) const {
return some_function_of(p, m_state);
}
};
int main(){
. . .
MyF myf{42};
// or
MyF myf{someVectorContainingHistRet};
// then use myf as you would have used mleGPD
}
You need to initiate MyF and MyDer with the same state (std::vector<double> histRet I presume.) Either as copies or (const) references to the same state.
Edit: More full example:
struct MLGDPG_State {
std::vector<double> xgrequ;
// . . . and more you need in f or fder
}
MLGDPG_State makeMLGDPG_State(const std::string& filename){
std::ifstream infile(filename);
std::ifstream infile("Xm-EVT.csv");
long double swapRet;
std::string closeStr;
std::vector<double> histRet;
//Read in historical swap data file
if (infile.is_open())
{
while (!infile.eof())
{
infile >> swapRet;
histRet.push_back(swapRet);
}
}
sort(histRet.begin(), histRet.end());
std::vector<double> negRet;
//separate out losses
for (unsigned c = 0; c < histRet.size(); c++)
{
if (histRet[c] < 0)
{
negRet.push_back(histRet[c]);
}
}
std::vector<double> absValRet;
//make all losses positive to fit with EVT convention
for (unsigned s = 0; s < negRet.size(); s++)
{
absValRet.push_back(abs(negRet[s]));
}
std::vector<double> xminusu, xmu, xgrequ;
int count = absValRet.size();
double uPercent = .9;
int uValIndex = ceil((1 - uPercent)*count);
int countAbove = count - uValIndex;
double c = (double)absValRet[uValIndex - 1];
//looking at returns above u
for (unsigned o = 0; o < uValIndex; ++o)
{
xmu.push_back(absValRet[o] - c);
if (xmu[o] >= 0)
{
xgrequ.push_back(absValRet[o]);
xminusu.push_back(xmu[o]);
}
}
return {std::move(xgrequ)};
// Or just 'return MleGPD(xgrequ)' if you are scared of {} and move
}
//Functor Class, for ion to be minimized
struct MleGPD{
MLGDPG_State state;
double operator()(const column_vector& p) const {
auto mu = state.xgrequ.size();
double sum = 0.0;
double a = p(0);
double b = p(1);
for (unsigned h = 0; h < nu; ++h)
{
sum += log((1 / b)*pow(1 - a*((xgrequ[h] - c) / b), -1 + (1 / a)));
}
return sum;
};
Use the same pattern for a struct MleGPD_Derivative.
Usage:
const auto state = makeMLGDPG_State("Xm-EVT.csv");
const auto f = MleGPD{state};
const auto der = MleGPD_Derivative{state};
start = .1, .1; //starting point for a and b
find_max(bfgs_search_strategy(), objective_delta_stop_strategy(1e-6), f, der, start,100);
std::cout << "solution" << start << std::endl;
Note, that for simple structs like these, it's often fine to use the default constructors, copy constructor etc. Also note http://en.cppreference.com/w/cpp/language/aggregate_initialization

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