Why it takes only the last 4 bits in my following example? - c

#include<stdio.h>
int main()
{
char c=48;
int i, mask=01;
for(i=1; i<=5; i++)
{
printf("%c", c|mask);
mask = mask<<1;
}
return 0;
}
I am learning for an exam, and this was a solved exercise with the answer: 12480 because %c takes only the last 4 bits. I don't understand why, as I know that sizeof char is 1 byte.

Let's look at the binary representation of 48:
2^ 7 6 5 4 3 2 1 0
---------------
0 0 1 1 0 0 0 0
The last 4 bits are not set. On the first 4 iterations of the loop, the mask sets one of those bits in the result, and the result reflects the change. On the last iteration, the mask is setting a bit which is already set, so there is no change for the last character printed.
As for what is being printed, in ASCII 48 is the character code for 0. The following digits are in order after that one. When you mask in the values for the first 4 iterations, because none of the bits in the value 48 are set in the mask, it is effectively the same as adding. So the first 4 characters printed have ASCII values 49 (1), 50 (2), 52 (4), and 56 (8).

Character code 48 is usually 0. When it's or'd with one, it prints digit 1. Then it prints the digits 2, 4, 8. Finally, 48|16 = 48, so it prints 0.

It takes them all, however the last time around you or that 1 with a bit that already is 1 (48 is 110000 in binary)

Related

Data types - overflow

If we consider overflow in long long unsigned int, after overflow it will generate a positive number always.
for example the below code generate positive numbers when a is not multiple of 2.
but if a is multiple of 2 like 2,4,6... after overflow it prints 0.
why?
#include<stdio.h>
#define LLU long long unsigned int
#define a 5
int main()
{
LLU t=2;
int i=0;
for(i=0; i<100; i++)
{
t=t*a;
printf("%llu\n",t) ;
}
return 0 ;
}
The reason the repeated multiplication by 2 yields zero on overflow is the same as the reason why repeated multiplication of 1 by 10 yields zero when the number of digits is fixed: every multiplication produces a binary number composed of a single 1, and all zeros after it.
Here is how it works for an 8-bit number:
Power of 2 Decimal Binary Last 8 bits
---------- ------- ---------- ------------
0 1 1 00000001
1 2 10 00000010
2 4 100 00000100
3 8 1000 00001000
4 16 10000 00010000
5 32 100000 00100000
6 64 1000000 01000000
7 128 10000000 10000000
8 256 100000000 00000000 <<== 1 "falls off the end"
Note that the last eight bits of the eights power of 2 are all zeros, so if we had only 8 bits, we would get zero after 8-th multiplication. All subsequent multiplications would yield zero as well.
The same exact thing is going on with LLU, except it takes 64 multiplications to get the number to overflow to zero.
Edit: All even numbers have zero at the end of their binary representation, for the same reason all decimal numbers divisible by ten have at least one zero at the end of their decimal representation. Therefore, if you start with any even number, not necessarily a power of two, each multiplication would increase the number of zeros at the end of the number by the number of zeros in the number being multiplied. For example, if you multiply by 14, which is 1110 in binary, the result would get an additional zero at the end. If you multiply by 12, which is 1100, you would get two additional zeros.
The overall result is the same as with multiplying by two: since each multiplication increases the number of tail zeros by at least one, you would end up with all zeros in at most 64 multiplications for LLU.

C: Finding closest number to the first without repeating digits from the second number?

I read two numbers, both int.
What I need to do is do print the number higher than but closest to the first number, such as 378, but which doesn't contain any of the digits from the second number, for example, 78.
Input: 378 78, output: 390 because that's the lowest number above 378 that doesn't contain any of the digits of 78.
Input: 3454 54, output: 3600 because 3600 is the first closest that doesn't contain 5 or 4, the digits of 54.
I am trying to do this by getting the latest modulus digits of the first number, from the length of the second. For example:
378 78
378 mod 100 == 78, then compare 78 and 78 digits, and if there is same digit move on to 379, then check for 379 mod 100 == 79. When comparing 79 and 78, 7 is the same digit.
And so on until we get 390 for example. This should work for all N-size numbers.
Here is what I've done so far...and that's almost nothing.
#include <stdio.h>
int main()
{
int number1, number2;
int closest = number1 + 1;
scanf("%d %d",&number1,&number2);
int count_modulus = 1;
while(number2)
{
count_modulus = count_modulus * 10;
number2 = number2 / 10;
}
int mod = count_modulus;
int n2 = number2;
while(number1)
{
int remain = number1 % mod;
while(remain)
{
if((remain % 10 == number2 % 10))
{
}
else
{
}
}
}
printf("%d",closest);
return 0;
}
I'm not entirely convinced that your modulo method is going to work since, if you start with 7823 and 78, then 7823 mod 100 gives you 23 which has no digits in common with 78 even though 7823 does.
But, even if I've misunderstood the specification and it did work, I think there's a better way. First things first, how to score a number based on what digits it contains.
Provided your integers have at least ten bits (and they will, since the standard mandates a range that requires sixteen), you can just use a bit mask with each bit representing whether the number holds a digit. We can use a normal int for this since ten bits will get us nowhere near the sign bit that may cause us issues.
The code for scoring a number is:
// Return a bitmask with the bottom ten bits populated,
// based on whether the input number has a given digit.
// So, 64096 as input will give you the binary value
// 000000 0000111010
// <-unused ^ ^ ^ ^
// 9876543210 (digits)
int getMask (int val) {
int mask = 0; // All start at 0
while (val > 0) { // While more digits
mask = mask | (1 << (val % 10)); // Set bit of digit
val = val / 10; // Move to next digit
}
return mask;
}
The "tricky" bit there is the statement:
mask = mask | (1 << (val % 10));
What it does it get the last digit of the number, with val % 10 giving you the remainder when dividing val by ten. So 123 % 10 gives 3, 314159 % 10 gives 9 and so on.
The next step is to shift the binary 1 that many bits to the left, with 1 << (val % 10). Shifting a 1-bit four places left would give you the binary value 10000 so this is simply a way to get the 1-bit in the correct position.
Finally, you bitwise-OR the mask with that calculated value, effectively setting the equivalent bit in the mask, keeping in mind that the bits a | b gives you 1 if either or both a and b are 1.
Or you can check out one of my other answers here for more detail.
So, I hear you ask, how does that bitmask help us to find numbers with no common digits. Well, that where the AND bitwise operator & comes in - this only gives you a 1 bit if both input bits are 1 (again, see the link provided earlier for more detail on the bitwise operators).
Once you have the bitmask for your two numbers, you can use & with them as per the following example, where there are no common digits:
Number Bitmask
9876543210
------ ----------------
314159 000000 1000111010
720 000000 0010000101
----------------- AND(&)
000000 0000000000
You can see that, unless the bit position has a 1 for both numbers, the resultant bit will be 0. If any numbers are in common at all, it will be some non-zero value:
Number Bitmask v
9876543210
------ -----------------
314159 000000 1000111010
320 000000 0000001101
----------------- AND(&)
000000 0000001000
^
The bit representing the common digit 3.
And that leads us to the actual checking code, something relative easy to build on top of the scoring function:
#include <stdio.h>
int main (int argc, char *argv[]) {
// Default input numbers to both zero, then try
// to get them from arguments.
int check = 0, exclude = 0, excludeMask;
if (argc > 1)
check = atoi(argv[1]);
if (argc > 2)
exclude = atoi(argv[2]);
// Get the mask for the exclusion number, only done once.
excludeMask = getMask (exclude);
// Then we loop, looking for a mask that has no
// common bits.
printf ("%d -> ", check);
//check++;
while ((excludeMask & getMask (check)) != 0)
check++;
printf ("%d\n", check);
return 0;
}
The flow is basically to get the numbers from the arguments, work out the bitmask for the exclusion number (the one that has the digits you don't want in the result), then start looking from the check number, until you find one.
I've commented out the initial check++ since I'm not sure whether you really wanted a higher number than the one given, or whether 123 with an exclusion of 98 should give you the actual starting number of 123. If not, just uncomment the line.
And there you have it, as shown in the following transcript, which includes your test data amongst other things:
$ ./myprog 378 78
378 -> 390
$ ./myprog 3454 54
3454 -> 3600
$ ./myprog 123 98 # would give 124 if 'count++' uncommented
123 -> 123
$ ./myprog 314159 6413
314159 -> 500000
It does have one potentially fatal flaw but one that's easy enough to fix if you check the exclusion bitmask before you start looking for. I'll leave that as an exercise for the reader, but just think about what might happen with the following command:
$ ./myprog 1 154862397
And, of course, if you want to go the other way (lower numbers), it's a matter of decrementing check rather then incrementing it. You may also need to get a bit smarter about what you want to happen if you go negative, such as with:
$ ./myprog 1 102
The code as it currently stands may not handle that so well.

bitwise-and with HEX and CHAR in C

I'm really getting frustrated here. Trying to implement the CRC-CCITT algorithm and I found a very nice example on an Internet site.
There is one line whose output I completely don't understand:
unsigned short update_crc_ccitt( unsigned short crc, char c){
[...]
short_c = 0x00ff & (unsigned short) c;
[...]
}
I want to calculate the CRC of the "test" string "123456789". So in the first run the char 'c' is 1. From my understanding short_c from the first run should be equal to 1 as well, but when I print it to the console, I get short_c = 49 for c = 1. How?
0x00ff in binary is: 1 1 1 1 1 1 1 1
char 1 in binary is: 0 0 0 0 0 0 0 1
bitand should be : 0 0 0 0 0 0 0 1
Where is my mistake?
The character 1 has ASCII code 0x31 = 49. This is different from the character with ASCII code 1 (which is ^A).
You are confusing characters and numbers, basically. The first letter in the string "123456789"is the character '1', whose decimal value on most typical computers is 49.
This value is decided by the encoding of the characters, which describes how each character is assigned a numerical value which is what your computer stores.
C guarantees that the encoding for the 10 decimal digits will be in a compact sequence with no gaps, starting with '0'. So, you can always convert a character to the corresponding number by doing:
const int digitValue = digit - '0';
This will convert the digit '0' to the integer 0, and so on for all the digits up to (and including) '9'.

c: bit reversal logic

I was looking at the below bit reversal code and just wondering how does one come up with these kind of things. (source : http://www.cl.cam.ac.uk/~am21/hakmemc.html)
/* reverse 8 bits (Schroeppel) */
unsigned reverse_8bits(unsigned41 a) {
return ((a * 0x000202020202) /* 5 copies in 40 bits */
& 0x010884422010) /* where bits coincide with reverse repeated base 2^10 */
/* PDP-10: 041(6 bits):020420420020(35 bits) */
% 1023; /* casting out 2^10 - 1's */
}
Can someone explain what does comment "where bits coincide with reverse repeated base 2^10" mean?
Also how does "%1023" pull out the relevent bits? Is there any general idea in this?
It is a very broad question you are asking.
Here is an explanation of what % 1023 might be about: you know how computing n % 9 is like summing the digits of the base-10 representation of n? For instance, 52 % 9 = 7 = 5 + 2.
The code in your question is doing the same thing with 1023 = 1024 - 1 instead of 9 = 10 - 1. It is using the operation % 1023 to gather multiple results that have been computed “independently” as 10-bit slices of a large number.
And this is the beginning of a clue as to how the constants 0x000202020202 and 0x010884422010 are chosen: they make wide integer operations operate as independent simpler operations on 10-bit slices of a large number.
Expanding on Pascal Cuoq idea, here is an explaination.
The general idea is, in any base, if any number is divided by (base-1), the remainder will be sum of all the digits in the number.
For example, 34 when divided by 9 leaves 7 as remainder. This is because 34 can be written as 3 * 10 + 4
i.e. 34 = 3 * 10 + 4
= 3 * (9 +1) + 4
= 3 * 9 + (3 +4)
Now, 9 divides 3 * 9, leaving remainder (3 + 4). This process can be extended to any base 'b', since (b^n - 1) is always divided by (b-1).
Now, coming to the problem, if a number is represented in base 1024, and if the number is divided by 1023, the remainder will be sum of its digits.
To convert a binary number to base 1024, we can group bits of 10 from the right side into single number
For example, to convert binary number 0x010884422010(0b10000100010000100010000100010000000010000) to base 1024, we can group it into 10 bits number as follows
(1) (0000100010) (0001000100) (0010001000) (0000010000) =
(0b0000000001)*1024^4 + (0b0000100010)*1024^3 + (0b0001000100)*1024^2 + (0b0010001000)*1024^1 + (0b0000010000)*1024^0
So, when this number is divided by 1023, the remainder will sum of
0b0000000001
+ 0b0000100010
+ 0b0001000100
+ 0b0010001000
+ 0b0000010000
--------------------
0b0011111111
If you observe the above digits closely, the '1' bits in each above digit occupy complementay positions. So, when added together, it should pull all the 8 bits in the original number.
So, in the above code, "a * 0x000202020202", creates 5 copies of the byte "a". When the result is ANDed with 0x010884422010, we selectively choose 8 bits in the 5 copies of "a". When "% 1023" is applied, we pull all the 8 bits.
So, how does it actually reverse bits? That is bit clever. The idea is, the "1" bit in the digit 0b0000000001 is actually aligned with MSB of the original byte. So, when you "AND" and you are actually ANDing MSB of the original byte with LSB of the magic number digit. Similary the digit 0b0000100010 is aligned with second and sixth bits from MSB and so on.
So, when you add all the digits of the magic number, the resulting number will be reverse of the original byte.

K&R C Exercise Help

I've been going through the K&R C Programming Language book and I'm stuck on Exercise 2-6 which reads:
Write a function setbits(x,p,n,y) that returns x with the n bits that begin at position p set to the rightmost n bits of y, leaving the other bits unchanged.
I'm having trouble understanding the exact thing they're looking for me to do. I looked at a possible answer here, but I still don't really understand. I think it's the wording that's throwing me off. Can anyone maybe explain what they're looking for me to do in a different way? I'm hoping that different wording will help me understand what I need to do code wise.
Expounding on Avi's answer:
int i = setbits(0xAB = b10101011, 5, 3, 0xAA = b10101010);
i equals 0x93 = b10010011
Say your i = 0xAB. In binary, this is: 10101011
Let's number each of the bit positions.
Position #: 7 6 5 4 3 2 1 0
Bit: 1 0 1 0 1 0 1 1
The right-most bit (the least-significant) is position "0". The left-most (most-significant) is position "7".
So the next two values, p and n, are saying "You want to modify n bits starting at bit p." So if p=5 and n=3, you want to start at bit number 5, and in total you're modifying 3 bits. Which means bits 5, 4, 3. "101" in this example.
Position #: 7 6 5 4 3 2 1 0
Bit: 1 0 1 0 1 0 1 1
| |
---------
(Modifying these three bits)
How are we modifying them? We are replacing them. With another set of 3 bits. The three least-significant bits from y.
So here's y:
Position #: 7 6 5 4 3 2 1 0
Bit: 1 0 1 0 1 0 1 0
And the right-most bits would be bits 2, 1, 0. or the value "010". Of course, if the value of n=6, then you'd want to replace those six bits from i with "101010" - the rightmost 6 bits.
So your task is to take the specified bits from i - in this case, "101" - and replace them with the specified bits in y - "010".
If you do this, then your return value is
1 0 1 0 1 0 1 0
For example:
int i = setbits(0xAB = b10101011, 5, 3, 0xAA = b10101010);
i equals 0x93 = b10010011
We take the 3 bits beginning at position 5 in x (101), and replace them with the rightmost three bits from y (010).
That "possible answer" is just code without comments. No wonder it didn't help you.
The question (and probably the answerers) assume that you are familiar with bit fields. This sort of thing is very common in embedded programming where you control hardware registers.
Say there's a register that sets the audio volume level, among other things. It might, at the same time, let you select speakers or microphones and things like that. The bits might look like this:
ssAAAmxx -- Each letter represents a bitfield within that number. To change the volume, you have to alter the value of "AAA". Now, lets say you have something in your program that lets you adjust the volume. It's a simple control, and it always returns a number between 0 and 7. The format for that looks like this:
xxxxxAAA -- You job then, is to take the AAA bits from this (call it "y"), and set them into that number above (call it "x"), without altering the bits that aren't the A's. Thus, the problem would read, "Take the rightmost 3 bits of y, and set them into x, starting with bit 5 (remember, they count bits from zero). Then, 3 and 5 in our example become n and p in the original problem.
The operation is "bitfield insert"
The idea is that y would usually be fewer than n bits, but in case it's not, only use n. In english, the task is to insert y into x beginning at p, using a field width of n.
Replace n bits of x, starting at p position, with the rightmost n bits of y.
And probably you should take advantage of the getbits() routine in chapter 2.9
How about this?
unsigned int
setbits(unsigned int x, int p, int n, unsigned int y)
{
char buffer[65];
unsigned x1 = x >> (p + 1);
x1 <<= (p + 1);
/*
* x1 now contains all the bits before position 'p'.
*/
unsigned x2 = y & ~(~0 << n);
x2 <<= (p + 1) - n;
/*
* x2 now contains the rightmost 'n' bits of 'y', left shifted (p + 1) - n bits.
*/
unsigned x3 = x & ~(~0 << ((p + 1) - n));
/*
* x3 now contains the rightmost (p + 1) - n bits.
*/
return x1 | x2 | x3;
}

Resources