Alef Veld <al**@xs4all.nlwrites:
1. When shifting bits, is there a certain bit size you are working on
(byte or more?) or can you define this yourself as with a bit field in
a struct. I mean i don't have to define a bit field when i shift a
number like 4 i can just do it. How many bits am i working with
here. Is that 32 bits for an int and a byte for a char ?
There are two cases. If the expression being shifted is of a type
"smaller" than plain int, the value is promoted and it is the
promoted value that is shifted. When the expression being shifted is
"bigger" than plain int the type is left alone.
I put "smaller" and "bigger" in quotes because the standard uses quite
a lengthy set of rules based a notion called the conversion rank of
the type. The upshot is that the value is preserved including, of
course, the sign but not necessarily the signedness. It is easy to
think that:
unsigned char x = 0xff;
x << 24
will be shifting an unsigned int but it won't. Because the type int
can represent all the possible values of unsigned char it is a plain
(signed) int that gets shifted. This matters, because the result of a
signed shift can be undefined (and may well be in this case).
If x had been declared unsigned int, the shift would have been an
unsigned one because unsigned int has the same conversion rank as int.
Shifts of "bigger" types are done without any conversion so 1ul << 7
is a shift of an unsigned long value.
2. How far can you shift or divide ? To the max of the power of 2
within the boundaries of a unsigned int ? (i'm only doing shifts on
unsigned ints for now)
With an unsigned type you can shift by up to (but not equal to) the
number of value bits in the type. It not worth remembering the rules
for signed types since bit operations in signed types are generally a
bad idea. (The rules are that right shifts of negative values are
implementation defined, and left shifts are undefined if the resulting
value can't be represented. In the example above, if 256 * pow(2, 24)
is INT_MAX (probable on a 32 bit machine) the result will be
undefined.)
3. is the MSB always the left byte and the LSB always the right byte
(probably differs on endianness) ? Why are these 2 important anyway
?
Shifts are defined in terms of what they do to the value (multiplying
and dividing by powers of 2). The endianness has no effect at all.
4. When i shift 4 times, am i performing a decimal_number * 4 or am i
doing a decimal_number * decimal_number * decimal_number *
decimal_number ?
A left shift by 4 bits has the effect of multiplying the value being
shifted by 16. I does not, as you might be suggesting, multiply it by
4, nor does it raise it to the 4th power.
(The term "decimal" refers to a way of representing a number. It says
nothing about the value. decimal_number * 4 would be better expressed
as number * 4 -- the "decimal" part is just confusing.)
5. What does this code do ? :
if(sscanf(t_addr, "%d.%d.%d.%d",
&octet1, &octet2, &octet3, &octet4) < 1)
exit_error(-1);
return((octet1 << 24) | (octet2 << 16) | (octet3 << 8) | octet4);
Looks like trouble. You can't tell with certainty what the shifts do
because we don't know the types of the octet1-4 variables. They are
set by a sscanf format of %d so they should int. In that case the
shifts are signed you maybe in all sorts of trouble. If they are not
int objects, then the sscanf call is wrong.
IP address calculations should be done with unsigned long variables or
with unsigned long casts where needed.
I'm focussing on the last line here. The shifts would display to me
the logic of an 32bit ip address but would when one entered 192 for
the first octet the decimal also not get shifted by 24 getting 4608
?which makes not a lot of sense to me and i don't quite understand
what the reasoning for that is.
I don't follow. If x << 24 is properly defined it has the effect of
multiplying by pow(2, 24) (2 to the power 24). Typically, that will
put the value of x in the MSB of a 4-byte value.
I'm used to working with ip addresses so for me i count from 128 and
start at 1. When working with more then 1 byte, do you just go to 256
512 1024 etc ? I tried a little program and it gave me this list after
the last number it went to 0 again. Is that the maximum amount of
multiplications that can be done ?
If you post the code, I am sure it can be explained but I can't follow
what you are asking.
--
Ben.