Recursive binary to decimal function without pow() or loops - c

I am doing a C course.
I need to do a recursive XOR binary but I have some limitations.
I can't use loop or any math.h functions, nor can I call another function from the XOR function.
This is the function prototype:
int binaryXor(int firstnumber[], int secondnumber[], int length);
where firstnumber and secondnumber are arrays with the same length of 1s and 0s and length is their length.
The function should return the decimal value of the XOR of those two arrays.
Doing the XOR is quite simple, but how can I convert it to decimal with all the limitations?

In order to write a recursive function, with no loops, you need to answer the following question:
"How can I express the answer to my problem in terms of a smaller problem?"
In this case, the problem is that you have length digits to look at, but you're not allowed to loop. So, how do you express an xor of size length in terms of a smaller xor, together with some amount of work that doesn't require a loop?
[Edit: hang on, just looked at your question again, and you say you already have the xor sorted, so I guess you've already done this. In that case my comment above is the only thing you need to know: you're finished. An int in C is not a decimal value, it's just a value. You don't need to convert anything to decimal in order to store or return it in an int.
If you're interested though, I can post code that does convert an int to a decimal value using a recursive function. One simple way is to work out on the way "down" how many digits are required, by comparing with bigger and bigger powers of 10, and then on the way back "up" print the digits out starting from the end.]

This is a standard recursive question. The trick is to realize that the integer value of a a string of 1s and 0s followed by a 1 or 0, is 2 * the integer value of the string plus the value of the digit.
So you will want to do something like
if( length <= 0) return 0;
return 2 * binaryXOR(firstnumber, secondnumber, length - 1) + (firstnumber[length - 1] ^ secondnumber[length - 1]);

A recursive function call can be used in place of a loop.

Related

Multiplication of 2 numbers with a maximum of 2000 digits [duplicate]

This question already has answers here:
What is the simplest way of implementing bigint in C?
(5 answers)
How can I compute a very big digit number like (1000 digits ) in c , and print it out using array
(4 answers)
Store very big numbers in an integer in C
(2 answers)
Closed 3 months ago.
Implement a program to multiply two numbers, with the mention that the first can have a maximum of 2048 digits, and the second number is less than 100. HINT: multiplication can be done using repeated additions.
Up to a certain point, the program works using long double, but when working with larger numbers, only INF is displayed. Any ideas?
Implement a program to multiply two numbers, with the mention that the first can have a maximum of 2048 digits, and the second number is less than 100.
OK. The nature of multiplication is that if a number with N bits is multiplied by a number with M bits, then the result will have up to N+M bits. In other words, you need to handle a result that has 2148 bits.
A long double could be anything (it's implementation dependent). Most likely (Windows or not 80x86) is that it's a synonym for double, but sometimes it might be larger (e.g. the 80-bit format described on this Wikipedia page ). The best you can realistically hope for is a dodgy estimate with lots of precision loss and not a correct result.
The worst case (the most likely case) is that the exponent isn't big enough either. E.g. for double the (unbiased) exponent has to be in the range −1022 to +1023 so attempting to shove a 2048 bit number in there will cause an overflow (an infinity).
What you're actually being asked to do is implement a program that uses "big integers". The idea would be to store the numbers as arrays of integers, like uint32_t result[2148/32];, so that you actually do have enough bits to get a correct result without precision loss or overflow problems.
With this in mind, you want a multiplication algorithm that can work with big integers. Note: I'd recommend something from that Wikipedia page's "Algorithms for multiplying by hand" section - there's faster/more advanced algorithms that are way too complicated for (what I assume is) a university assignment.
Also, the "HINT: multiplication can be done using repeated additions" is a red herring to distract you. It'd take literally days for a computer do the equivalent of a while(source2 != 0) { result += source1; source2--; } with large numbers.
Here's a few hints.
Multiplying a 2048 digit string by a 100 digit string might yield a string with as many as 2148 digits. That's two high for any primitive C type. So you'll have to do all the math the hard way against "strings". So stay in the string space since your input will most likely be read in as much.
Let's say you are trying to multiple "123456" x "789".
That's equivalent to (123456 * (700 + 80 + 9)
Which is equivalent to to 123456 * 700 + 123456 * 80 + 123456 * 9
Which is equivalent to doing these steps:
result1 = Multiply 123456 by 7 and add two zeros at the end
result2 = Multiply 123456 by 8 and add one zero at the end
result3 = Multiply 123456 by 9
final result = result1+result2+result3
So all you need is a handful of primitives that can take a digit string of arbitrary length and do some math operations on it.
You just need these three functions:
// Returns a new string that is identical to s but with a specific number of
// zeros added to the end.
// e.g. MultiplyByPowerOfTen("123", 3) returns "123000"
char* MultiplyByPowerOfTen(char* s, size_t zerosToAdd)
{
};
// Performs multiplication on the big integer represented by s
// by the specified digit
// e.g. Multiple("12345", 2) returns "24690"
char* Multiply(char* s, int digit) // where digit is between 0 and 9
{
};
// Performs addition on the big integers represented by s1 and s2
// e.g. Add("12345", "678") returns "13023"
char* Add(char* s1, char* s2)
{
};
Final hint. Any character at position i in your string can be converted to its integer equivalent like this:
int digit = s[i] - '0';
And any digit can be converted back to a printable char:
char c = '0' + digit

Algorithm for printing decimal value of a huge(over 128bits) binary number?

TLDR, at the bottom :)
Brief:
I am in a process of creating an basic arithmetic library(addition, subtraction, ...) for handling huge numbers. One of the problem i am facing is printing these huge binary numbers into decimal.
I have huge binary number stored in an array of uint64_t. e.g.
uint64_t a[64] = {0};
Now, the goal is to print the 64*64bits binary number in the console/file as its decimal value.
Initial Work:
To elaborate the problem I want to describe how I printed hex value.
int i;
int s = 1;
a[1] = (uint64_t)0xFF;
for(i = s; i>= 0; i--)
{
printf("0x%08llX, ", a[i]);
}
Output:
0x000000FF, 0x00000000,
Similarly for printing OCT value I can just take LSB 3 bits from a[64], print decimal equivalent of those bits, 3 bits right shift all the bits of a[64] and keep repeating until all the values of a[64] has been printed. (print in revers order to keep first Oct digit on the right)
I can print Hex and Oct value of a binary of unlimited size just by repeating this unit algorithm, but I could not find/develop one for Decimal which I can repeat over and over again to print a[64](or something bigger).
What I have thought of:
My initial idea was to keep subtracting
max_64 =(uint64)10000000000000000000; //(i.e.10^19)
the biggest multiple of 10 inside uint64_t, from a until the value inside a is smaller than max_64 (which is basically equivalent of rem_64 = a%max_64 ) and print the rem_64 value using
printf("%019llu",rem_64);
which is the 1st 19 decimal digits of the number a.
Then do an arithmetic operation similar to (not the code):
a = a/max_64; /* Integer division(no fractional part) to remove right most 19 dec digits from 'a' */
and keep repeating and printing 19 decimal digits. (print in such a way that first found 19 digits are on the right, then next 19 digits on its left and so on...).
The problem is this process is to long and I don't want to use all these to just print the dec value. And was looking for a process which avoids using these huge time consuming arithmetic operations.
What I believe is that there must be a way to print huge size just by repeating an algorithm (similar to how Hex and Oct can be printed) and I hope someone could point me to the right direction.
What my library can do(so far):
Add (Using Full-Adder)
Sub (Using Full-subtractor)
Compare (by comparing array size and comparing array elements)
Div (Integer division, no fractional part)
Modulus (%)
Multiplication (basically adding from several times :( )
I will write code for other operations if needed, but I would like to implement the printing function independent of the library if possible.
Consider the problem like this:
You have been given a binary number X of n bits (1<=n<=64*64) you have to print out X in decimal. You can use existing library if absolutely needed but better if unused.
TLDR:
Any code, reference or unit algorithm which I can repeat for printing decimal value of a binary of too big and/or unknown size would be much helpful. Emphasis on algorithm i.e. I don't need a code if some one could describe a process I will be able to implement it. Thanks in advance.
When faced with such doubts, and given that there are many bigint libraries out there, it is interesting to look into their code. I had a look at Java's BigInteger, which has a toString method, and they do two things:
for small numbers, they bite the bullet and do something similar to what you proposed - straightforward link-by-link base conversion, outputting decimal numbers in each step.
for large numbers, they use the recursive Schönhage algorithm, which they quote in the comments as being referred to in, among other places,
Knuth, Donald, The Art of Computer Programming, Vol. 2, Answers to
Exercises (4.4) Question 14.

Using the mod operator correctly in C

In a hash table implementation in C, I am relying on the mod operator to transform my hash of the key by the capacity of the hash table as follows:
int i = compute_index(key, hash, capacity);
while(table[i].occupied && (strcmp(table[i].key, key) != 0))
{
...
The hash seems to be computed correctly, because in my debugger, I am able to utilize the hash function and the key to output -724412585.
The strange thing is, when I mod this number by the capacity using a regular calculator, I get 7. But within the debugger, and my code, the integer -1 is returned. This is very confusing and I would appreciate some help.
My compute_index() simply does this:
int compute_index(const char* key, int (*hash)(const char*), int cap)
{
return hash(key) % cap;
}
Would appreciate some guidance, thank you.
There are two common conventions for the sign of a % b: in one case, the sign is the same as b (i.e. always positive when b is positive), and in the other case it's the same as a (i.e. negative when a is negative). Older versions of C allowed either behavior, but C99 and later require the second behavior (which goes hand-in-hand with requiring truncating division, rather than leaving the choice of truncating or flooring division up to the compiler).
The upshot of this is that if your hash function can return a negative number, then hash(key) % cap will also be negative sometimes. The simplest thing you can do is to alter hash to return unsigned int instead of int.
I agree w/ everything #hobbs said, except for the following:
I believe the easiest thing you can do is either:
change the output of hash() to unsigned int,
or cast the output of hash() to unsigned int within the body of compute_index() before the modulo operation, or
add the modulus back in if the result of the % operation < 0 (to get the abstract-algebraic sense of "integer mod q").
The behavior of % in C for negative numbers can be confusing to those with a background in abstract algebra, particularly for one who works with the rings of integers mod q.

Binary to integer, need suggestions on this approach.

So I'm working on an assignment where I have to perform different operations but without using the standard arithmetic ones. Part of the assignment is converting the users input as an integer in binary form to the standard readable format.
So if the user inputs 0111, I have to return 7.
My question is, how can I split the input into separate values and then store them in an array? I cannot use the standard operands but I do have functions written for addition, subtraction and multiplication.
So what I'm thinking of doing is setting each value of the integer to an array, then reversing it, and in a while loop converting the values by multiplying the given 0 or 1 by corresponding powers of two and then adding everything up.
Scan it as a string. It has a nice advantage of already being an array:
char input[33];
scanf("%s",input);
that gives you an array of characters. They aren't integer which is probably what you want. You can covert it to an array of integers, one character at a time using character arithmetic:
array[i] = input[i] - '0';
You must stop when input[i] is 0, that is the end of the string. You can reverse the array if you want low order bit first.

Why does C give me a different answer than my calculator?

I've run into an odd problem with this code:
legibIndex = 206.385 - 84.6 * (countSylb / countWord) - 1.015 * (countWord / countSent);
This is the calculation for the legibility index of a given text file.
Since this is a homework assignment, we were told what the Index should be (80, or exactly 80.3)
My syllable count, word count, and sentence count are all correct (they match up with the given numbers for the sample textfiles.
Even if I hardcode the numbers in, I do not get 80, even though I do when i put it into my caclulator exactly as seen. I can't imagine what is wrong.
Here is the equation we were given:
Index = 206.835 - 84.6 * (# syllables/# words) - 1.015 * (# words/# sentences)
As you can see, I just plugged in my variables (which are holding the correct values.
For reference, the values are : 55 Syllables, 40 Words, 4 Sentences, as given by the instructor. The values my program produces when ran is a Legibility Index of 112.
Am I missing some brackets, or what?
I'm stumped!
Right off the bat, from the names (which include the word count) I'd guess that countSylb, countSent and countWord are declared as integers, and therefore your divisions are doing integer arithmetic, truncating the decimal portions. Cast them to floats and that should fix it.
legibIndex = 206.385 - 84.6 * ((float)countSylb / ((float)countWord) -
1.015 * (((float)countWord / ((float)countSent);
You probably have a data type issue where you're rounding because int/int = int instead of float.
If you cast to float or declare as float it should help you.
Works here. Perhaps you're doing integer division instead of float division:
>>> def leg(syl, wor, sen):
... return 206.835 - 84.6 * (float(syl) / wor) - 1.015 * (float(wor) / sen)
...
>>> print leg(55, 40, 4)
80.36
If your calculations inside the brackets are pure integer the calculation will drop the decimal parts and be rounded down ( same as using floor() ) which obviously will alter the result.
When I run this in Haskell, I get the right answer (80.36000000000001).
I think the problem is that (# syllables/# words) comes to 1 if you're using integer arithmetic. If you make sure that you perform the calculation using floating point arithmetic (so # syllables/# words = 1.375), you should get the right answer out.
As pointed out above, your count variables are likely whole number integers, but your expression contains literal floating point numbers. Casting those ints into floats will give the correct value. You must also make sure that what you are storing the expression's result in (legibIndex) is also of type float.
It's probably an operator precedence issue. To be sure, group the things you think should happen first more than you already have.
Edit No, it isn't; using C's operator precedence I get 80.36. I expect sparks was right (and the first off the mark) that it's a data type problem and you're running into premature rounding.

Resources