I am doing a CRC program in C. Basically I am taking input in binary as a char array as dividend and divisor. Now I want to perform division operation on this two numbers. To perform arithmetic operation I will first convert this number in to integers, for example, '0' + t[1]. Now how do I perform bitwise modulo operation on this bits? Or if anyone know any better way to implement CRC on sender and receiver side, please suggest me?
Ok I think my words are bit confusing. I will try to make understand what I want to do by giving a simple example, suppose the dividend entered is 11100101 and the divisor is 11011, then what should happen is
Observe in the image given that selected numbers are divided they are XORed against the result. Here I want the same thing to happen in my program as is illustrated in the image. How do I perform this kind of bit by bit division?
Related
I have an assignment to make the Full Adder, it was chosen for us to practice the loops and conditinals in C.
So i did the easiest part of checking wether the number is in Base-2 and printing C-Out and Sum. But for Base-16 and Base-8 I couldn't figure out how to convert them to a smaller bases.
No advanced techniques are allowed, rules as follows:
You are not allowed to use data structures such as arrays to store values for the conversion
operation.
You are not allowed to use bitwise operators.
You are not allowed to define your own functions.
I hope that you don't give me the full solution for this step, like only help me with converting one base to another, and i will try figuring out the rest of it by myself.
Think of it this way: you must be familiar with base 10, or decimal numbers. You use them every day. So how do they work? First, the number of symbols to represent them is the base number, 10. This is why, as you are counting the numbers, whenever you get to a power of 10, you need to increase the number of symbols used to represent the number. What you are asked to do here is kind of the reverse of that process. If you had to write down the digits of a number in base 10 without being allowed to see the number, how would you do it? I will give you the first step: you can get the least significant digit by diving the number by 10 and taking the remainder. This will give you the number of times you had to change the symbol used since the last time you had to increase the number of symbols used.
If you do num%2 you will get the right most bit (LSBit) -- depending on how you want to return the bit pattern (string etc) -- save this bit.
If you divide by two then you will lose the right most bit (LSBit) .. keep doing this in a loop until the number becomes zero.
I have a random_rand() function which produces a random number between 0 and RANDOM_RAND_MAX. RANDOM_RAND_MAX is defined to be 65535.
I would like to use the middle bits from the result of random_rand() instead of lowest-order bits so that I can make the randomiztion better.
Could you please show me a quick way to do this.
Thanks
That's naughty.
Linear congruential generators work in such a way that the "most random" part comprises the lower order bits. A very famous IBM implementation of rand a couple of decades ago swapped the highest and lowest bits round after a drawing as a final flourish - this was found to completely ruin the generator!
So keep things simple. Generate your random number and extract the least significant bits using the % operator or a bitwise &: although this introduces statistical bias, the effects are no worse than the generator itself.
Whatever you end up doing, always run some statistical checks on your generator to make sure it has adequate statistical properties. At the time of writing, the generation scheme that seems to be the "best one" is the Mersenne Twister.
(If you really want the middle bits, then use a mixture of the bitwise right shift operator >> and &.)
result = (random_rand() >> 4) & 0xff
This shifts the whole result right by four bits (destroying the first four bit) and then logically-AND's the result with binary 0000000011111111 so only the next 8 bits are taken.
But when you need to resort to such dirty hacks to improve the quality of your pseudorandom number generator, you should rather consider to use a better PRNG instead. The mersenne twister, for example, is a very good tradeoff between performance and quality.
I've been researching this the last few days and I have been unable to come up with an answer. I have come up with one algorithm that works if the divisor is only one word. But, if the divisor is multiple words then I get some strange answers. I know this question has been asked a few times on here, but there has been no definitive answer except use the schoolbook method or go get a book on the subject. I have been able to get every function in my big integer library to work except division. It seems that some individuals think big integer division is a NP hard problem, and with the trouble that I'm having with it, I'm inclined to agree.
The data is stored in a structure that contains a pointer to an array of either uint16_t or uint32_t based on if the long long data type is supported or not. If long long is not supported, then uint16_t is used for the capture of any carry/overflow from multiplication and addition operations. The current functions that I have are addition, subtraction, multiply, 2's complement negation, comparison, and, or, xor, not, shift left, shift right, rotate left, rotate right, bit reversal (reflection), a few conversion routines, a random number fill routine, and some other utility routines. All these work correctly (I checked the results on a calculator) except division.
typedef struct bn_data_t bn_t;
struct bn_data_t
{
uint32 sz1; /* Bit Size */
uint32 sz8; /* Byte Size */
uint32 szw; /* Word Count */
bnint *dat; /* Data Array */
uint32 flags; /* Operational Flags */
};
This is related to another question that I asked about inline assembler as this is what it was for.
What I have found so far:
Algorithm for dividing very large numbers
What is the fastest algorithm for division of crazy large integers?
https://en.wikipedia.org/wiki/Division_algorithm
Newton-Raphson Division With Big Integers
And a bunch of academic papers on the subject.
What I have tried so far:
I have a basic routine working, but it divides a multi-word big integer number by a single word. I have tried to implement a Newton-Raphson algorithm, but that's not working as I have gotten some really strange results. I know about Newton's method from Calculus on which it is based, but this is integer math and not floating point. I understand the math behind the Goldschmidt division algorithm, but I am not clear on how to implement it with integer math. Part of the problem with some of these algorithms is that they call for a base 2 logarithm function. I know how to implement a logarithm function using floating point and a Taylor series, but not when using integer math.
I have tried looking at the GMP library, but the division algorithm is not very well documented and it kinda goes over my head. It seems that they are using different algorithms at different points which adds to the confusion.
For the academic papers, I mostly understand the math (I have cleared basic calculus math, multi-variable calculus, and ordinary differential equations), but once again, there is a disconnect between my mathematical knowledge and implementation using integer math. I have seen the grade school method being suggested which from what I can ascertain is something similar to a shift-subtract method, but I'm not too sure how to implement that one either. Any ideas? Code would be nice.
EDIT:
This is for my own personal learning experience. I want to learn how it is done.
EDIT: 4-JUN-2016
It has been awhile since I have worked on this as I had other irons in the fire and other projects to work on. Now that I have revisited this project, I have finally implemented big integer division using two different algorithms. The basic one is the shift-subtract method outlined here. The high speed algorithm which uses the CPU divide instruction is called only when the divisor is one word. Both algorithms have been confirmed to work properly as the results that they produce has been checked with an online big number calculator. So now, all basic math and logic functions have been implemented. Those functions include add, subtract, multiply, divide, divide with modulus, modulus, and, or, not, xor, negate, reverse (reflection), shift left, shift right, rotate left, and rotate right. I may add additional functions as their need comes up. Thank you to everyone who responded.
The schoolbook division (long-division) algorithm, commonly used for base-10 operands, can be used for arbitrarily large operands too. I will assume we are implementing the large numbers by array of digits in base B.
When we perform long-division manually for decimal operands, we usually depend on trial-and-error to find each quotient-digit d. But this trial-and-error can be replaced with an efficient method (due to D. A. Pope and M. L. Stein) when using long-division for large operands in base B.
To guess d, we can use the first digit (e) of the divisor and first two digits (yz) of the "current remainder" (resulting from a subtraction step of long-division). Say, d1 is the estimate for d obtained by dividing the number yz by e. It can be proved that, if the divisor has certain properties (which are always achievable, refer the link below), either d1 or d1-1 or d1-2 must be the required digit d. Each of these three candidates can be checked for the desired properties of d one by one.
Thus the finding of each quotient-digit becomes efficient, and for the rest part we can follow the iterative long-division process. Please refer the below article (written by me) for details about this algorithm and implementation in C:
https://mathsanew.com/articles/implementing_large_integers_division.pdf
It seems it should be a straightforward to shift/rotate an array by n bits.
However, the programming language I'm using (Solidity) doesn't have any such operator (i.e. there's no shift or rotate operator)...
I have an unsigned, 256-bit integer (which is a Solidity type uint256).
I was wondering if I could somehow do a shift or rotate operation "manually"?
I mean, perform some series of multiplication (*), mod (%) or similar operations to give the desired shift and rotate? I know this could be very inefficient, but I only need to do this operation once or twice an hour so it doesn't matter in my use-case.
If there isn't a shift function then you will likely have to do some series of *2 or slightly better would be:
val*[2^(number of shifts)]
I have a big number (integer, unsigned) stored in 2 variables (as you can see, the high and low part of number):
unsigned long long int high;
unsigned long long int low;
I know how to add or subtract some other that-kind of variable.
But I need to divide that-kind of numbers. How to do it? I know, I can subtract N times, but, maybe, there are more better solutions. ;-)
Language: C
Yes. It will involve shifts, and I don't recommend doing that in C. This is one of those rare examples where assembler can still prove its value, easily making things run hundreds of times faster (And I don't think I'm exaggerating this.)
I don't claim total correctness, but the following should get you going :
(1) Initialize result to zero.
(2) Shift divisor as many bits as possible to the left, without letting it become greater than the dividend.
(3) Subtract shifted divisor from dividend and add one to result.
(4) Now shift divisor to the right until once again, it is less than the remaining dividend, and for each right-shift, left-shift result by one bit. Go back to (3) unless stopping condition is satisfied. (Stopping condition must be something like "divisor has become zero", but I'm not certain about that.)
It really feels great to get back to some REAL programming problems :-)
Have you looked at any large-number libraries, such as GNU MP BigNum?
I know, I can subtract N times, but, maybe, there are more better solutions.
Subtracting N times may be slow when N is large.
Better (i.e. more complicated but faster) would be shift-and-subtract, using the algorithm you learned to do long division of decimal numbers in elementary school.
[There may also be 3rd-party library and/or compiler-specific support for such numbers.]
Hmm. I suppose if you have some headroom in "high", you could shift it all up one digit, divide high by the number, then add the remainder to the top remaining digit in low and divide low by the number, then shift everything back.
Here's another library doing 128 bit arithmetic. GnuCash: Math128.
Per my commenters below, my previous answer was stupid.
Quickly, my new answer would be that when I've tried to do this in the past, it almost always involved shifting, because it's the only operation that can be applied across multiple "words", if you will, and have it look the same as if it were one large word (with the exception of having to track carryover bits).
There are a couple different approaches to it, but I don't know of any better general direction than using shifts, unless your hardware has some special operations.
You could implement a "BigInt" type algorithm that does divisions on string arrays. Create 1 string array for each high,low pair and do the division. Store the result in another string array, then convert back to high,low integer pair.
Since the language is C, the array would probably be a character array. Consider it analogous to the "string array" I was mentioning above.
You can do addition and subtraction of arbitrarily large binary objects using the assembler looping and "add/subtract with carry (adc/sbb)" instructions. You can implement the other operations using them. I've never investigated doing anything beyond those two personally.
If your processor (or your C library) has a fast 64-bit divide, you can break the 128-bit divide into pieces (the same way you'd do a 32-bit divide on processors that had 16-bit divisions).
By the way, there are all sorts of tricks you can use if you know what typical values will be for the dividend and divisor. What is the source of these numbers? If a lot of your cases can be solved quickly, it might be OK the occasional case takes a long time.
Also, if you can find cases where an approximate answer is OK, that opens the door to a lot of speedy approximations.