I have an 8 digit hexadecimal number of which I need certain digits to be either 0 or f. Given the specific place of the digits is there a quick way to generate the hex number with those places "flipped" to f. For example:
flip_digits(1) = 0x000000f
flip_digits(1,2,4) = 0x0000f0ff
flip_digits(1,7,8) = 0xff00000f
I'm doing this on an embedded device so I can't call any math libraries, I suspect it can be done with just bit shifts but I can't quite figure out the method. Any sort of solution (Python, C, Pseudocode) will work. Thanks in advance.
result = 0
for i in inputs:
result |= 0xf << ((i - 1) << 2)
You can define eight named variables, each with a given nibble set all bits on:
unsigned n0 = 0x0000000f;
unsigned n1 = 0x000000f0;
unsigned n2 = 0x00000f00;
unsigned n3 = 0x0000f000;
unsigned n4 = 0x000f0000;
unsigned n5 = 0x00f00000;
unsigned n6 = 0x0f000000;
unsigned n7 = 0xf0000000;
Then you can use the bitwise-or to combine them:
unsigned nibble_0 = n0;
unsigned nibbles_013 = n0 | n1 | n3;
unsigned nibbles_067 = n0 | n6 | n7;
If you want to combine them at runtime, it would likely be simplest to store the constants in an array so they can be accessed more easily (e.g., n[0] | n[6] | n[7]).
Related
I need to write the function to check if the number binary representation doesn't contain duplications. For example, the function must return true if N equals to 42, because bin(42) equals to 101010, but if N equals to 45 the function must return false, because of binary representation of 45 which equals to 101101 and which contains duplicates 11.
This allows only bits that alternate between 0 and 1, plus possibly leading zeros.
One way to check this is to look at (N << 2) | N. If N is of the correct form, then this is equal to N << 2, except for bit 0 or 1. We can compensate for that as follows:
unsigned N2 = N << 2;
return (N | N2) <= (N2 | 2);
I'm trying to make program which counts the number of odd digits in integer using Haskell. I have ran into problem with checking longer integers. My program looks like this at the moment:
oddDigits:: Integer -> Int
x = 0
oddDigits i
| i `elem` [1,3,5,7,9] = x + 1
| otherwise = x + 0
If my integer is for example 22334455 my program should return value 4, because there are 4 odd digits in that integer. How can I check all numbers in that integer? Currently it only checks first digit and returns 1 or 0. I'm still pretty new to haskell.
You can first convert the integer 22334455 to a list "22334455". Then find all the elements satisfying the requirement.
import Data.List(intersect)
oddDigits = length . (`intersect` "13579") . show
In order to solve such problems, you typically split this up into smaller problems. A typical pipeline would be:
split the number in a list of digits;
filter the digits that are odd; and
count the length of the resulting list.
You thus can here implement/use helper functions. For example we can generate a list of digits with:
digits' :: Integral i => i -> [i]
digits' 0 = []
digits' n = r : digits' q
where (q, r) = quotRem n 10
Here the digits will be produced in reverse order, but since that does not influences the number of digits, that is not a problem. I leave the other helper functions as an exercise.
Here's an efficient way to do that:
oddDigits :: Integer -> Int
oddDigits = go 0
where
go :: Int -> Integer -> Int
go s 0 = s
go s n = s `seq` go (s + fromInteger r `mod` 2) q
where (q, r) = n `quotRem` 10
This is tail-recursive, doesn't accumulate thunks, and doesn't build unnecessary lists or other structures that will need to be garbage collected. It also handles negative numbers correctly.
I cant understand how the swap function does the swapping
void swap(char* p, char* q)
{
char tmp = *p;
*p = *q;
*q = tmp;
}
int h(char* s, int n)
{
if (s[n]==0) {
return 0;
}
if (s[n+1]==0) {
return 1;
}
int k = h(s+1,n+1);
swap(s,s+k+1); //how does this work?
return k+2;
}
void func3()
{
char s[] = "intro to cs";
int x = h(s,0);
printf("x = %d\n", x);
printf("s = %s\n", s);
}
swap(s,s+k+1); //how does this work?
Here s is a pointer to a chunk of memory that contains a sequence of characters. The swap function takes two pointers to characters, and takes the values pointed to and swaps them. In the following example,
|-------|
s | 'i' |
|-------|
s+1 | 'n' |
|-------|
s+2 | 't' |
|-------|
s+3 | 'r' |
|-------|
s+4 | 'o' |
|-------|
...
you could swap the characters 'i' and 'r' by calling swap(s, s+3). This will take the contents of address s ('i')and store it in address s+3, and vice versa. In your example, you are using pointer arithmetic. s is a contiguous chunk of memory containing characters (like an array), so you could get the ith character in the sequence by doing s[i], or equivalently *(s + i). s is the base address of the string, so to get the address of character 'r', we simply add 3 to the base address (s)
I am going over some revision and I came across a question that asked what is 10011001 in signed integer and unsigned. I know the unsigned integer is 153 because there are no negatives in unsigned integers, but am I correct to say the signed integer of 10011001 is -153 or am I making a mistake ?
This difference between unsigned and signed number is that one of the bit is used to indicate positive or negative number.
So in your example you have 8 bits.
If I treat is as signed, then I have 7 bits to work with: 2^7
000 0000 = 0
111 1111 = 127
001 1001 = 25 then the most significant bit cause the following calculation to occurred.
(25 - 128) = -103
If I use all 8 bits then I unsigned bits to work with: 2^8
0000 0000 = 0
1111 1111 = 255
1001 1001 = 153
Here is code to demonstrate the answer:
char *endptr;
char binary[11] = "10011001"; // need an extra char for the termination
char x = (char)strtol(binary, &endptr, 2);
unsigned char y = (unsigned char)strtol(binary, &endptr, 2);
printf("%s to signed char (1 byte): %i\n", binary, (short)x);
printf("%s to unsigned char (1 byte): %u\n", binary, y);
Output:
I know it's associative and commutative:
That is,
(~x1 + ~x2) + ~x3 = ~x1 + (~x2 + ~x3)
and
~x1 + ~x2 = ~x2 + ~x1
However, for the cases I tried, it doesn't seem to be distributive, i.e,
~x1 + ~x2 != ~(x1 + x2)
Is this true? Is there a proof?
I have C code as follows:
int n1 = 5;
int n2 = 3;
result = ~n1 + ~n2 == ~(n1 + n2);
int calc = ~n1;
int calc0 = ~n2;
int calc1 = ~n1 + ~n2;
int calc2 = ~(n1 + n2);
printf("(Part B: n1 is %d, n2 is %d\n", n1, n2);
printf("Part B: (calc is: %d and calc0 is: %d\n", calc, calc0);
printf("Part B: (calc1 is: %d and calc2 is: %d\n", calc1, calc2);
printf("Part B: (~%d + ~%d) == ~(%d + %d) evaluates to %d\n", n1, n2, n1, n2, result);
Which gives the following output:
Part B: (n1 is 5, n2 is 3
Part B: (calc is: -6 and calc0 is: -4
Part B: (calc1 is: -10 and calc2 is: -9
Part B: (~5 + ~3) == ~(5 + 3) evaluates to 0
[I know this is really old, but I had the same question, and since the top answers were contradictory...]
The one's compliment is indeed distributive over addition. The problem in your code (and Kaganar's kind but incorrect answer) is that you are dropping the carry bits -- you can do that in two-s compliment, but not in one's compliment.
Whatever you use to store the sum needs more memory space than what you are summing so that you don't drop your carry bits. Then fold the carry bits back into the number of bits you are using to store your operands to get the proper sum. This is called an "end-around carry" in one's compliment arithmetic.
From Wikipedia article ( https://en.wikipedia.org/wiki/Signed_number_representations#Ones'_complement ):
To add two numbers represented in this system, one does a conventional binary addition, but it is then necessary to do an end-around carry: that is, add any resulting carry back into the resulting sum. To see why this is necessary, consider the following example showing the case of the addition of −1 (11111110) to +2 (00000010):
binary decimal
11111110 –1
+ 00000010 +2
─────────── ──
1 00000000 0 ← Not the correct answer
1 +1 ← Add carry
─────────── ──
00000001 1 ← Correct answer
In the previous example, the first binary addition gives 00000000, which is incorrect. The correct result (00000001) only appears when the carry is added back in.
I changed your code a bit to make it easier to do the math myself for a sanity check and tested. It may require a bit more thought using signed integer datatypes or to account for end-around borrowing instead of carrying. I didn't go that far since my application is all about checksums (i.e. unsigned, and addition only).
unsigned short n1 = 5; //using 16-bit unsigned integers
unsigned short n2 = 3;
unsigned long oc_added = (unsigned short)~n1 + (unsigned short)~n2; //32bit
/* Fold the carry bits into 16 bits */
while (oc_added >> 16)
oc_added = (oc_added & 0xffff) + (oc_added >> 16);
unsigned long oc_sum = ~(n1 + n2); //oc_sum has 32 bits (room for carry)
/* Fold the carry bits into 16 bits */
while (oc_sum >> 16)
oc_sum = (oc_sum & 0xffff) + (oc_sum >> 16);
int result = oc_added == oc_sum;
unsigned short calc = ~n1;
unsigned short calc0 = ~n2;
unsigned short calc1 = ~n1 + ~n2; //loses a carry bit
unsigned short calc2 = ~(n1 + n2);
printf("(Part B: n1 is %d, n2 is %d\n", n1, n2);
printf("Part B: (calc is: %d and calc0 is: %d\n", calc, calc0);
printf("Part B: (calc1 is: %d and calc2 is: %d\n", calc1, calc2);
printf("Part B: (~%d + ~%d) == ~(%d + %d) evaluates to %d\n", n1, n2, n1, n2, result);
Check out the Wikiepdia article on Ones' complement. Addition in one's complement has end-carry around where you must add the overflow bit to the lowest bit.
Since ~ (NOT) is equivalent to - (NEGATE) in ones' complement, we can re-write it as:
-x1 + -x2 = -(x1 + x2)
which is correct.
One's compliment is used to represent negative and positive numbers in fixed-width registers. To distribute over addition the following must apply: ~a + ~b = ~(a + b). The OP states + represents adding 'two binary numbers'. This itself is vague, however if we take it to mean adding unsigned binary numbers, then no, one's compliment is not distributive.
Note that there are two zeroes in one's compliment: all bits are ones or all bits are zeroes.
Check to see that ~0 + ~0 != ~(0 + 0):
~0 is zero. However, ~0 is represented by all ones. Adding it to itself is doubling it -- the same as a left shift -- and thus introduces a zero in the right hand digit. But that is no longer one of the two zeroes.
However, 0 is zero, and 0 + 0 is also zero, and thus so is ~(0 + 0). But the left side isn't zero, so to distribution does not hold.
On the other hand... Consider two's compliment: flip all bits and add one. If care is taken to treat negatives in one's compliment specially, then that version of 'binary addition' is similar to two's compliment and is distributive as you end up with a familiar quotient ring just like in two's compliment.
The aforementioned Wikipedia article has more details on handling addition to allow for expected arithmetic behavior.
From De Morgan's laws:
~(x1 + x2) = ~x1 * ~x2