I should find result of "1001011 AND 1001010=1001010"...How can I find the result of this process in C programmin without using & symbol? Thanks for your help...
You can perform this operation one bit at a time and get the result using the multiplication operator:
unsigned and(unsigned a, unsigned b) {
unsigned mul = 1, res = 0;
while ((a != 0) * (b != 0)) {
res += mul * (a % 2) * (b % 2);
a /= 2;
b /= 2;
mul *= 2;
}
return res;
}
For a more efficient approach, use the Boolean algebraic equivalence:
unsigned and(unsigned a, unsigned b) { return ~(~a | ~b); }
This sounds a bit like homework, so...
The truth table for AND is:
0 AND 0 = 0
0 AND 1 = 0
1 AND 0 = 0
1 AND 1 = 1
The truth table for OR is:
0 OR 0 = 0
0 OR 1 = 1
1 OR 0 = 1
1 OR 1 = 1
What happens if you swap all the 0's and 1's in the bottom table?
NOT 0 OR NOT 0 = ?
NOT 0 OR NOT 1 = ?
NOT 1 OR NOT 0 = ?
NOT 1 OR NOT 1 = ?
I hope this helps, without giving the game away completely!
Related
I have been trying to translate this code to put it in simple terms to understand but can't quite get it.
Can someone help me understand it better and why the next line would they want to divide by 16?
char r = (c+n1+n2)>=16 ?
((c+n1+n2)-16+'0') :
((c+n1+n2)>9?((c+n1+n2)+55):(c+n1+n2)+'0');
c = (c+n1+n2)/16;
the lines above this are a while loop to print multiple numbers and are:
int i=s1-1, j=s2-1, c=0, k=0;// sets up for the calculations -1
// for the s1 and s2 because you do not want null character included here
// k is the number of places we use for addition
printf("COL d d c\n");
while(i>=0 || j>=0){
int n1 = i<0?0:num1[i]-'0';// is converting from the character representation
// of a number to the actual integer value of the same digit if not 0
int n2 = j<0?0:num2[j]-'0';
char r = (c+n1+n2)>=16 ?
((c+n1+n2)-16+'0') :
((c+n1+n2)>9?((c+n1+n2)+55):(c+n1+n2)+'0');
c = (c+n1+n2)/16;
printf("%3d : %d+%d+%d = %c\n", k, n1, n2, c, r);
i--;
j--;
k++;
}
It seems, the function above was intended to add two hex strings. I believe this, because the line in question encodes hex characters and the overflow, that occurs when adding two digits is treated in a way, that makes only sense if the digits are treated as 4 bit digts (hex digits). E.g. because of the division by 16.
If I am right, the hex decoding contains a bug, while the hex encoding for outputting the result seems almost correct. Almost, because if I got it right, the original version will not be able to calculate string additions like "00F" + "00F" correctly (see last output below).
It seems, as if even the original author was overwhelmed by his code.
Here is a version, that should do, what the original author intended to do:
void string_add(char num1[], char num2[], int s1, int s2) {
int i=s1-1, j=s2-1, c=0, k=0;// sets up for the calculations -1 for the s1 and s2 because you do not want null character included here
int z=0;
// k is the number of places we use for addition
printf("COL d d c\n");
while(i>=0 || j>=0){
/*
* the following lines represent the expressions
* int n1 = i<0?0:num1[i]-'0';// is converting from the character representation of a number to the actual integer value of the same digit if not 0
* int n2 = j<0?0:num2[j]-'0';
* I added the conversion of hex digits in the range A-F
*/
int n1, n2= 0;
char r;
if(i>=0) {
n1= num1[i];
if(n1>='A') {
n1-= 'A'-10;
} else {
n1-= +'0';
}
}
if(j>=0) {
n2= num2[j];
if(n2>='A') {
n2-= 'A'-10;
} else {
n2-= '0';
}
}
/*
* the following code is, what the line
* char r = (c+n1+n2)>=16?((c+n1+n2)-16+'0'):((c+n1+n2)>9?((c+n1+n2)+55):(c+n1+n2)+'0');
* originally did (I also do a partial calculation of the line
* c = (c+n1+n2)/16;
* to avoid repeating the term
*/
c= c+n1+n2;
r= c&15; // only take the lower 4 bits (ignore overflow bits)
z|= r << (4*k);
// construct the binary representation (shift the 4 bits into position and use bitwise or to add them to z)
if(r>9) {
r+= 'A'-10; // produces chars in range A-F = (ascii('G')-16+c
} else {
r+= '0'; // produces chars in range 0-9 if no overflow occurs
}
/*
* now just do the /16 part of
* c = (c+n1+n2)/16;
*/
c/= 16;
printf("%3d : %d+%d+%d = %c\n", k, n1, n2, c, r);
i--;
j--;
k++;
}
printf("%d\n", z);
}
void main(void) {
char s1[]= "0100";
char s2[]= "0B01";
string_add(s1, s2, 4, 4);
}
Tests (first output is from the version above, second from the original version):
"0005"+"0005"=
COL d d c
0 : 5+5+0 = A
1 : 0+0+0 = 0
2 : 0+0+0 = 0
3 : 0+0+0 = 0
10
COL d d c
0 : 5+5+0 = A
1 : 0+0+0 = 0
2 : 0+0+0 = 0
3 : 0+0+0 = 0
"9989"+"0987"=
COL d d c
0 : 9+7+1 = 0
1 : 8+8+1 = 1
2 : 9+9+1 = 3
3 : 9+0+0 = A
41744
COL d d c
0 : 9+7+1 = 0
1 : 8+8+1 = 1
2 : 9+9+1 = 3
3 : 9+0+0 = A
"000F"+"000F"=
COL d d c
0 : 15+15+1 = E
1 : 0+0+0 = 1
2 : 0+0+0 = 0
3 : 0+0+0 = 0
30
COL d d c
0 : 22+22+2 = L
1 : 0+0+0 = 2
2 : 0+0+0 = 0
3 : 0+0+0 = 0
The last output seems suspicuous. Was this really intended?
The code seems to perform the addition of 2 numbers stored as hexadecimal encoded strings. It is obfuscated in silly ways. Here is how to improve readability:
white space should be used wisely to make the logic more obvious: typically insert a space character on both sides of binary operators, between keywords and the corresponding ( and before the { opening a block.
the magic constant 55 should be replaced with 'A' - 10, making it more evident that the code performs a conversion from a numeric value to a hexadecimal digit character.
intermediary values should be computed and stored into aptly named local variables.
comments can be used for non obvious steps.
The code seems incorrect:
c > 0 should be tested too to account for possible overflow on the most significant digit.
conversion from hex should be performed when reading digits from the num1 and num2 strings, converting digits A through F to the values 10 to 15.
the resulting digit would be incorrect if c + n1 + n2 >= 26
Here is an attempt at fixing the code:
// s1 is the length of hex encoded string num1
// s2 is the length of hex encoded string num2
int carry = 0;
int i = s1, j = s2, k = 0;
// k is the number of places we use for addition
printf("COL d d c\n");
while (i > 0 || j > 0 || carry > 0) {
// get the digit values from num1 and num2
char c1 = i == 0 ? '0' : num1[--i];
char c2 = j == 0 ? '0' : num2[--j];
int d1 = c1 <= '9' ? c1 - '0' : c1 - 'A' + 10;
int d2 = c2 <= '9' ? c2 - '0' : c2 - 'A' + 10;
int digit = carry + d1 + d2;
carry = digit >> 4;
digit %= 15;
char r = digit > 9 ? (digit - 10 + 'A') : (digit + '0');
printf("%3d : %d+%d+%d = %c\n", k, d1, d2, carry, r);
k++;
}
I am trying to get all possible combinations of a char*. This string consits of four values: two numbers and two different letters. For example:
char *text = "01ab";
There should be
so
different combinations for my example string, which seems to be true (done by hand):
Combinations for values: 0, 1, a, b:
0 0 a b 1 1 a b a 0 0 b b 0 0 a
0 0 b a 1 1 b a a 0 1 b b 0 1 a
0 1 a b 1 0 a b a 0 b 0 b 0 a 0
0 1 b a 1 0 b a a 0 b 1 b 0 a 1
0 a 0 b 1 a 1 b a 1 b 0 b 1 0 a
0 a 1 b 1 a 0 b a 1 b 1 b 1 1 a
0 a b 0 1 a b 1 a 1 0 b b 1 a 0
0 a b 1 1 a b 0 a 1 1 b b 1 a 1
0 b 0 a 1 b 1 a a b 0 0 b a 0 0
0 b 1 a 1 b 0 a a b 0 1 b a 0 1
0 b a 0 1 b a 1 a b 1 0 b a 1 0
0 b a 1 1 b a 0 a b 0 0 b a 1 1
My approach would be the same as the one I did by hand:
get all combinations with the first index of text at the start, then all combinations of the second index of text and so on. So something like this:
void printPasswordCombinations()
{
char *all_values = "01ab";
int len = strlen(all_values);
char *tmp_pwd = malloc(sizeof(len) * sizeof(char));
for(int i=0 ; i<len ; i++)
{
tmp_pwd[0] = all_values[i];
/* len-1, since the first index is already set. */
for(int j=0 ; j<len-1 ; j++)
{
}
}
printf("%s\n", tmp_pwd);
free(tmp_pwd);
}
Now I am a bit confused about how to continue after the first index of the combination. There are several examples for all combinations, but my problem seems to be a bit different, since my the numbers in the combination could be the same and only the letters have to be different.
How could I achieve to print all combinations to my console?
I implemented a function which calculates the amount of possible combinations, so just assume this is already done.
It would be nice if the algorithm would work for any amounts of numbers and letters, so for example all combinations of a text of lenght 6 with four different numbers and two different letters could also be calculated.
The language doesn't matter, any advice is appreciated.
Your problem can be solved by backtracking strategy. It will create all
possible combinations.
I know you want to remove duplicate combinations in case the two number are the same, to get rid of them, you can use a hash table to store generated combination, and then, each time you generate a new combination, bring it to the hash table to check if it was generated or not(if not, enter it to the hash table and print it out, ignore printing in vice versa). There for my pseudocode as follow (you can have a better way):
val characters = [/*4 characters*/]
val picked = [false,false,false,false]
val hashtable = empty
function genetate(string aCombin):
if aCombin.size == 4:
if(hashtable.contains(aCombin)):
//do nothing
else:
print(aCombin)
hashtable.add(aCombin)
for i in characters.size:
if(picked[i]==false):
picked[i]=true
aCombin.add(characters[i])
generate(aCombin)
picked[i]=false //backtrack
aCombine.popBack() //remove the last character
I used Javascript because it can run in browser and language doesn't matter. The below method uses recursion. Try it with '0123ab'.
'use strict';
const input = '01ab';
const reLetters = /[^0-9]/g;
const reDigits = /[0-9]/g;
const nLetters = input.replace(reDigits, '').length;
const nDigits = input.replace(reLetters, '').length;
const findComb = cur => {
if (cur.length === input.length)
return console.log(cur);
for (let l of input) {
if (l.match(reDigits)) {
if (cur.replace(reLetters, '').length === nDigits) continue;
} else {
if (cur.match(l) || cur.replace(reDigits, '').length === nLetters) continue;
}
findComb(cur + l);
}
}
findComb('');
Here is a version without "removing letters to count digits". it is about 20% more efficient. I used nodejs and '01234abc' as input to measure.
'use strict';
const input = '01ab';
const reLetters = /[^0-9]/g;
const reDigits = /[0-9]/g;
const maxLetters = input.replace(reDigits, '').length;
const maxDigits = input.replace(reLetters, '').length;
const findComb = (cur = '', nDigits = 0, nLetters = 0) => {
if (cur.length === input.length)
return console.log(cur);
for (let l of input) {
if (l.match(reDigits)) {
if (nDigits < maxDigits)
findComb(cur + l, nDigits + 1, nLetters);
} else {
if (cur.match(l)) continue;
if (nLetters < maxLetters)
findComb(cur + l, nDigits, nLetters + 1);
}
}
}
findComb();
Here it is without recursion. This is slowest of all, but can be improved.
'use strict';
const input = '01ab';
const reLetters = /[^0-9]/g;
const reDigits = /[0-9]/g;
const nLetters = input.replace(reDigits, '').length;
const nDigits = input.replace(reLetters, '').length;
let cur = '', l = undefined;
do {
l = input[input.indexOf(l) + 1];
if (l !== undefined) {
if (l.match(reDigits)) {
if (cur.replace(reLetters, '').length === nDigits) continue;
} else {
if (cur.match(l) ||
cur.replace(reDigits, '').length === nLetters) continue;
}
if (cur.length + 1 === input.length) {
console.log(cur + l);
} else {
cur = cur + l;
l = undefined;
}
} else {
l = cur[cur.length - 1];
cur = cur.slice(0, -1);
}
} while (cur != '' || l != undefined);
A recursive approach would be the easy way here.
Let's consider that you want to generate all strings with m letters, all of them distinct, taken from a letters[m] array, and n numbers, that can be repeated, taken from a numbers[N] array (n can be smaller, of same size of bigger than N, it does not really matter).
You can solve it this way then (pseudo code, C style):
void print_them_all(char *numbers, int nb_numbers_in_result, int n \
char *letters, bool *is_letter_used, int nb_letters_in_result, int m,
char *current_string){
if ((nb_numbers_in_result == n) && (nb_letters_in_result == m)){
// terminal case -> time to print the current string
printf("%s\n", current_string);
} else {
// string not completely built yet
// get the index where the next char will be added
current_index = nb_letters_in_result + nb_numbers_in_result;
if (nb_numbers_in_result < n){ // still possible to add a number
for (int i = 0; i < N; i++){
current_string[current_index] = numbers[i];
print_them_all(numbers, nb_numbers_in_result+1, n, \
letters, is_letter_used, nb_letters_in_result, m, \
current_string);
}
}
if (nb_letters_in_result < m){ // still possible to add a letter
for (int i = 0; i < m; i++) {
if (is_letter_used[i] == false){ // check the letter has not been added yet
// keep track that the letter has been added by 'marking' it
is_letter_used[i] = true;
// add it
current_string[i] = letters[i];
// recursive call
print_them_all(numbers, nb_numbers_in_result, n, \
letters, is_letter_used, nb_letters_in_result+1, m, \
current_string);
// now 'unmark' the letter
is_letter_used[i] = false;
}
}
}
}
}
To solve this kind of problem, the recursive approach is necessary. It works as follows:
if I have a string with k numbers in it already, k<n, then I can add any number to it, and I can continue (now my string will have k+1 numbers in it).
If I have a string with k letters in it already, k<m, then I can add any letter that was not added already (the array of booleans helps to make sure it is the case), and I can continue.
If my string is ready for print, print it.
The first call should be done with the boolean array initialized to false everywhere, and 0 for the values of nb_letters_in_result and nb_numbers_in_result, since you have not added any number or letter in your result string yet.
As for your result string, since you code in C, don't forget to allocate memory for it:
char *current_string = malloc((m+n+1) * sizeof(char));
and to null-terminate it:
current_string[m+n] = '\0';
I also found an interesting solution for my question.
Assume my example string 01ab.
First we want to create all combinations of the numbers 01 and the permutation of ab.
There are plenty examples of how to solves this.
So now we have all combinations of 01 and ab. I will call them producer combinations:
10 ab
01 ba
11
00
Now we want to combine all numbers with all letters but with the rule
The order of the numbers or letters must not be reserved for each combination
So if we combine 10 with ab we get:
10ab
1a0b
a10b
now we move b to the left side until it is about to swap its place with a, which is forbidden because of my rule. We do this for every combination:
10ab produces:
10ab
since b is already next to a.
1a0b produces:
1ab0
so we got one more combination.
a10b produces:
a1b0
ab10
so we got 2 more combinations.
Now we have all possible combinations for 01 and ab:
10ab
1a0b
a10b
1ab0
a1b0
ab10
Since our producer combinations contain 8 elements we have to do this step 8 times with all elements. The resulting combinations will always contain 6 elements like in my example which leads us to 48 elements in total as I calculated in my question.
Hello beautiful people,
I need a help with output of this program:
#include <stdio.h>
int main() {
int x,y;
scanf("%d %d",&x,&y);
int t = x^y;
int p = 0;
while (t > 0) {
p += t%2;
t /= 2;
}
printf("%d", p);
return 0;
}
I tried to write it down on paper and do some work by hand.
So i wrote this :
lets say for x = 2 and y = 4
first iteration:
p = 0 + 16mod2 which is equal to 0
t = 8
second iteration:
p = 0 + 8mod2 which is equal to 0
t = 4
third iteration:
p = 0 + 4mod2 which is equal to 0
t = 2
forth iteration:
p = 0 + 2mod2 which is equal to 0
t = 1
And output should be 0, but somehow when I run code I get 2.
Can someone help me out with this one please? And are there any other cases to consider, like what if x = 0, y = 0 or x and y are < 0 ?
The problem here, is that you assume that 2^4 == 16, when in fact, it is only 6, as the ^ operator, is actually an XOR.
You should be using
int t = pow(x, y)
int t = x^y;
Is not "x raised to the power of y". It's "x XOR y". T starts at 6 in your example.
As others have mentioned x^y is XOR operation, what you had in mind is :
#include <math.h>
....
int t = pow(x,y);
I have written this program to compute the maximum and minimum values of some of the data types in C, signed data types. The problem is that it is giving correct maximum values but incorrect minimum values, although i think my logic is correct. I know that there are better and efficient ways to get the result and i have implemented those too. Just need to know where the given code is going wrong.
What i have done?
I have implemented this using sizeof operator and then calculating the number of bits in the type and using that to calculate the max and min values.
Thanx in advance.......
/*
* Program to calculate the size of various data types like :
* int, long, short, char
*
* Version 3
*
* Problem with this version : Working correct only for maximum value of a
* data type.
*
* Author : Ravi Malik
*/
#include<stdio.h>
int main()
{ int i, i_prev ;
long l, l_prev ;
char c, c_prev ;
short s, s_prev ;
for( i = 0, i_prev = -1 ; i > i_prev ; i = i << 1 | 0x01 )
i_prev = i ;
for( l = 0, l_prev = -1 ; l > l_prev ; l = l << 1 | 0x01 )
l_prev = l ;
for( c = 0, c_prev = -1 ; c > c_prev ; c = c << 1 | 0x01 )
c_prev = c ;
for( s = 0, s_prev = -1 ; s > s_prev ; s = s << 1 | 0x01 )
s_prev = s ;
printf("MAX_INT:%d and MIN_INT:%d\n",i_prev,i);
printf("MAX_LONG:%ld and MIN_INT:%ld\n",l_prev,l);
printf("MAX_CHAR:%d and MIN_CHAR:%d\n",c_prev,c);
printf("MAX_SHORT:%hd and MIN_SHORT:%hd\n",s_prev,s);
return 0;
}
-1 means all the bits are set to 1. In 2's complement, minimum value is 1 followed by zero (only for signed data types).
In your case, you are getting -1 in i, l, c or s since it contains all the ones.
Initialize them with 1 and keep left shifting 1 only (no bitwise OR).
for( i = 1, i_prev = -1 ; i > i_prev ; i = i << 1)
i_prev = i ;
MIN_INT = - (MAX_INT + 1) is probably the easiest formula, once you have calculated MAX_INT correctly.
So in the case of a 32-bit signed integer, MAX_INT = +2,147,483,683, and hence MIN_INT = - (MAX_INT + 1) = -2,147,483,684.
/*
* ezThreeFourths - multiplies by 3/4 rounding toward 0,
* Should exactly duplicate effect of C expression (x*3/4),
* including overflow behavior.
* Examples: ezThreeFourths(11) = 8
* ezThreeFourths(-9) = -6
* ezThreeFourths(1073741824) = -268435456 (overflow)
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 12
* Rating: 3
*/
int ezThreeFourths(int x) {
int z = x+x+x;
int sign_z = z>>31;
return ((z>>2)&(~sign_z)) + (((z>>2)+1)&sign_z);
}
I tried to solve this puzzle but
ERROR: Test ezThreeFourths(-2147483648[0x80000000]) failed...
...Gives -536870911[0xe0000001]. Should be -536870912[0xe0000000]
compiled with gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-51)
What's wrong with this solution?
Here's what I did:
#include <stdio.h>
#include <limits.h>
int ThreeFourths(int x)
{
int x3 = x + x + x;
return (x3 >= 0) ? (x3 >> 2) : -(int)((UINT_MAX - x3 + 1) >> 2);
}
int testData[] =
{
0,
1,
-1,
2,
-2,
3,
-3,
4,
-4,
5,
-5,
-9,
11,
INT_MAX / 2 + 1,
INT_MIN
};
int main(void)
{
int i;
for (i = 0; i < sizeof(testData)/sizeof(testData[0]); i++)
{
printf(" %d * 3 / 4 = %d\n",
testData[i], testData[i] * 3 / 4);
printf("ThreeFourths(%d) = %d\n",
testData[i], ThreeFourths(testData[i]));
}
return 0;
}
Output:
0 * 3 / 4 = 0
ThreeFourths(0) = 0
1 * 3 / 4 = 0
ThreeFourths(1) = 0
-1 * 3 / 4 = 0
ThreeFourths(-1) = 0
2 * 3 / 4 = 1
ThreeFourths(2) = 1
-2 * 3 / 4 = -1
ThreeFourths(-2) = -1
3 * 3 / 4 = 2
ThreeFourths(3) = 2
-3 * 3 / 4 = -2
ThreeFourths(-3) = -2
4 * 3 / 4 = 3
ThreeFourths(4) = 3
-4 * 3 / 4 = -3
ThreeFourths(-4) = -3
5 * 3 / 4 = 3
ThreeFourths(5) = 3
-5 * 3 / 4 = -3
ThreeFourths(-5) = -3
-9 * 3 / 4 = -6
ThreeFourths(-9) = -6
11 * 3 / 4 = 8
ThreeFourths(11) = 8
1073741824 * 3 / 4 = -268435456
ThreeFourths(1073741824) = -268435456
-2147483648 * 3 / 4 = -536870912
ThreeFourths(-2147483648) = -536870912
The reason why I didn't use right shifts on negative integers is simple. The result of these shifts is implementation-defined (per the C standard) and is not guaranteed to be the same as from a right shift with sign extension that we might be expecting because of it being the most common implementation.
I wrote (UINT_MAX - x3 + 1) instead of simply -x3 because it can result a signed overflow (when x3 = INT_MIN that is a minus power of 2), which has undefined behavior (per the C standard, again). And even if this undefined behavior is known to be harmless, simple negation could still fail to produce a positive number (because of the asymmetry in the 2's complement representation of signed integers).
x + x + x can still produce signed overflow just as x * 3 can. So, this is the same undefined behavior.
Btw, since signed overflows result in UB, it should not even be legally asked from you to achieve them, let alone have specific expectations about the results when UB occurs.
int ezThreeFourths(int x) {
int z = x+x+x;
int sign_z = z>>31;
return ((z>>2)&(~sign_z)) + (((z>>2)+1)&sign_z);
}
Works with non-negative numbers. Also you shouldn't lie about code "you" wrote. Considering the exact code was written in "2008-01-26"
Works fine for me using Embarcadero C++ 6.43:
// x = 2147483647
int ezThreeFourths(int x)
{
int z = x+x+x;
// z = 2147483645 (6442450941[0x17FFFFFFD] truncated to 32-bits!)
int sign_z = z>>31;
// sign_z = (2147483645 >> 31) = 0
return ((z>>2)&(~sign_z)) + (((z>>2)+1)&sign_z);
// = ((2147483645 >> 2) & (~0)) + (((2147483645 >> 2) + 1) & 0)
// = (536870911 & 0xFFFFFFFF) + ((536870911+1) & 0)
// = (536870911 & 0xFFFFFFFF) + (536870912 & 0)
// = (536870911 & 0xFFFFFFFF) + 0
// = (536870911 & 0xFFFFFFFF)
// = 536870911
}
Your approach for making negative numbers round towards zero is not working correctly in the case of input values that divide evenly by 4. 0x80000000 is one such example, but it's perhaps easier to see the problem if you try with a small value.
For example: ezThreeFourths(-8) = -5 [ should be -6 ]