Add a bit in the middle of any two bits - bit-manipulation

In a binary representation of a number is there a simpler way than this
long half(long patten, bool exclusive) {
if (patten == 0) {
return 1;
}
long newPatten = 0;
for (int p = 0; p < MAX_STEPS; p++) {
long check = 1 << p;
if ((check & patten) > 0) {
int end = (p + MAX_STEPS) - 1;
for (int to = p+1; to <= end; to++) {
long checkTo = 1 << (to % MAX_STEPS);
if ( (checkTo & patten) > 0 || to == end ) {
int distance = to - p;
long fullShift = (int)round( ((float)p) + ((float)distance)/2 );
long shift = fullShift % MAX_STEPS;
long toAdd = 1 << shift;
newPatten = newPatten | toAdd;
break;
}
}
}
}
return exclusive ? patten ^ newPatten : patten | newPatten;
}
To add a bit in the middle of any two other bits with wrapping around and rounding to one side when there is an even number of positions between?
E.g.
010001 to
110101
Or
1001 to
1101
Update: These bits aren't coming from anywhere else, such as another number, just want a new True bit to be in the middle of any other two True bits, so if there was a 101, then the middle would be the 0 and the result would be 111. Or if we started with 10001, then the middle would be the center 0 and the result would be 10101.
When i say wrapping i also mean adding bits as if the bit array was a circle so if we had 00100010 representing the positions with letters:
00100010
hgfedcba
So we have True bits at b and f we would put a middle bit between b and f going left to right at d but also going right to left, wrapping around and putting it at h resulting in:
10101010
hgfedcba
I understand this isn't a usual problem.
Are there known tricks to do things like this without loops?

Related

Error with two credit card numbers. Identifies the number as the wrong credit card type

These are my current errors, I think I did something wrong with the maths but everything I tried didn't work.
Ps: Sorry if my question's formatting is bad, first time using stackflow.
:) credit.c exists
:) credit.c compiles
:) identifies 378282246310005 as AMEX
:) identifies 371449635398431 as AMEX
:) identifies 5555555555554444 as MASTERCARD
:) identifies 5105105105105100 as MASTERCARD
:) identifies 4111111111111111 as VISA
:) identifies 4012888888881881 as VISA
:) identifies 4222222222222 as VISA
:) identifies 1234567890 as INVALID
:) identifies 369421438430814 as INVALID
:) identifies 4062901840 as INVALID
:) identifies 5673598276138003 as INVALID
:( identifies 4111111111111113 as INVALID
expected "INVALID\n", not "VISA\n"
:( identifies 4222222222223 as INVALID
expected "INVALID\n", not "VISA\n"
#include <cs50.h>
#include <math.h>
// Prompt user for credit card number
int main(void)
{
long credit_card, credit_number;
do
{
credit_card = get_long("Enter credit card number: ");
}
while (credit_card < 0);
credit_number = credit_card;
// Calculate total number of digits
int count = (credit_number == 0) ? 1 : (log10(credit_number) + 1);
int summation = 0;
while (credit_number == 0)
{
int x = credit_number % 10; summation += x;
int y = 2 * ((credit_number / 10) % 10);
int r = (y % 10) + floor((y / 10) % 10); summation += r; credit_number /= 100;
}
string card;
// Identify which card type you get after inputing your credit card number
int test = cc / pow(10, count - 2);
if ((count == 13 || count == 16) && test / 10 == 4)
{
card = "VISA";
}
else if (count == 16 && test >= 51 && test <= 55)
{
card = "MASTERCARD";
}
else if (count == 15 && (test == 34 || test == 37))
{
card = "AMEX";
}
else
{
card = "INVALID";
}
// Final verification
if (sum % 10 == 0)
{
printf("%s\n", card);
}
else
{
printf("INVALID\n");
}
}```
Your algorithm is maybe not fully correct. I would therefore propose a different approach. You can look at each single digit in a loop. And, you can also do the whole checksum calculation in one step.
I will show you how to do and explain the algorithm behind it.
BTW. Chosing the right algorithm is always the key for success.
So, first we need to think on how we can extract digits from a number. This can be done in a loop by repeating the follwoing steps:
Perform a modulo 10 division to get a digit
Do a integer division by 10
Repeat
Let us look at the example 1234.
Step 1 will get the 4 -- (1234 % 10 = 4)
Step 2 will convert original number into 123 -- (1234 / 10 = 123)
Step 1 will get the 3 -- (123 % 10 = 3)
Step 2 will convert the previous number into 12 -- (123 / 10 = 12)
Step 1 will get the 2 -- (12 % 10 = 2)
Step 2 will convert the previous number into 1 -- (12 / 10 = 1)
Step 1 will get the 1 -- (1 % 10 = 1)
Step 2 will convert the previous number into 0 -- (1 / 10 = 0)
Then the loop stops. Additionally we can observe that the loop stops, when the resulting divided becomes 0. And, we see addtionally that the number of loop executions is equal to the number of digits in the number. But this is somehow obvious.
OK, then let us look, what we learned so far
while (creditCardNumber > 0) {
unsigned int digit = creditCardNumber % 10;
creditCardNumber /= 10;
++countOfDigits;
}
This will get all digits and count them.
Good. Lets go to next step.
For later validation and comparison purpose we need to get the most significant digit (the first digit) and the second most significant digit (the second digit) of the number.
For this, we define 2 variables which will hold the number. We simply assign the current evaluated digit (and override it in each loop execution) to the "mostSignificantDigit". At the end of the loop, we will have it in our desired variable.
For the "secondMostSignificantDigit" we will simple copy the "old" or "previous" value of the "mostSignificantDigit", before assigning a new value to "mostSignificantDigit". With that, we will always have both values available.
The loop looks now like this:
while (creditCardNumber > 0) {
const unsigned int digit = creditCardNumber % 10;
secondMostSignificantDigit = mostSignificantDigit;
mostSignificantDigit = digit;
creditCardNumber /= 10;
++countOfDigits;
}
OK, now we come to the maybe more complex part. The cheksum. The calculation method is.
Start with the least significant (the last) digit
Do not multiply the digit, which is equivalent with multiplying it with 1, and add it to the checksum
Goto the next digit. Multiply it by 2. If the result is greater than 10, then get again the single digits and add both digits to the checksum
Repeat
So, the secret is, to analyze the somehow cryptic specification, given here. If we start with the last digit, we do not multiply it, the next digit will be multiplied, the next not and so on and so on.
To "not multiply" is the same as multiplying by 1. This means: In the loop we need to multiply alternating with 1 or with 2.
How to get alternating numbers in a loop? The algorithm for that is fairly simple. If you need alternating numbers, lets say, x,y,x,y,x,y,x..., Then, build the sum of x and y and perform the subtratcion "value = sum - value". Example:
We need alternating values 1 and 2. The sum is 3. To get the next value, we subtract the current value from the sum.
initial value = 1
sum = 3
current value = initial value = 1
next value = 3 - 1 = 2. Current value = 2
next value = 3 - 2 = 1. Current value = 1
next value = 3 - 1 = 2. Current value = 2
next value = 3 - 2 = 1. Current value = 1
next value = 3 - 1 = 2. Current value = 2
next value = 3 - 2 = 1. Current value = 1
. . .
Good, now we understand, how to make alternating values.
Next, If we multiply a digit with 2, then the maximum result maybe a 2 digit value. We get the single digits with a modulo and an integer division by 10.
And, now important, it does not matter, if we multiply or not, because, if we do not multiply, then the upper digit will always be 0. And this will not contribute to the sum.
With all that, we can always do a multiplication and always split the result into 2 digits (many of them having the upper digit 0).
The result will be:
checkSum += (digit * multiplier) % 10 + (digit * multiplier) / 10;
multiplier = 3 - multiplier;
An astonishingly simple formula.
Next, if we know C or C++ we also know that a multiplication with 2 can be done very efficiently with a bit shift left. And, additionally, a "no-multiplication" can be done with a bit shift 0. That is extremely efficient and faster than multiplication.
x * 1 is identical with x << 0
x * 2 is identical with x << 1
For the final result we will use this mechanism, alternate the multiplier between 0 and 1 and do shifts.
This will give us a very effective checksum calculation.
At the end of the program, we will use all gathered values and compare them to the specification.
Thsi will lead to:
int main() {
// Get the credit card number. Unfortunately I do not know CS50. I use the C++ standard iostream lib.
// Please replace the following 4 lines with your CS50 equivalent
unsigned long long creditCardNumber;
std::cout << "Enter credit card number: ";
std::cin >> creditCardNumber;
std::cout << "\n\n";
// We need to count the number of digits for validation
unsigned int countOfDigits = 0;
// Here we will calculate the checksum
unsigned int checkSum = 0;
// We need to multiply digits with 1 or with 2
unsigned int multiplier = 0;
// For validation purposes we need the most significant 2 digits
unsigned int mostSignificantDigit = 0;
unsigned int secondMostSignificantDigit = 0;
// Now we get all digits from the credit card number in a loop
while (creditCardNumber > 0) {
// Get the least significant digits (for 1234 it will be 4)
const unsigned int digit = creditCardNumber % 10;
// Now we have one digit more. In the end we will have the number of all digits
++countOfDigits;
// Simply remember the most significant digits
secondMostSignificantDigit = mostSignificantDigit;
mostSignificantDigit = digit;
// Calculate the checksum
checkSum += (digit << multiplier) % 10 + (digit << multiplier) / 10;
// Multiplier for next loop
multiplier = 1 - multiplier;
creditCardNumber /= 10;
}
// Get the least significant digit of the checksum
checkSum %= 10;
// Validate all calculated values and show the result
if ((0 == checkSum) && // Checksum must be correct AND
(15 == countOfDigits) && // Count of digits must be correct AND
((3 == mostSignificantDigit) && // Most significant digits must be correct
((4 == secondMostSignificantDigit) || (7 == secondMostSignificantDigit)))) {
std::cout << "AMEX\n";
}
else if ((0 == checkSum) && // Checksum must be correct AND
(16 == countOfDigits) && // Count of digits must be correct AND
((5 == mostSignificantDigit) && // Most significant digits must be correct
((secondMostSignificantDigit > 0) && (secondMostSignificantDigit < 6)))) {
std::cout << "MASTERCARD\n";
}
else if ((0 == checkSum) && // Checksum must be correct AND
((16 == countOfDigits) || (13 == countOfDigits)) && // Count of digits must be correct AND
((4 == mostSignificantDigit))) { // Most significant digit must be correct
std::cout << "VISA\n";
}
else {
std::cout << "INVALID\n";
}
return 0;
}
What we learn with this example, is integer division and modulo division and the smart usage of the identity element for binary operations.
In case of questions, please ask
Just to be complete, I will show you a C++ solution, based on a std::string and using modern C++ elements and algorithms.
For example, the whole checksum calculation will be done with one statement. The whole program does not contain any loop.
#include <iostream>
#include <string>
#include <regex>
#include <numeric>
int main() {
// ---------------------------------------------------------------------------------------------------
// Get user input
// Inform user, what to do. Enter a credit card number. We are a little tolerant with the input format
std::cout << "\nPlease enter a credit card number:\t";
// Get the number, in any format from the user
std::string creditCardNumber{};
std::getline(std::cin, creditCardNumber);
// Remove the noise, meaning, all non digits from the credit card number
creditCardNumber = std::regex_replace(creditCardNumber, std::regex(R"(\D)"), "");
// ---------------------------------------------------------------------------------------------------
// Calculate checksum
unsigned int checksum = std::accumulate(creditCardNumber.rbegin(), creditCardNumber.rend(), 0U,
[multiplier = 1U](const unsigned int sum, const char digit) mutable -> unsigned int {
multiplier = 1 - multiplier; unsigned int value = digit - '0';
return sum + ((value << multiplier) % 10) + ((value << multiplier) / 10); });
// We are only interested in the lowest digit
checksum %= 10;
// ---------------------------------------------------------------------------------------------------
// Validation and output
if ((0 == checksum) && // Checksum must be correct AND
(15 == creditCardNumber.length()) && // Count of digits must be correct AND
(('3' == creditCardNumber[0]) && // Most significant digits must be correct
(('4' == creditCardNumber[1]) || ('7' == creditCardNumber[1])))) {
std::cout << "AMEX\n";
}
else if ((0 == checksum) && // Checksum must be correct AND
(16 == creditCardNumber.length()) && // Count of digits must be correct AND
(('5' == creditCardNumber[0]) && // Most significant digits must be correct
((creditCardNumber[1] > '0') && (creditCardNumber[1] < '6')))) {
std::cout << "MASTERCARD\n";
}
else if ((0 == checksum) && // Checksum must be correct AND
((16 == creditCardNumber.length()) || (13 == creditCardNumber.length())) && // Count of digits must be correct AND
(('4' == creditCardNumber[0]))) { // Most significant digit must be correct
std::cout << "VISA\n";
}
else {
std::cout << "INVALID\n";
}
return 0;

Contiguous sub sequence with max success rate in a sequence given a minimum sub sequence length

I'm trying to solve an algorithmic problem where the premises revolves around an input sequence that consists of 0s and 1s along with a minimum length l for the output subsequence. The problem asks for the subsequence which has the highest rate of 1s (number of ones in the subsequence divided by the length of the subsequence). Further background and sample input/output to the problem can be found here.
I have come up with a solution that passes all tests except for the last one and I am trying to figure out what my current implementation is lacking. My approach is to use a dynamically resizeable sliding window while storing the maximum rate of the sliding window along with the length of that maximum rated window. I think the way that I'm moving (growing and shrinking) my window is the problem, but I'm having trouble figuring out what to change.
This is how I move my window:
static void max_rate(long min_len, string sequence) {
long left_window = 0, right_window = min_len - 1;
long best_left = 0, best_len = 0, most_ones = 0;
long double best_success_rate = -1;
for (;;) {
auto tmp = sequence.substr(left, right - left + 1);
long n_ones = count_ones(tmp);
long double success_rate = (long double)n_ones / (long double)tmp.length();
if (success_rate >= best_success_rate) {
best_success_rate = success_rate;
best_left = left;
best_len = right - left + 1;
most_ones = n_ones;
}
// Window sliding starts here
bool can_move_right = (right + 1) < (long)sequence.length();
bool can_move_left = (right - left + 1 - 1) >= min_len;
if (can_move_right && sequence.at(right + 1) == '1') {
++(right);
} else if (can_move_right && sequence.at(right + 1) == '1') {
++(right);
} else if (can_move_left && (sequence.at(left + 1) == '0')) {
++left;
} else if (can_move_right) {
++(right);
} else {
break;
}
cout << best_left + 1 << " ";
cout << best_len << endl;
I'm basically checking:
Grow the window if you can increase the rate
Otherwise, if possible (considering our minimum size requirement), shrink the window if you can increase the rate
Otherwise, if possible (-), shrink the window
Otherwise, if possible (we are not at the end of the sequence) grow the window
I must be missing something here I think
According to the code you posted, for input
8, "0011101011"
the sequence would seem to be
0 0 1 1 1 0 1 0 1 1
l r
l r
l r
l r
which gives us:
zero-based index 1, interval length 9
and ratio 6 / 9 = 0.6666666666666666
but the correct answer is
ratio 0.75
zero-based index 2, interval length 8

Given a huge integer number as a string, check if its a power of 2

The number is huge (cannot fit in the bounds of unsigned long long int in C++). How do we check?
There is a solution given here but it doesn't make much sense.
The solution here tries to repeatedly divide the large number (represented as a string) by 2 but I'm not sure I understand how the result is reached step by step.
Can someone please explain this or propose a better solution?
We cannot use any external libraries.
This is the sample code:
int isPowerOf2(char* str)
{
int len_str = strlen(str);
// sum stores the intermediate dividend while
// dividing.
int num = 0;
// if the input is "1" then return 0
// because 2^k = 1 where k >= 1 and here k = 0
if (len_str == 1 && str[len_str - 1] == '1')
return 0;
// Divide the number until it gets reduced to 1
// if we are successfully able to reduce the number
// to 1 it means input string is power of two if in
// between an odd number appears at the end it means
// string is not divisible by two hence not a power
// of 2.
while (len_str != 1 || str[len_str - 1] != '1') {
// if the last digit is odd then string is not
// divisible by 2 hence not a power of two
// return 0.
if ((str[len_str - 1] - '0') % 2 == 1)
return 0;
// divide the whole string by 2. i is used to
// track index in current number. j is used to
// track index for next iteration.
for (int i = 0, j = 0; i < len_str; i++) {
num = num * 10 + str[i] - '0';
// if num < 2 then we have to take another digit
// to the right of A[i] to make it bigger than
// A[i]. E. g. 214 / 2 --> 107
if (num < 2) {
// if it's not the first index. E.g 214
// then we have to include 0.
if (i != 0)
str[j++] = '0';
// for eg. "124" we will not write 064
// so if it is the first index just ignore
continue;
}
str[j++] = (int)(num / 2) + '0';
num = (num) - (num / 2) * 2;
}
str[j] = '\0';
// After every division by 2 the
// length of string is changed.
len_str = j;
}
// if the string reaches to 1 then the str is
// a power of 2.
return 1;
}
I'm trying to understand the process in the while loop. I know there are comments but they arent really helping me glean through the logic.
Let's start by figuring out how to halve a "string-number". We'll start with 128 as an example. You can halve each digit in turn (starting from the left), keeping in mind that an odd number affects the digit on the right(a). So, for the 1 in 128, you halve that to get zero but, because it was odd, five should be kept in storage to be added to the digit on its right (once halved):
128
v
028
Then halve the 2 as follows (adding back in that stored 5):
028
v
018
v
068
Because that wasn't odd, we don't store a 5 for the next digit so we halve the 8 as follows:
068
v
064
You can also make things easier then by stripping off any leading zeros. From that, you can see that it correctly halves 128 to get 64.
To see if a number is a power of two, you simply keep halving it until you reach exactly 1. But, if at any point you end up with an odd number (something ending with a digit from {1, 3, 5, 7, 9}, provided it's not the single-digit 1), it is not a power of two.
By way of example, the following Python 3 code illustrates the concept:
import re, sys
# Halve a numeric string. The addition of five is done by
# Choosing the digit from a specific set (lower or upper
# digits).
def half(s):
halfS = '' # Construct half value.
charSet = '01234' # Initially lower.
for digit in s: # Digits left to right.
if digit in '13579': # Select upper for next if odd.
nextCharSet = '56789'
else:
nextCharSet = '01234' # Otherwise lower set.
halfS += charSet[int(digit) // 2] # Append half value.
charSet = nextCharSet # And prep for next digit.
while halfS[0] == '0': # Remove leading zeros.
halfS = halfS[1:]
return halfS
# Checks for validity.
if len(sys.argv) != 2:
print('Needs a single argument')
sys.exit(1)
num = sys.argv[1]
if not re.match('[1-9][0-9]*', num):
print('Argument must be all digits')
sys.exit(1)
print(num)
while num != '1':
if num[-1:] in '13579':
print('Reached odd number, therefore cannot be power of two')
sys.exit(0)
num = half(num)
print(num)
print('Reached 1, was therefore power of two')
Running that with various (numeric) arguments will show you the process, such as with:
pax$ python ispower2.py 65534
65534
32767
Reached odd number, therefore cannot be power of two
pax$ python ispower2.py 65536
65536
32768
16384
8192
4096
2048
1024
512
256
128
64
32
16
8
4
2
1
Reached 1, was therefore power of two
(a) Take, for example, the number 34. Half of the 3 is 1.5 so the 1 can be used to affect that specific digit position but the "half" left over can simply be used by bumping up the digit on the right by five after halving it. So the 4 halves to a 2 then has five added to make 7. And half of 34 is indeed 17.
This solution does work only for numbers which are not too large i.e. fits in the range of unsigned long long int.
Simpler C++ solution using bitmanipulation for small numbers :-
int power(string s) {
// convert number to unsigned long long int
// datatype can be changed to long int, int as per the requirement
// we can also use inbuilt function like stol() or stoll() for this
unsigned long long int len = s.length();
unsigned long long int num = s[0]-'0';
for(unsigned long long int i = 1; i<len; i++)
num = (num*10)+(s[i]-'0');
if(num == 1)
return 0;
//The powers of 2 have only one set bit in their Binary representation
//If we subtract 1 from a power of 2 what we get is 1s till the last unset bit and if we apply Bitwise AND operator we should get only zeros
if((num & (num-1)) == 0)
return 1;
return 0;
}
A bit better solution that I could code in Java, which doesn't use any fancy object like BigInteger. This approach is same as simple way of performing division. Only look out for remainder after each division. Also trim out the leading zeroes from the quotient which becomes new dividend for next iteration.
class DivisionResult{
String quotient;
int remainder;
public DivisionResult(String q, int rem){
this.quotient = q;
this.remainder = rem;
}
}
public int power(String A) {
if (A.equals("0") || A.equals("1")) return 0;
while (!A.equals("1")){
DivisionResult dr = divideByTwo(A);
if (dr.remainder == 1) return 0;
A = dr.quotient;
}
return 1;
}
public DivisionResult divideByTwo(String num){
StringBuilder sb = new StringBuilder();
int carry = 0;
for (int i = 0;i < num.length(); i++){
int divisibleNum = carry*10 + (num.charAt(i) - '0');
carry = divisibleNum%2;
sb.append(divisibleNum/2);
}
return new DivisionResult(sb.toString().replaceAll("^0+(?!$)", ""), carry);
}

Understanding the given snippet on bit reversal

I found this snippet on 'codefights' submitted by a programmer. My solution to the problem was 30 lines, whereas this is just a beauty.
But I am not able to understand the logic.
Can anyone explain this.
int mirrorBits(int a) {
int r = 0;
for (; a; a >>= 1)
r = r << 1 | a & 1;
return r;
}
input a = 8; output : 1
First of all, there is a very good StackOverflow answer here:
Most Efficient Algorithm for Bit Reversal ( from MSB->LSB to LSB->MSB) in C
The algorithm makes use of
>> ... binary shift right (100b >> 1 == 10b)
<< ... binary shift left (100b << 1 == 1000b
| .... binary or (100b | 10b == 110b)
& .... binary and (111b & 100b == 100b)
The for loop shifts a to the right until all bits have fallen out of a.
Imagine you start with a = 101101 then a >>= 1 does the following:
At the end of loop 1: a == 10110
At the end of loop 2: a == 01011
At the end of loop 3: a == 00101
At the end of loop 4: a == 00010
At the end of loop 5: a == 00001
At the end of loop 6: a == 00000 (condition fails -> loop ends)
The body of the loop shifts b one bit right, uses & to mask the last bit of a and adds it as last digit to b. The or can be used to add the last digit because << inserts 0 for all "new" bits.
Imagine you start with a = 101101
loop 1: a = 101101, r = 0 => 01
loop 2: a = 010110, r = 01 => 010
loop 3: a = 001011, r = 010 => 0101
loop 4: a = 000101, r = 0101 => 01011
loop 5: a = 000010, r = 01011 => 010110
loop 6: a = 000001, r = 010110 => 0101101
In detail the inner loop #3 does the following:
(a is 001011 and r is 010)
r << 1 changes r from 010 to 0100. The last digit is the inserted 0.
a & 1 masks the current last bit from a (the 1 in 001011)
now we have (0100 | 1) which has the result 0101.
Warning: This algorithm is not really mirroring the bits, because you do not get the original value if you apply the algorithm to the result.
If you need a mirrored 32-bit unsigned integer you have to loop 32 times independently of the value of a:
unsigned int r = 0;
unsigned int a = 12345;
for(int i = 0; i < 32; ++i)
{
r = (r << 1) | (a & 1);
a >>= 1;
}
If you apply this algorithm twice, you should get the original value.

Long Hand Multiplication In C++

I am trying to implement Long Hand Multiplication method for 8 bit binary numbers stored in two arrays BeforeDecimal1 and BeforeDecimal2. The problem is I always get the wrong result. I tried to figure out the issue but couldn't do it. Here is the code:
This is a much more refined code then previous one. It is giving me result but the result is not correct.
int i=0,carry=0;
while(true)
{
if(BeforeDecimal2[i]!=0)
for(int j=7;j>=0;j--)
{
if(s[j]==1 && BeforeDecimal1[j]==1 && carry==0)
{
cout<<"Inside first, j= "<<j<<endl;
carry=1;
s[j]=0;
}
else
if(s[j]==1 && BeforeDecimal1[j]==0 && carry==1)
{
cout<<"Inside second, j= "<<j<<endl;
carry=1;
s[j]=0;
}
else
if(s[j]==0 && BeforeDecimal1[j]==0 && carry==1)
{
cout<<"Inside third, j= "<<j<<endl;
carry=0;
s[j]=1;
}
else
if(s[j]==0 && BeforeDecimal1[j]==0 && carry==0)
{
cout<<"Inside fourth, j= "<<j<<endl;
carry=0;
s[j]=0;
}
else
if(s[j]==0 && BeforeDecimal1[j]==1 && carry==0)
{
cout<<"Inside fifth, j= "<<j<<endl;
carry=0;
s[j]=1;
}
else
if(s[j]==1 && BeforeDecimal1[j]==1 && carry==1)
{
//cout<<"Inside fifth, j= "<<j<<endl;
carry=1;
s[j]=1;
}
else
if(s[j]==1 && BeforeDecimal1[j]==0 && carry==0)
{
//cout<<"Inside fifth, j= "<<j<<endl;
carry=0;
s[j]=1;
}
else
if(s[j]==0 && BeforeDecimal1[j]==1 && carry==1)
{
//cout<<"Inside fifth, j= "<<j<<endl;
carry=1;
s[j]=0;
}
}
for(int h=7;h>=0;h--)
{
if(h==0)
{
BeforeDecimal1[0]=0; // that is inserting zeros from the right
}
else
{
BeforeDecimal1[h]=BeforeDecimal1[h-1];
BeforeDecimal1[h-1]=0;
}
}
if(i==3)
break;
i++;
}
Regards
Maybe it would be easiest to back up and start with 8-bit binary numbers stored as 8-bit binary numbers. Much like when we do decimal multiplication, we start with a number of digits. We take the values of multiplying by those individual digits, and add them together to get the final result. The difference (or one obvious difference) is this since we're working in binary, all our digits represent powers of two, so we can get each intermediate result by simply bit shifting the input.
Since it's binary, we have only two possibilities for each digit: if it's a 0, then we need to add 0 times the other number shifted left the appropriate number of places. Obviously, 0 time whatever is still 0, so we simply do nothing in this case. The other possibility is that we have a 1, in which case we add 1 times the other number shifted left the appropriate number of places.
For example, let's consider something like 17 x 5, or (in binary) 10001 x 101.
10001
101
------
10001
+ 1000100
--------
= 1010101
Converting that to something more recognizable, we get 0x55, or 85d.
In code, that process comes out fairly short and simple. Start with a result of 0. Check whether the least significant bit in one operand is set. If so, add the other operand to the result. Shift the one operand right a bit and the other left a bit, and repeat until the operand you're shifting to the right equals 0:
unsigned short mul(unsigned char input1, unsigned char input2) {
unsigned short result = 0;
while (input2 != 0) {
if (input2 & 1)
result += input1;
input1 <<= 1;
input2 >>= 1;
}
return result;
}
If you want to deal with signed numbers, it's generally easiest to figure up the sign of the result separately, and do the multiplication on the absolute values.
You have problem in following lines of code
if(reverse==0)
{
totalReverse=totalReverse-1;
reverse=totalReverse;
}
after some iterations of the inner for loop (index j based) the values of reverse goes should goes to negative and when reverse less than 3 then there should be exception thrown.
Are you running this code without exception handling?
to me this smells like shift and add. is there a requirement that you may use operations simulating logical gates only?
for your full adder you have 3 inputs s(s[j]), b(BeforeDecimal1[j]), c(carry), and two outputs ns(new s[j]), nc (new carry)
the table looks like this
s b c ns nc
0 0 0 0 0 handled in v5 clause 4
0 0 1 1 0 handled in v5 clause 3
0 1 0 1 0 handled in v6 clause 5
0 1 1 0 1
1 0 0 1 0
1 0 1 0 1 handled in v5 clause 2
1 1 0 0 1 handled in v5 clause 1
1 1 1 1 1
your code covers only 4 (now 5) of these 8 clauses
to avoid the ugly if-else-if rake i recommend to use temporary result variables (carry and s still valid in the next if clause)
when you analyze the table you could also do (pseudo bool notation)
nc = s && b || s && c || b && c;
ns = s XOR b XOR c; // there is no XOR in C++: axb = a&&!b || !a&&b
arithmetic notation
nc = (s + b + c) / 2;
ns = (s + b + c) % 2;
// [...]
for(int j=7;j>=0;j--)
{
// start changed code
const int sum = s[j] + BeforeDecimal1[j] + carry;
s[j]=sum % 2;
carry=sum / 2;
// end changed code
}
// [...]
here is a nice simulation of your problem Sequential Multiplication
Unless your requirement precisely states otherwise, which isn't clear from your question or any of your comments so far, it is not necessary to process arrays of bits. Arrays of bytes are much more efficient in both space and time.
You don't need this exhaustive explosion of cases either. The only special case is where either operand is zero, i.e. a[i]|b[i] == 0, when
result[i] = carry;
carry = 0;
All other cases can be handled by:
result[i] = a[i]*b[i]+carry;
carry = (result[i] >>> 8) & 1;
result[i] &= 0xff;
I don't see much point in the names BeforeDecimal1 and BeforeDecimal2 either.