In binary if LSB:
This pattern works because binary inherently encodes numbers as sums of powers of 2, making divisibility checks straightforward!
A number is divisible by 2 if its last bit is 0.
$$(6_{10} = 110_2)$$:
$$(7_{10} = 111_2)$$:
A number is divisible by 4 if its last 2 bits are 00.
$$(12_{10} = 1100_2)$$:
$$(14_{10} = 1110_2)$$:
A number is divisible by 8 if its last 3 bits are 000.
$$(24_{10} = 11000_2)$$:
$$(26_{10} = 11010_2)$$:
A number is divisible by $$(2^n)$$ if its last $$(n)$$ bits are all 0.
$$(32_{10} = 100000_2)$$:
$$(36_{10} = 100100_2)$$:
In binary, numbers are represented as sums of powers of 2:
$[\text{Binary Number:} b_k b_{k-1} \dots b_2 b_1 b_0 = b_k \cdot 2^k + b_{k-1} \cdot 2^{k-1} + \dots + b_1 \cdot 2^1 + b_0 \cdot 2^0]$
The last $$(n)$$ bits of a binary number represent the portion that determines divisibility by $$(2^n)$$. If these bits are all 0, the entire number is divisible by $$(2^n)$$.
Think of binary numbers as "buckets" of powers of 2:
The last $$(n)$$ bits in binary indicate divisibility by $$(2^n)$$ because binary inherently represents values in powers of 2. Zeros in these positions mean no leftover contributions smaller than $$(2^n)$$, ensuring clean divisibility.
void main() {
char array[10] = {5, 10, 15, 20, 25, 30, 35, 40, 45, 50};
char *p = array;
p = p + (4); // Line 4
*p = *p + 5; // Line 5
p = p + (-5); // Line 6
*p = *p + 5; // Line 7
p = p + (5); // Line 8
*p = *p + 5; // Line 9
}
Which lines cause pointer faults?
&array[0] = 256
, or 0x100
in hexadecimal.char
takes up 1 byte in memory.Initial Setup:
{5, 10, 15, 20, 25, 30, 35, 40, 45, 50}
.char *p = array
means p
initially points to array[0]
, which is at address 0x100
.Line 4 (p = p + (4);
):
p
is moved 4 positions forward, so it points to array[4]
, which is at address 0x104
.Line 5 (*p = *p + 5;
):
*p
modifies the value at array[4]
. Initially, array[4] = 25
. After adding 5, array[4] = 30
.p = 0x104
and *p = 30
.Line 6 (p = p + (-5);
):
p
moves back 5 positions, so it now points to array[0]
at address 0x100
.Line 7 (*p = *p + 5;
):
*p
modifies the value at array[0]
. Initially, array[0] = 5
. After adding 5, array[0] = 10
.p = 0x100
and *p = 10
.Line 8 (p = p + (5);
):
p
moves forward 5 positions, so it now points to array[5]
at address 0x105
.Line 9 (*p = *p + 5;
):
*p
modifies the value at array[5]
. Initially, array[5] = 30
. After adding 5, array[5] = 35
.p = 0x105
and *p = 35
.After line 5: p = 0x104, *p = 30, a[4] is modified:
p
is at address 0x104
, *p = 30
, and a[4]
(or array[4]
) is modified.After line 5: p = 0x114, *p = 35, a[5] is modified:
p
is at 0x104
, not 0x114
, and *p = 30
, not 35
.After line 9: p = 0x103, *p = 30, a[3] is modified:
p
is at 0x105
, not 0x103
, and a[3]
is not modified.After line 7: p = 0x0fe, *p = Unknown, Index out of bounds:
p
is at 0x100
, not 0x0fe
, and *p = 10
, so it’s not out of bounds.After line 7: p = 0x100, *p = 0, a[0] is modified:
p = 0x100
, but *p = 10
, not 0. So this statement is incorrect.After line 9: p = 0x114, *p = 35, a[5] is modified:
p = 0x105
, not 0x114
, though a[5]
is modified.After line 7: p = 0x0ff, *p = Unknown, Index out of bounds:
p
is at 0x100
, not 0x0ff
, so this statement is incorrect.The only correct statement is:
This matches the memory and pointer operations as detailsed above.
x = *((short*)array+13)
where array = 0x1000
, Little EndianMemory Layout: The memory contents are laid out byte by byte as shown in the question. Given that the system is little-endian, the least significant byte is stored first.
Memory contents (in bytes):
Address 0 1 2 3
0x1000 00 01 02 03
0x1004 04 05 06 07
0x1008 08 09 0a 0b
0x100c 0c 0d 0e 0f
0x1010 10 11 12 13
0x1014 14 15 16 17
Pointer Arithmetic:
*((short*)array + 13)
means we are treating the memory starting from array
(address 0x1000
) as an array of short
values (2 bytes each).short*
type moves by 2 bytes) means we are accessing the bytes at address 0x1000 + 13 * 2 = 0x101A
.Little Endian Interpretation:
0x101A
is formed by the two bytes at 0x101A
and 0x101B
(little-endian means the least significant byte is stored first).0x101A
, the value is 1a
, and at 0x101B
, the value is 1b
.Forming the Result:
1a
) comes first, followed by the more significant byte (1b
).0x1b1a
(in hex).Thus, x
equals 0x1b1a in hexadecimal.
If you are given a multidimensional array.
*(short*)(array_c + 2);
Lets try to explain it in terms of pointer manipulation and how many bytes will be read
Key idea:The +2 in the expression is pointer math based on the type of array_c a char*
The number of bytes you read once the pointer is calculated is based on the cast type
array_c + 2
:
array_c
is a pointer to char
array_c
moves the pointer 2 bytes ahead because pointer arithmetic takes the size of the data type into account (in this case, char
is 1 byte).char
array (array_c[2]
).(short*)
:
array_c + 2
(which is of type char*
) to a short*
.*(short*)
:
*
dereferences the short*
pointer, meaning it reads the value stored at the memory location array_c + 2
, but since the pointer has been cast to a short*
, it reads 2 bytes of data starting from the location array_c + 2
.In the expression array[i][j]
for a 2D array int array[16][16]
, we can break down how the memory is accessed and calculate which byte is being accessed relative to the start of the array (array[0][0]
).
Memory Layout for 2D Arrays:
array[16][16]
are stored in row-major order. This means that elements of each row are stored contiguously in memory.int
), the size of each element (in most systems) is 4 bytes since an int
typically occupies 4 bytes of memory.Array Access:
array[i][j]
accesses the element at row i
and column j
of the 2D array.Memory layout for int array[16][16] (Row-Major Order):
array[0][0] array[0][1] array[0][2] ... array[0][15]
array[1][0] array[1][1] array[1][2] ... array[1][15]
array[2][0] array[2][1] array[2][2] ... array[2][15]
...
array[15][0] array[15][1] array[15][2] ... array[15][15]
array[i][j]
, you first need to skip i
rows and then skip j
elements within the i
th row.The total number of elements to skip before reaching array[i][j]
is:
$$[\text{Offset in elements} = i \times 16 + j]$$
This gives you the total number of elements before array[i][j]
.
To convert this to a byte offset, multiply by the size of each element (which is 4 bytes for int
):
$$[\text{Byte offset} = (i \times 16 + j) \times 4]$$
This is the number of bytes from the start of array[0][0]
to the element array[i][j]
.
array[2][3]
, the byte offset is:
$$[\text{Byte offset} = (2 \times 16 + 3) \times 4 = (32 + 3) \times 4 = 35 \times 4 = 140 \text{ bytes}]$$
So, array[2][3]
is 140 bytes from the start of array[0][0]
.Group of answer choices
12 (2’s complement), 12 (Sign-mag) |
---|
12 (2’s complement), 12 (Sign-mag) |
11 (2’s complement), 13 (Sign-mag) |
13 (2’s complement), 11 (Sign-mag) |
14 (2’s complement), 12 (Sign-mag) |
Let's break down how many bits are required to represent the number -1897 in both 2’s complement and sign-magnitude.
In 2’s complement, to represent a negative number, we first find its binary form as a positive number, then invert all the bits and add 1.
Step-by-step process:
Hence, 12 bits are needed for 2's complement.
In sign-magnitude, one bit is used for the sign (0 for positive, 1 for negative), and the remaining bits represent the magnitude of the number (the absolute value).
So, the correct option is:
12 (2’s complement), 12 (Sign-mag).
Sure! Let's break this down step-by-step, showing exactly how the expression works in binary. The goal is to set every 10th bit in a 32-bit integer to 1, starting from the least significant bit (LSB).
Setting every 10th bit of int x to 1 (starting from the LSB) e.g., every 4th bit …0001001001 ? Legal ops: ! ~ & ^ | << >>
x
We are dealing with a 32-bit integer. For each bit position, the index starts at 0 from the LSB (rightmost bit) to the MSB (leftmost bit).
So we want to set these specific bits to 1.
We need to create a mask that has 1s in the 10th, 20th, and 30th bit positions (binary positions 9, 19, and 29, respectively).
This is done using left shifts (<<
) and OR (|
) operations.
1 << 9
: This shifts the number 1
(which is 00000001
in binary) to the left by 9 positions.
00000000 00000000 00000010 00000000
(in 32 bits).1 << 19
: This shifts the number 1
to the left by 19 positions.
00000000 00000100 00000000 00000000
(in 32 bits).1 << 29
: This shifts the number 1
to the left by 29 positions.
00100000 00000000 00000000 00000000
(in 32 bits).Now, we combine these using the OR (|
) operation.
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
So, the result of the bitwise OR between these shifted values is:
00000000 00000000 00000010 00000000 (1 << 9)
| 00000000 00000100 00000000 00000000 (1 << 19)
| 00100000 00000000 00000000 00000000 (1 << 29)
-----------------------------------------
00100000 00000100 00000010 00000000 (final mask)
This gives us the binary mask with 1s at the 9th, 19th, and 29th positions, and 0s elsewhere.
x
Once the mask is created, we need to apply it to the integer x
using the bitwise OR (|
) operation. This ensures that the bits in the positions we are interested in (9, 19, and 29) are set to 1, while the rest of the bits in x
remain unchanged.
For example, if x
is:
x = 00000000 00000000 00000000 00000000 (initial value of x)
We apply the OR operation between x
and the mask:
00000000 00000000 00000000 00000000 (x)
| 00100000 00000100 00000010 00000000 (mask)
-------------------------------------------
00100000 00000100 00000010 00000000 (result)
Now, the bits at positions 9, 19, and 29 are set to 1 in x
.
The full expression to achieve this in a 32-bit integer x
is:
x = x | (1 << 9 | 1 << 19 | 1 << 29);
1 << 9
shifts 1 to the 9th position (10th bit).1 << 19
shifts 1 to the 19th position (20th bit).1 << 29
shifts 1 to the 29th position (30th bit).x
.By using this approach, you can set every 10th bit (starting from the LSB) in a 32-bit integer x
to 1.
sizeof(my_struct)
and s_array
Memory Layoutmy_struct
Fieldsmy_struct
s_array
typedef struct{
short fld0;
double fld1;
float fld2[6];
} my_struct;
my_struct s;
my_struct s_array[3];
// Consider int: 4bytes, char: 1byte, float: 4bytes
// double: 8bytes long: 8bytes pointer: 8bytes
sizeof(my_struct)
and s_array
Memory LayoutTo determine the size of the structure my_struct
and the memory occupied by the array s_array
, we must consider the alignment and padding rules of the system architecture.
my_struct
FieldsGiven typedef struct
:
short fld0
: Size is 2 bytes.
double
field next, padding will be added.double fld1
: Size is 8 bytes.
float fld2[6]
: Size is ( 6 \times 4 = 24 ) bytes.
my_struct
my_struct
with padding:+------------+---------+
| fld0 | padding | (2 bytes for short + 6 bytes padding)
+------------+---------+
| fld1 | (8 bytes for double)
+-----------------------+
| fld2[0] | (4 bytes for each float)
| fld2[1] |
| fld2[2] |
| fld2[3] |
| fld2[4] |
| fld2[5] |
+-----------------------+
fld0
(short): Starts at offset 0, uses 2 bytes.
fld1
) requires alignment to 8 bytes, so 6 bytes of padding are added after fld0
.fld1
(double): Starts at offset 8, uses 8 bytes.fld2[6]
(float array): Starts at offset 16, uses ( 6 \times 4 = 24 ) bytes.my_struct
:fld0
) ( + 8 + 24 = 40 ) bytes.double
).sizeof(my_struct) = 40 bytes
s_array
s_array[3]
contains 3 instances of my_struct
.s_array
= ( 3 \times sizeof(my_struct) = 3 \times 40 = 120 ) bytes.my_struct
(40 bytes):Offset Field Size
0 fld0 2 bytes
2 padding 6 bytes
8 fld1 8 bytes
16 fld2[0] 4 bytes
20 fld2[1] 4 bytes
24 fld2[2] 4 bytes
28 fld2[3] 4 bytes
32 fld2[4] 4 bytes
36 fld2[5] 4 bytes
s_array[3]
(120 bytes):Each struct is laid out consecutively in memory:
Struct 0:
0 fld0 2 bytes
2 padding 6 bytes
8 fld1 8 bytes
16 fld2[0] 4 bytes
... fld2[5] 4 bytes
40 End of struct 0
Struct 1:
40 fld0 2 bytes
... (same layout)
80 End of struct 1
Struct 2:
80 fld0 2 bytes
... (same layout)
120 End of struct 2
sizeof(my_struct)
: 40 bytess_array[3]
: 120 bytes