I want to make a bitwise AND computation over integers, but without converting them to binary numbers. For example, I have a integer "10111" (it is integer, not binary) and another integer "01001". I want bitwise AND of these numbers without converting them to binary and then making bitwise AND. I know it is not bitwise what I ask, but I want something similar to this. I know it can be interpreted initially as binary, converted to decimal and then do bitwise AND, but I do not want that. I want something like this:
int a;
int b;
int temp;
double result;
temp = a & b;
while (result != 0) {
if (result % 10 == 1)
count++;
result /= 10;
}
int length = floor(log10(abs(a))) + 1;
result = count / length;
return result;
I want this to check similarity of the Bag of Words(from natural language processing, string of 0s and 1s). I am importing Bag of Words in Monetdb, Column type should be Integer (Not string). If I have for example "10111" and "01001" in the Integer type cells, I want to get "00001" and fraction 1/5, because only 1 positions matches.
Thanks in advance
Might be a bit bulky, but it kind of works) You can optimize it yourself. I hope that I get you correctly.
IDEOne demo
#include <stdio.h>
unsigned int weirdAnd(unsigned int a, unsigned int b) {
unsigned int result = 0;
unsigned int coef = 1;
while (a && b) {
result += ((a % 10) && (b % 10)) * coef;
coef *= 10;
a /= 10;
b /= 10;
}
return result;
}
unsigned int weirdOr(unsigned int a, unsigned int b) {
unsigned int result = 0;
unsigned int coef = 1;
while (a || b) {
result += ((a % 10) || (b % 10)) * coef;
coef *= 10;
a /= 10;
b /= 10;
}
return result;
}
int main(void) {
// your code goes here
unsigned int a = 10110;
unsigned int b = 10011;
printf("%u and \n%u = \n%u\n\n", a, b, weirdAnd(a, b));
printf("%u or \n%u = \n%u\n\n", a, b, weirdOr(a, b));
return 0;
}
Output:
10110 and 10011 = 10010
10110 or 10011 = 10111
The problem is that and works on bits only, and it does not care if the input numbers are given in decimals, octal, hexadecimal, or any other way. To force and to work correctly, you must give it an input in 'binary', that is, only ones and zeroes. To do so you need to grab each digit of the input numbers as if they are binary digits.
The following works as expected:
#include <stdio.h>
int cheap_pow (int base, int exponent)
{
int result = base;
while (exponent-- > 0)
result *= base;
return result;
}
int main (void)
{
int a = 10111, b = 1001 ;
int result, factor;
printf ("BAD: %05d AND %05d = %05d\n", a, b, a & b);
printf ("GOOD: %05d AND %05d = ");
result = 0;
factor = 1;
while (a | b)
{
result += factor * ((a & 1) and (b & 1));
factor *= 10;
a /= 10;
b /= 10;
}
printf ("%05d\n", result);
}
but you must be careful when defining your inputs. When written directly into your source code, a value b = 01001 will be interpreted by the C compiler as octal (base 8), rather than decimal; and it will have the (decimal) value 513. It's just a Rule of C.
If your input comes from elsewhere, you don't need to take this into account – except when you use a standard function such as strtol, where you should carefully read the documentation because it does the same thing:
If base is zero or 16, the string may then include a "0x"
prefix, and the number will be read in base 16; otherwise, a zero
base is taken as 10 (decimal) unless the next character is '0', in
which case it is taken as 8 (octal).
An additional note is this program only will work in the range for signed int, that is (currently) up to 10 "binary" digits. If you need some more, you could switch to a larger type; but beyond that, you are better off with a not-numerical solution and use a character strings throughout.
int a, b;
int tmp = a & b;
int res = 0;
while ((tmp != 0 &&) (tmp / 10 != 0)){
int dig = tmp % 10;
res = (dig == 1)? ++res: res;
tmp /= 10;
}
Try this.
Related
The code below will get two integers X and Y from user, convert them to binary and insert all bits of Y after the last set bit in X.
example: 10 14
output: 188
Explanation:
10 -> 1010
14 -> 1110
10111100 -> 188
Here is the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int insertBits(int X, int Y) {
int int_to_bin(int k) {
return (k == 0 || k == 1 ? k : ((k % 2) + 10 * int_to_bin(k / 2)));
}
int a1 = int_to_bin(X);
int a2 = int_to_bin(Y);
char msg[20];
char msg1[20];
char deal[20];
sprintf(msg, "%d", a1);
sprintf(msg1, "%d", a2);
int k = 0;
int i = 0;
for (i = strlen(msg) - 1; i >= 0; i--) {
if (msg[i] == '1') {
k = 1;
break;
}
}
memcpy(msg, &msg[0], i);
memcpy(deal, &msg[i], -1);
strcat(msg, deal);
printf("%s", strcat(deal, msg1));
}
int main() {
insertBits(10, 20);
}
I wrote the code till converting the input to binary and extracted the binarys i dont know how to merge it and convert to decimal.please help me
Ok so lets summarize what you have to do,
Convert the numbers in 4bit binary and concatenate into a string.
After both numbers are done in separate strings concatenate both strings to get new string.
Convert the new string in decimal.
This functions converts a single number into 4bit binary string. Call this 2 times and you get two string with 4bit bin number. Now take the two string and concatenate it for getting the final string.
const char *byte_to_binary(int x)
{
static char b[9];
b[0] = '\0';
int z;
for (z = 8; z > 0; z >>= 1)
{
strcat(b, ((x & z) == z) ? "1" : "0");
}
return b;
}
Now what if you need more the 4bits. You can see I have initialized z=8 because 0b0000 1000 in dec is 8. so if you need 5bit then just so z=16 because 0b0001 0000 is 16 in dec.
For converting string of numbers in decimal, use the basic concept. If bin number is 0b1000, then to convert it to dec you need to do, 12^3 + 02^2 + 02^1 + 02^0.
for(sum=0, j=0, s=strlen(num)-1; s >= 0; s--, ++j){
if(num[s] == '1'){
sum = sum + pow(2,j);
}
}
This code snippet converts a string of binary in dec. That's it.
P.S. Not giving you full code as time is limited and I guess you are smart enough to figure it out by yourself. Comment for any help.
I will give a non portable answer. It will work for x86 + gcc.
#include <stdio.h>
int insertBits(int X, int Y) {
int msb;
asm("bsrl %1,%0" : "=r"(msb) : "r"(X));
Y <<= (msb+1);
return X|Y;
}
int main() {
printf("%d\n", insertBits(10, 20));
}
X=10 => 1010
Y=20 => 10100
Result=330 => 101001010
Your approach is severely limited: if the number is larger than 1023, the conversion will overflow the range of int.
You should use unsigned int arguments, compute the number of trailing zeroes in X and the number of bits in Y and the result will be easy to get with shift operations:
unsigned int insertBits(unsigned int X, unsigned int Y) {
int n1, n2;
unsigned int temp;
if (X == 0)
return Y;
if (Y == 0)
return X;
// compute the number of trailing zeroes in X
for (n1 = 0, temp = X; (temp & 1) == 0; n1++, temp >>= 1)
continue;
// compute the number of bits in Y
for (n2 = 0, temp = Y; temp != 0; n2++, temp >>= 1)
continue;
return ((X >> n1 << n2) | Y) << n1;
}
I've been working on a code that converts a given number (decimal base) to any other base from 2 to 16.
Clearly, I've come across the issue that the function base_conversion_it (it stands for iterative) prints the values in reverse.
I cannot use arrays nor pointers, and everyone on the internet seems to solve this issue like that. My assignment requires making both an iterative and a recursive function (which I did and works).
void base_conversion_it(unsigned int n, unsigned int b) {
if (n > 0) {
//bases between 2 and 16
if (b >= 2 && b <= 16) {
int r; //r = remainder
int q = 1; //quotient
int num; //saves the remainder
while (q != 0) {
r = n % b;
printf("%X", r);
q = n / b;
n = q;
}
}
}
}
You start converting from the units digit.
Maybe start with the most significant digit instead?
// It's Undefined Behaviour if `b` is outside the range [2...16]
void base_conversion_it(unsigned int n, unsigned int b) {
unsigned highestbase = 1;
while (highestbase * b <= n) highestbase *= b; //possible wrap around and infinite loop
while (highestbase) {
printf("%X", n / highestbase);
n %= highestbase;
highestbase /= b;
}
printf("\n");
}
Sorry missed iterative.
char digits[] = "0123456789ABCDEFGHIJKLMNOP";
void print(unsigned long long val, unsigned base)
{
unsigned long long mask = base;
while(val / mask >= base) mask *= base;
do
{
printf("%c", digits[val / mask]);
val %= mask;
mask /= base;
}while(val);
}
int main(void)
{
print(45654756453, 10); printf("\n");
print(45654756453, 16); printf("\n");
print(45654756453, 24); printf("\n");
print(45654756453, 2); printf("\n");
}
https://godbolt.org/z/W3fGnnhYs
Recursion:
char digits[] = "0123456789ABCDEF";
void print(unsigned long long val, unsigned base)
{
if(base <= 16 && base > 1)
{
if(val >= base) print(val / base, base);
printf("%c", digits[val % base]);
}
}
https://godbolt.org/z/84hYocnjv
If you cannot use either arrays (including strings) or recursion, then I think you need to compute the output digits in most-significant-first order. This is a bit less natural than computing them in the opposite order and reversing the result, but it can be done:
use a loop to find the place value of the most significant non-zero base-b digit of n. For example, check the result of dividing n by successive powers of b until the result is 0, then back off one step.
In a separate loop, read off the base-b digits of n one by one, starting with the one at the discovered most-significant position. For each digit,
Divide the current value of n by the place value pv of the current digit to get a digit value.
Replace n with n % pv.
Be careful to continue all the way down to place value 1, as opposed, say, to stopping when n becomes zero.
I'm trying to input two numbers and remove 8s and 9s (not convert them, only remove unneeded numbers) so they can fit in the octal base.
When I run the program and input the numbers, they are almost correctly returned, but they are deducted by a bit.
I still don't know why and how to fix it. It might be something with zeroes, but I don't know.
int octal(int a)
{
int b = 0;
int i = 0;
while(a > 0){
if((a % 10) <= 7){
b= pow(10,i) * (a%10)+b;
i++;
}
a=a/10;
}
return b;
}
int main()
{
int j, o, a, b;
scanf(" %d %d", &j, &o);
a=octal(j);
b=octal(o);
printf("%d\n%d\n",a,b);
return 0;
}
edit: Example
Input: 72349 and 91238
Output: 7233 and 122
Code is encountering a weak double pow() that is returning values near the expected mathematical result. When the result is just under a whole number, the conversion back to int results in fraction truncation - results appear 1 less then expected.
Could use round(pow(10,i)) or better yet, stay with int math as follows.
Other simplifications possible, but minimal code changes to outline OP's issue.
int octal(int a) {
int b = 0;
int i = 0;
int pow10 = 1;
while (a > 0) {
if ((a % 10) <= 7) {
//b = pow(10,i) * (a%10)+b;
b = pow10 * (a % 10) + b;
pow10 *= 10;
i++;
}
a = a / 10;
}
return b;
}
Care for a walk on the recursive side of life?
int octal(int a) {
assert(a >= 0);
while (a >= 8) {
int digit = a%10;
a /= 10;
if (digit < 8) {
return octal(a)*10 + digit;
}
}
return a;
}
Given a integer(2^n) which is power of 2, I want to find out n, the index value using logarithm. The formula to find index is : log(number) / log(2). Following is the code snippet :
unsigned long int a;
double apower;
apower = log((double)a) / log((double)2);
I found that value of 'apower' is wrong at some large value of a, I do not know the value, as my code fails, after I submit it. Why is it so? Is there some casting issue?
Following is the entire snippet :
int count = 0;
unsigned long int a,b;
double apower,bpower;
apower = log((double)a) / log((double)2);
bpower = log((double)b) / log((double)2);
count = abs(apower - bpower);
printf("%d\n",count);
Values of a and b will always be power of 2. So apower and bpower must be have 00 in decimal places. That is why, value of count will be int (%d).
I just want to know the behavior of Logarithm.
I am only answering half of your question, because it is not necessary to use logs to solve this. An easy way is to use this:
unsigned long long a = 0x8000000000000000ULL;
int n = 0;
while (a >>= 1) n++;
printf("%d\n", n);
Output:
63
Converting to logs and divding may cause loss of significance, in which case you should use round. You use the word "submit", so it was an online challenge that failed? What exactly did you print? (in this case) 63.000000? That would be got from the default format of %f.
Why not take advantage of the fact that the log2 is stored in the exponent field of a double? :)
unsigned long long a = 0x8000000000000000ULL;
union {
double d;
unsigned long long l;
} u;
u.d = a;
int apower = (u.l >> 52) - 1023;
printf("%d\n", apower);
Output:
63
This assumes that unsigned long longs and doubles are 64 bit and that the input is > 0.
When using double math, the log result or quotient may not be exactly the mathematical result but 1 (or 2) next representable double away.
Calculating log() only returns an exact mathematical result for log(0), all other mathematical results are irrational. All double are rational.
This may result in an answer like 29.999999..., which saved as an int is 29.
Recommend using integer math instead
int mylog2(unsigned long x) {
int y = 0;
#if (ULONG_MAX>>16 > 1lu<<16)
if (x >= 1lu<<32) { x >>= 32; y += 32;
#endif
if (x >= 1lu<<16) { x >>= 16; y += 16; }
if (x >= 1lu<<8) { x >>= 8; y += 8; }
if (x >= 1lu<<4) { x >>= 4; y += 4; }
if (x >= 1lu<<2) { x >>= 2; y += 2; }
if (x >= 1lu<<1) { x >>= 1; y += 1; }
return y;
}
How can I subtract two integers in C without the - operator?
int a = 34;
int b = 50;
You can convert b to negative value using negation and adding 1:
int c = a + (~b + 1);
printf("%d\n", c);
-16
This is two's complement sign negation. Processor is doing it when you use '-' operator when you want to negate value or subtrackt it.
Converting float is simpler. Just negate first bit (shoosh gave you example how to do this).
EDIT:
Ok, guys. I give up. Here is my compiler independent version:
#include <stdio.h>
unsigned int adder(unsigned int a, unsigned int b) {
unsigned int loop = 1;
unsigned int sum = 0;
unsigned int ai, bi, ci;
while (loop) {
ai = a & loop;
bi = b & loop;
ci = sum & loop;
sum = sum ^ ai ^ bi; // add i-th bit of a and b, and add carry bit stored in sum i-th bit
loop = loop << 1;
if ((ai&bi)|(ci&ai)|(ci&bi)) sum = sum^loop; // add carry bit
}
return sum;
}
unsigned int sub(unsigned int a, unsigned int b) {
return adder(a, adder(~b, 1)); // add negation + 1 (two's complement here)
}
int main() {
unsigned int a = 35;
unsigned int b = 40;
printf("%u - %u = %d\n", a, b, sub(a, b)); // printf function isn't compiler independent here
return 0;
}
I'm using unsigned int so that any compiler will treat it the same.
If you want to subtract negative values, then do it that way:
unsgined int negative15 = adder(~15, 1);
Now we are completly independent of signed values conventions. In my approach result all ints will be stored as two's complement - so you have to be careful with bigger ints (they have to start with 0 bit).
Pontus is right, 2's complement is not mandated by the C standard (even if it is the de facto hardware standard). +1 for Phil's creative answers; here's another approach to getting -1 without using the standard library or the -- operator.
C mandates three possible representations, so you can sniff which is in operation and get a different -1 for each:
negation= ~1;
if (negation+1==0) /* one's complement arithmetic */
minusone= ~1;
else if (negation+2==0) /* two's complement arithmetic */
minusone= ~0;
else /* sign-and-magnitude arithmetic */
minusone= ~0x7FFFFFFE;
r= a+b*minusone;
The value 0x7FFFFFFFE would depend on the width (number of ‘value bits’) of the type of integer you were interested in; if unspecified, you have more work to find that out!
+ No bit setting
+ Language independent
+ Can be adjusted for different number types (int, float, etc)
- Almost certainly not your C homework answer (which is likely to be about bits)
Expand a-b:
a-b = a + (-b)
= a + (-1).b
Manufacture -1:
float: pi = asin(1.0);
(with minusone_flt = sin(3.0/2.0*pi);
math.h) or = cos(pi)
or = log10(0.1)
complex: minusone_cpx = (0,1)**2; // i squared
integer: minusone_int = 0; minusone_int--; // or convert one of the floats above
+ No bit setting
+ Language independent
+ Independent of number type (int, float, etc)
- Requires a>b (ie positive result)
- Almost certainly not your C homework answer (which is likely to be about bits)
a - b = c
restricting ourselves to the number space 0 <= c < (a+b):
(a - b) mod(a+b) = c mod(a+b)
a mod(a+b) - b mod(a+b) = c mod(a+b)
simplifying the second term:
(-b).mod(a+b) = (a+b-b).mod(a+b)
= a.mod(a+b)
substituting:
a.mod(a+b) + a.mod(a+b) = c.mod(a+b)
2a.mod(a+b) = c.mod(a+b)
if b>a, then b-a>0, so:
c.mod(a+b) = c
c = 2a.mod(a+b)
So, if a is always greater than b, then this would work.
Given that encoding integers to support two's complement is not mandated in C, iterate until done. If they want you to jump through flaming hoops, no need to be efficient about it!
int subtract(int a, int b)
{
if ( b < 0 )
return a+abs(b);
while (b-- > 0)
--a;
return a;
}
Silly question... probably silly interview!
For subtracting in C two integers you only need:
int subtract(int a, int b)
{
return a + (~b) + 1;
}
I don't believe that there is a simple an elegant solution for float or double numbers like for integers. So you can transform your float numbers in arrays and apply an algorithm similar with one simulated here
If you want to do it for floats, start from a positive number and change its sign bit like so:
float f = 3;
*(int*)&f |= 0x80000000;
// now f is -3.
float m = 4 + f;
// m = 1
You can also do this for doubles using the appropriate 64 bit integer. in visual studio this is __int64 for instance.
I suppose this
b - a = ~( a + ~b)
Assembly (accumulator) style:
int result = a;
result -= b;
As the question asked for integers not ints, you could implement a small interpreter than uses Church numerals.
Create a lookup table for every possible case of int-int!
Not tested. Without using 2's complement:
#include <stdlib.h>
#include <stdio.h>
int sillyNegate(int x) {
if (x <= 0)
return abs(x);
else {
// setlocale(LC_ALL, "C"); // if necessary.
char buffer[256];
snprintf(buffer, 255, "%c%d", 0x2d, x);
sscanf(buffer, "%d", &x);
return x;
}
}
Assuming the length of an int is much less than 255, and the snprintf/sscanf round-trip won't produce any unspecified behavior (right? right?).
The subtraction can be computed using a - b == a + (-b).
Alternative:
#include <math.h>
int moreSillyNegate(int x) {
return x * ilogb(0.5); // ilogb(0.5) == -1;
}
This would work using integer overflow:
#include<limits.h>
int subtractWithoutMinusSign(int a, int b){
return a + (b * (INT_MAX + INT_MAX + 1));
}
This also works for floats (assuming you make a float version…)
For the maximum range of any data type , one's complement provide the negative value decreased by 1 to any corresponding value. ex:
~1 --------> -2
~2---------> -3
and so on... I will show you this observation using little code snippet
#include<stdio.h>
int main()
{
int a , b;
a=10;
b=~a; // b-----> -11
printf("%d\n",a+~b+1);// equivalent to a-b
return 0;
}
Output: 0
Note : This is valid only for the range of data type. means for int data type this rule will be applicable only for the value of range[-2,147,483,648 to 2,147,483,647].
Thankyou .....May this help you
Iff:
The Minuend is greater or equal to 0, or
The Subtrahend is greater or equal to 0, or
The Subtrahend and the Minuend are less than 0
multiply the Minuend by -1 and add the result to the Subtrahend:
SUB + (MIN * -1)
Else multiply the Minuend by 1 and add the result to the Subtrahend.
SUB + (MIN * 1)
Example (Try it online):
#include <stdio.h>
int subtract (int a, int b)
{
if ( a >= 0 || b >= 0 || ( a < 0 && b < 0 ) )
{
return a + (b * -1);
}
return a + (b * 1);
}
int main (void)
{
int x = -1;
int y = -5;
printf("%d - %d = %d", x, y, subtract(x, y) );
}
Output:
-1 - -5 = 4
int num1, num2, count = 0;
Console.WriteLine("Enter two numebrs");
num1 = int.Parse(Console.ReadLine());
num2 = int.Parse(Console.ReadLine());
if (num1 < num2)
{
num1 = num1 + num2;
num2 = num1 - num2;
num1 = num1 - num2;
}
for (; num2 < num1; num2++)
{
count++;
}
Console.WriteLine("The diferrence is " + count);
void main()
{
int a=5;
int b=7;
while(b--)a--;
printf("sud=%d",a);
}