binary division in c require assistance - c

i need help i cant seemed to get the result. the assignment i am doing right now has to do with binary division. the purpose of this project is to try to mimic the ALU and we are not allowed to use the addition or subtraction operator. is there some parts in the code that i am missing?
#include <stdio.h>
#include <math.h>
int subtraction(int operand_1, int operand_2);
int division(int dividen, int divisor);
int addition(int operand_1, int operand_2);
int main()
{
int operand_1, operand_2,res;
printf (" enter the value for operand_1(dividen) and operand_2(divisor): ");
scanf ("%d %d",&operand_1,&operand_2);
res = division(operand_1,operand_2);
printf(" binary division: %d\n\n",res);
}
int addition(int operand_1, int operand_2)
{
int carry = operand_2;
int sum = operand_1;
while (carry !=0)
{
int temp =(sum & carry )<<1;
sum = sum ^ carry;
carry = temp;
}
return sum;
}
int subtraction(int operand_1, int operand_2)
{
operand_2= addition(~operand_2,1);
return addition (operand_1,operand_2);
}
int division ( int dividen, int divisor)
{
int i;
int quotient =0;
for (i= 0; i < 33 ; i++)
{
int remainder = subtraction(remainder,divisor);
if (remainder<0)
{
remainder = addition(divisor, remainder);
quotient= quotient << 1 & 0xfe;
}
else
{
quotient = quotient >> 1 & 0xfe;
}
divisor =divisor >> 1 ;
}
return quotient;
}

Issues with the division() function presented
Function division() initializes its quotient variable to 0. It later performs shift operations on it (quotient >> 1, quotient << 1), and bitwise & operations on the shifted results, but all of these will always produce 0 when quotient is 0. Those results are the only thing ever assigned back to quotient, so the function presented will never return anything other than 0 (unless as a result of exercising undefined behavior).
Moreover, this line is certainly wrong:
int remainder = subtraction(remainder,divisor);
It passes the indeterminate initial value of remainder to the subtraction() function, and uses the undefined result of that as the value of remainder.
And perhaps most telling, the function never uses its dividen parameter.
If your compiler is not producing warnings about the last two, then you would be well advised to learn how to turn up its warning output, or else to find a more helpful compiler. On the other hand, if you are ignoring your compiler's warnings then stop doing that. Compiler warnings are there to help you. Take the time to understand what they are telling you, and fix the problems they describe, or else be sure you can explain why it is safe to ignore them.
Binary long division
Based on the small, fixed bounds of the for loop in the presented division() function and its use of bit shifting, I'm inclined to think that you are specifically trying to implement binary long division. That would be a reasonable way to go, but the details aren't right at all.
is there some parts in the code that i am missing?
It's not a matter of some essential detail having been skipped. Although the algorithm implemented is reminiscent of binary long division, there's pretty much nothing correct about it.
Setting aside the questions of negative inputs and division by zero, binary long division could take this general form:
Convert dividend and divisor to type unsigned int. This gives you an extra value bit to work with, and it gives you defined behavior in relevant cases where [signed] int does not. (See also below.)
Shift the (unsigned) divisor left until it exceeds the (unsigned) dividend, then shift it one bit back right. Let b designate the total number of left shifts performed in that process, which may be zero.
Initialize the working quotient to 0, and the working remainder to the dividend.
Perform the following steps b times:
shift the working quotient one bit left
subtract the (shifted) divisor from the working remainder
if the difference is non-negative then
set the working remainder to the difference
turn on the least-significant bit of the working quotient (equivalently, add 1 to the quotient)
(else the difference is negative. The working remainder should not be updated, and the corresponding quotient bit is (already) zero).
shift the divisor one bit right.
After the iterations are finished, the working quotient is the correct binary quotient (of the unsigned operands), and the working remainder is the remainder, as would be computed by the % operator.
Note that although the bit-shifting disguises it somewhat, this is the same long division algorithm you learned in grade school, simplified by the fact that 1 and 0 are the only digits to be concerned with.
If your function must handle negative inputs then the initial conversion to unsigned must capture information about their signs and yield their absolute values. The sign information will inform whether the quotient needs to be inverted at the end.
I have intentionally avoided writing actual C code for the division function, so as not to rob you of the instructional value of writing that code yourself. I would encourage you, moreover, to study the algorithm description until you understand what it's doing and why, and then attempt to rewrite your division() function without referring further to this answer.

This works. I check for operators sign, if both are - result will be +.
Btw, your keyboard input doesnt work fine for 2 negative values, probably it is better in 2 different lines, in 2 scanfs.
int division ( int dividen, int divisor)
{
char sign=0;
int i;
int quotient =0;
int remainder=dividen;
if(dividen<0)
{
dividen=addition(~dividen,1);
sign^=1;
}
if(divisor<0)
{
divisor=addition(~divisor,1);
sign^=1;
}
do
{
printf("%d %d\r\n ",quotient ,remainder);
if (remainder>=divisor)
{
quotient= addition(quotient,1);
remainder=subtraction(remainder,divisor);
}
}while(remainder>=divisor);
if(sign)
quotient=addition(~quotient,1);
return quotient;
}

Related

Is there a way to know if an integer division operation had a remainder?

I don't want to know what the remainder is, I just want to know if there was a remainder as a boolean value.
As such, using the modulo operator is not what I'm looking for.
Something in C would be preferable, but any language works.
If really you cannot use the remainder operation (homework constraint ?), then you can use
check_remainder = b*(a/b) != a;
But the remainder use % is the natural way to go.
Use div(), which, hopefully, calculates quotient and remainder with 1 single operation.
#include <stdlib.h>
//...
int a = 42, b = 5;
div_t c = div(a, b);
if (c.rem) /* remainder for a/b is not zero */;
//...
You cannot tell if there is a remainder until you calculate such remainder, which means you have to perform the division.
That said, there are some shortcuts you can take but only if the divisor is a power of 2. For example, a division by 2 will have a remainder if the least significant bit is 1. In general, a division by 2 raised to the power n will have a remainder if the least n significant bits have a value other than 0000.....0 (n zeroes).
At the assembly level, some architectures, such as x86 provide you with both the quotient and the remainder as he result of a DIV instruction.
If using the modulus operator (or the division operator which is used internally) is not an option, you can do it the naive way:
unsigned has_remainder (unsigned a, unsigned b)
{
while (a >= b)
a -= b;
return a;
}

pow() function giving wrong answer [duplicate]

This question already has an answer here:
pow() function in C problems [duplicate]
(1 answer)
Closed 3 years ago.
I'm trying to multiply 2, 3 digit numbers.
I used 2 for loops (nested) and multiplied each digit of num1 with num2,
and shifted each result to the appropriate place using pow().
So the problem is pow(10,3) is coming out to be 299 instead of 300.
I haven't tried much as but used printf to find what is actually happening in the runtime and this is what I have found.
the values of tempR after shift should be
5,40,300,100,800,6000,1500,12000,90000
but are coming as
5,40,299,100,799,6000,1500,12000,89999
int main(void)
{
int result; // final result
int tempR; // temporary for each iteration
char a[] = "345"; // number 1
char b[] = "321"; // number 2
for(int i = 2;i>= 0 ; i --)
{
for(int j = 2;j >= 0 ; j --)
{
int shift = abs(i-2 + j -2);
printf("%d\n",shift); //used to see the values of shift.
//and it is coming as expected
tempR = (int)(b[i] - '0') * (int)(a[j] - '0');
printf("%d \n",tempR); // value to tempR is perfect
tempR = tempR*pow(10,shift);
printf("%d \n",tempR); // here the problem starts
result += tempR;
}
}
printf("%d",result);
}
Although IEEE754 (ubiquitous on desktop systems) is required to return the best possible floating point value for certain operators such as addition, multiplication, division, and subtraction, and certain functions such as sqrt, this does not apply to pow.
pow(x, y) can and often is implemented as exp(y * ln (x)). Hopefully you can see that this can cause result to "go off" spectacularly when pow is used with seemingly trivial integral arguments and the result truncated to int.
There are C implementations out there that have more accurate implementations of pow than the one you have, particularly for integral arguments. If such accuracy is required, then you could move your toolset to such an implementation. Borrowing an implementation of pow from a respected mathematics library is also an option, else roll your own. Using round is also a technique, if a little kludgy if you get my meaning.
Never use float functions for the integer calculations. Your pow result almost never will be precise. In this case it is slightly below 300 and the cast to integer makes it 299.
The pow function operates on doubles. Doubles use finite precision. Conversion back to integer chops rather than rounding.
Finite precision is like representing 1/3 as 0.333333. If you do 9 * 1/3 and chop to an integer, you'll get 2 instead of 3 because 9 * 1/3 will give 2.999997 which chops to two.
This same kind of rounding and chopping is causing you to be off by one. You could also round by adding 0.5 before chopping to an integer, but I wouldn't suggest it.
Don't pass integers through doubles and back if you expect exact answers.
Others have mentioned that pow does not yield exact results, and if you convert the result to an integer there's a high risk of loss of precision. Especially since if you assign a float type to an integer type, the result get truncated rather than rounded. Read more here: Is floating math broken?
The most convenient solution is to write your own integer variant of pow. It can look like this:
int int_pow(int num, int e)
{
int ret = 1;
while(e-- > 0)
ret *= num;
return ret;
}
Note that it will not work if e is negative or if both num and e is 0. It also have no protection for overflow. It just shows the idea.
In your particular case, you could write a very specialized variant based on 10:
unsigned int pow10(unsigned int e)
{
unsigned int ret = 1;
while(e-- > 0)
ret *= 10;
return ret;
}

Is Modulus or Remainder % Signed Value Always the same as And Operator Minus 1 from that value?

Here is some example code
int test = 1234;
int modValue, andValue;
modValue = test % -8;
andValue = test & 7;
printf("Mod Value = %d And Value = %d\n", modValue, andValue);
int counter = 0;
for(counter = 0; counter < 10000; counter++) {
modValue = counter % -8;
andValue = counter & 7;
if(modValue != andValue) {
printf("diff found at %d\n", counter);
}
}
Ideone link: http://ideone.com/g79yQm
Negative numbers give different results, that's about it but other then that do they always both function exactly the same for all positive values?
Even for negative numbers they seem to be offsetted only always just off by 1 cyclic round.
Those wondering it's similar to this question Why is modulo operator necessary? question but I don't subtract 1.
This uses negative values which are higher then the modulus value and yeah only works for positive values.
I found this from the IDA-PRO Hex-Ray's decompiler seems to generate sometimes a Modulus % and other times a AND & operator for both identical source codes afaik in different functions. I guess it's from the optimizer.
Since this project I decompiled shouldn't even use negative values I wonder what was the original source code doubt anyone uses modulus with negative values though seems weird.
Also using And as a modulus command how I know cyclic operation always use a modulus yet in this case the person must of used a Val And 7 since Val % 7 is completely different result.
Forgot to say the original code most likely used abs(Val) and 7 since anything with modulus with positive values seems to be wrong I don't think anyone would be using modulus with negative values it looks unappealing to the eyes. So I guess that's the best it could be.
The optimization of x % N to x & (N-1) only works if N is a power of two.
You also need to know that x is positive, otherwise there is a little difference between the bitmask operation and the remainder operation. The bitmask operation produces the remainder for the Euclidean division, which is always positive, whereas % produces the remainder for C's division /, which rounds towards zero and produces a remainder that is sometimes negative.
The sign of the result of % are machine dependent for negative operands, the same applies for overflow/underflow. / by proxy follows the same rules.

In C bits, multiply by 3 and divide by 16

A buddy of mine had these puzzles and this is one that is eluding me. Here is the problem, you are given a number and you want to return that number times 3 and divided by 16 rounding towards 0. Should be easy. The catch? You can only use the ! ~ & ^ | + << >> operators and of them only a combination of 12.
int mult(int x){
//some code here...
return y;
}
My attempt at it has been:
int hold = x + x + x;
int hold1 = 8;
hold1 = hold1 & hold;
hold1 = hold1 >> 3;
hold = hold >> 4;
hold = hold + hold1;
return hold;
But that doesn't seem to be working. I think I have a problem of losing bits but I can't seem to come up with a way of saving them. Another perspective would be nice. Just to add, you also can only use variables of type int and no loops, if statements or function calls may be used.
Right now I have the number 0xfffffff. It is supposed to return 0x2ffffff but it is returning 0x3000000.
For this question you need to worry about the lost bits before your division (obviously).
Essentially, if it is negative then you want to add 15 after you multiply by 3. A simple if statement (using your operators) should suffice.
I am not going to give you the code but a step by step would look like,
x = x*3
get the sign and store it in variable foo.
have another variable hold x + 15;
Set up an if statement so that if x is negative it uses that added 15 and if not then it uses the regular number (times 3 which we did above).
Then divide by 16 which you already showed you know how to do. Good luck!
This seems to work (as long as no overflow occurs):
((num<<2)+~num+1)>>4
Try this JavaScript code, run in console:
for (var num = -128; num <= 128; ++num) {
var a = Math.floor(num * 3 / 16);
var b = ((num<<2)+~num+1)>>4;
console.log(
"Input:", num,
"Regular math:", a,
"Bit math:", b,
"Equal: ", a===b
);
}
The Maths
When you divide a positive integer n by 16, you get a positive integer quotient k and a remainder c < 16:
(n/16) = k + (c/16).
(Or simply apply the Euclidan algorithm.) The question asks for multiplication by 3/16, so multiply by 3
(n/16) * 3 = 3k + (c/16) * 3.
The number k is an integer, so the part 3k is still a whole number. However, int arithmetic rounds down, so the second term may lose precision if you divide first, And since c < 16, you can safely multiply first without overflowing (assuming sizeof(int) >= 7). So the algorithm design can be
(3n/16) = 3k + (3c/16).
The design
The integer k is simply n/16 rounded down towards 0. So k can be found by applying a single AND operation. Two further operations will give 3k. Operation count: 3.
The remainder c can also be found using an AND operation (with the missing bits). Multiplication by 3 uses two more operations. And shifts finishes the division. Operation count: 4.
Add them together gives you the final answer.
Total operation count: 8.
Negatives
The above algorithm uses shift operations. It may not work well on negatives. However, assuming two's complement, the sign of n is stored in a sign bit. It can be removed beforing applying the algorithm and reapplied on the answer.
To find and store the sign of n, a single AND is sufficient.
To remove this sign, OR can be used.
Apply the above algorithm.
To restore the sign bit, Use a final OR operation on the algorithm output with the stored sign bit.
This brings the final operation count up to 11.
what you can do is first divide by 4 then add 3 times then again devide by 4.
3*x/16=(x/4+x/4+x/4)/4
with this logic the program can be
main()
{
int x=0xefffffff;
int y;
printf("%x",x);
y=x&(0x80000000);
y=y>>31;
x=(y&(~x+1))+(~y&(x));
x=x>>2;
x=x&(0x3fffffff);
x=x+x+x;
x=x>>2;
x=x&(0x3fffffff);
x=(y&(~x+1))+(~y&(x));
printf("\n%x %d",x,x);
}
AND with 0x3fffffff to make msb's zero. it'l even convert numbers to positive.
This uses 2's complement of negative numbers. with direct methods to divide there will be loss of bit accuracy for negative numbers. so use this work arround of converting -ve to +ve number then perform division operations.
Note that the C99 standard states in section section 6.5.7 that right shifts of signed negative integer invokes implementation-defined behavior. Under the provisions that int is comprised of 32 bits and that right shifting of signed integers maps to an arithmetic shift instruction, the following code works for all int inputs. A fully portable solution that also fulfills the requirements set out in the question may be possible, but I cannot think of one right now.
My basic idea is to split the number into high and low bits to prevent intermediate overflow. The high bits are divided by 16 first (this is an exact operation), then multiplied by three. The low bits are first multiplied by three, then divided by 16. Since arithmetic right shift rounds towards negative infinity instead of towards zero like integer division, a correction needs to be applied to the right shift for negative numbers. For a right shift by N, one needs to add 2N-1 prior to the shift if the number to be shifted is negative.
#include <stdio.h>
#include <stdlib.h>
int ref (int a)
{
long long int t = ((long long int)a * 3) / 16;
return (int)t;
}
int main (void)
{
int a, t, r, c, res;
a = 0;
do {
t = a >> 4; /* high order bits */
r = a & 0xf; /* low order bits */
c = (a >> 31) & 15; /* shift correction. Portable alternative: (a < 0) ? 15 : 0 */
res = t + t + t + ((r + r + r + c) >> 4);
if (res != ref(a)) {
printf ("!!!! error a=%08x res=%08x ref=%08x\n", a, res, ref(a));
return EXIT_FAILURE;
}
a++;
} while (a);
return EXIT_SUCCESS;
}

Performing arithmetic operations in binary using only bitwise operators [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I multiply and divide using only bit shifting and adding?
I have to write functions to perform binary subtraction, multiplication, and division without using any arithmetic operators except for loop control. I've only written code in Java before now, so I'm having a hard time wrapping my head around this.
Starting with subtraction, I need to write a function with prototype
int bsub(int x, int y)
I know I need to convert y to two's complement in order to make it negative and add it to x, but I only know how to do this by using one's complement ~ operator and adding 1, but I can't use the + operator.
The badd function was provided, and I will be able to implement it in bsub if I can figure out how to make y a negative number. The code for badd is shown below. Thanks in advance for any tips.
int badd(int x,int y){
int i;
char sum;
char car_in=0;
char car_out;
char a,b;
unsigned int mask=0x00000001;
int result=0;
for(i=0;i<32;i++){
a=(x&mask)!=0;
b=(y&mask)!=0;
car_out=car_in & (a|b) |a&b;
sum=a^b^car_in;
if(sum) {
result|=mask;
}
if(i!=31) {
car_in=car_out;
} else {
if(car_in!=car_out) {
printf("Overflow occurred\n");
}
}
mask<<=1;
}
return result;
}
Well, subtracting in bitwise operations without the + or - operators is slightly tricky, but can be done. You have the basic idea with the complement, but without using + it becomes slightly tricky.
You can do it by first setting up addition with bit-wise only, then using that, you can do subtraction. Which is used for the complement, So the code looks like this:
int badd(int n1, int n2){
int carry, sum;
carry = (n1 & n2) << 1; // Find bits that are used for carry
sum = n1 ^ n2; // Add each bit, discard carry.
if (sum & carry) // If bits match, add current sum and carry.
return badd(sum, carry);
else
return sum ^ carry; // Return the sum.
}
int bsub(int n1, int n2){
// Add two's complement and return.
return badd(n1, badd(~n2, 1));
}
And then if we use the above code in an example:
int main(){
printf("%d\n", bsub(53, 17));
return 0;
}
Which ends up returning 36. And that is how subtraction works with bitwise only operations.
Afterwards multiplication and division get more complicated, but can be done; for those two operations, use shifts along with addition and/or subtraction to get the job done. You may also want to read this question and this article on how to do it.
You have to implement the binary addition first:
Example with 4 bits:
a = 1101
b = 1011
mask will range from 0001 to 1000
for (i=0;i<4;i++) {
x = a & pow(2, i); //mask, you can shift left as well
y = b & pow(2, i);
z = x ^ y; //XOR to calculate addition
z = z ^ carry; //add previous carry
carry = x & y | x ^ carry | y ^ carry; //new carry
}
This is pseudocode. The mask allows for operating bit by bit from left to right. You'll have to store z conveniently into another variable.
Once you have the addition, you'll be able to implement subtraction by 1'complementing and adding 1.
Multiplication goes the same way, but slightly more difficult. Basically it's the same division method you learned at school, using masks to select bits conveniently and adding the intermediate results using the addition above.
Division is a bit more complicated, it would take some more time to explain but basically it's the same principle.

Resources