Double is double precision (Debugging 1)
Points : 30
The given C code consists of a transfermem(void *destination, void *source, int startIndex, int numBytes) function which is used to copy numBytes bytes of data starting from source address to startIndex bytes ahead of destination memory location.
But the function gives a compilation error.
You are required to remove the compilation error by editing the expression in statement at line#7 and produce the output as given below. You can not add any other expression to that statement. Also you need to explain the changes you perform.
CodeFest 10 11 20 4 15 4
Her sister is cute too ;)
CodeFest IT-BHU
9 8 7 1 2 3 4 5 6 0
Also you need to explain the output produced after removal of compilation error.
Note: Use gcc 3.4 or higher compiler. Do not use Turbo C compiler. Do not use any optional flag for compilation.
Points Distribution
- 7 points for the correction to be done in line#7.
- 8 points for explanation of first line of output.
- 12 points for explanation of second line of output.
- 3 points for explanation of last two lines of output.
Code
- #include <stdio.h>
- #include<string.h>
- void transfermem(void *destination, void *source, int startIndex, int numBytes)
- {
- while(numBytes--)
- {
- *(startIndex + destination++) = *source++;
- }
- }
- int main()
- {
- char str[20]="CodeFest \061\x30\088";
- char *str2=str;
- float i=0.15;
- int p;
- int arr1[10] = {9,8,7};
- int arr2[7] = {1,2,3,4,5,6};
- float me = 1.1, other;
- double you = 1.25;
- printf("%s %d %d %d %d %d\n",str,strlen(str),sizeof(str),sizeof(str2),sizeof("CodeFest \001\x30\088"),sizeof(i=0.25));
- other=me+i;
- if(me==1.1)
- {
- if(me+i==you)
- printf("I love U\n");
- else
- printf("I hate U\n");
- }
- else
- {
- if(other==1.35)
- printf("I am confused\n");
- else
- {
- if(other==you)
- printf("Her sister is cute too ;)\n");
- else
- printf("Damn these girls\n");
- }
- }
- transfermem(str,"IT-BHU 2010",9,6);
- transfermem(str,"",15,1);
- printf("%s\n",str2);
- transfermem(arr1,arr2,12,28);
- for(p=0;p<10;p++)
- printf("%d ",arr1[p]);
- printf("\n");
- return 0;
- }
#include <stdio.h>
#include <string.h>
void transfermem(void *destination, void *source, int startIndex, int numBytes)
{
while(numBytes--)
{
*(startIndex + destination++) = *source++;
}
}
int main()
{
char str[20]="CodeFest \061\x30\088";
char *str2=str;
float i=0.15;
int p;
int arr1[10] = {9,8,7};
int arr2[7] = {1,2,3,4,5,6};
float me = 1.1, other;
double you = 1.25;
printf("%s %d %d %d %d %d\n",str,strlen(str),sizeof(str),sizeof(str2),sizeof("CodeFest \001\x30\088"),sizeof(i=0.25));
other=me+i;
if(me==1.1)
{
if(me+i==you)
printf("I love U\n");
else
printf("I hate U\n");
}
else
{
if(other==1.35)
printf("I am confused\n");
else
{
if(other==you)
printf("Her sister is cute too ;)\n");
else
printf("Damn these girls\n");
}
}
transfermem(str,"IT-BHU 2010",9,6);
transfermem(str,"",15,1);
printf("%s\n",str2);
transfermem(arr1,arr2,12,28);
for(p=0;p<10;p++)
printf("%d ",arr1[p]);
printf("\n");
return 0;
}
Solution
Corrected Code for line 7:
*(unsigned char*)(startIndex + destination++) = *(unsigned char *)source++;
Here for the implementation of transfermem() we have to use typecasting using (unsigned char *) because pointer to void cannot be dereferenced itself. [Refer Pg 94 Ritchie]. [Correct Answer : 4 points, correct explanation: 3 points].
Common misconception:
Size of void data type is not defined or it can not be incremented. Try the following code:
int main(){
int arr[3]= {1,2,3};
void *p = arr;
printf("%p %u\n",p,sizeof(void));
printf("%p\n",++p);
return 0;
}
Explanation for Line 1 of output corresponding to Line 21 of given code:
For %s, characters from the string str is printed till the character '\0' is encountered. Here note that '\061' is a single character which represents an octal number equivalent to '1' in ASCII. Also, '\x30' is a single character which represents an hexadecimal number equivalent to '0' on ASCII. \088 are 3 characters, 8 is not an octal number. [2 points] [Refer Pg 37 Escape Sequences, Ritchie].
strlen counts the number of characters in a character array till '\0' is encountered. Hence 11. [1 point]
str is an array object of size 20. [1 point]
str2 is a character pointer and like all pointers have size of 4 bytes on 32 bit machines. [1 point]
"CodeFest \001\x30\088" is an string constant which in its internal representation is an array of characters terminated with the null character. Hence the size is 11. [2 points] [Refer Pg 44 string constant]
i being a float variable its size of 4 bytes. [1 point]
Explanation for Line 2 of output:
All real constants are of type double by default. On line 19, when 1.1 is assigned to me, the nearest representable floating point number is stored in memory for me since 1.1 is not exactly representable. Let say the error is e [Refer :http://en.wikipedia.org/wiki/Single_precision].
1.1 can not be exactly represented in double with double precision also and error is e1 (less than e).[Refer http://en.wikipedia.org/wiki/Double_precision_floating-point_format].
When me is compared with 1.1, it is first converted to double but error in me remains the same e. Hence me==1.1 returns 0. [4 points].
Use the following code snippet to see actual memory representation of floating point numbers.
float num=1.1
printf("%f : %x\n",num, *(int *)#
sizeof is an unary operator whos operand can be an expression but is not evaluated. Hence other= me+i = 1.1f + 0.15f = 1.25 (approx) and not 1.35. [2 points] [pg 204 sizeof]
0.15 like 1.1 can not be exactly represented in float/double data type. When me and i are added the value is just greater than 1.25 but as 1.25 is the nearest floating point representable value, 1.25 is stored in other.
When other is compared to you, it is automatically typecasted to double. As 1.25 is exactly representable in both float and double, there is no difference between the two values and the comparison returns 1 (true). [6 points]
Next the control goes to line no 42 with the call to transfermem function which copies the data from source to destination byte by byte from the given startIndex and up-to next numBytes.
So the next statement transfermem(str,"IT-BHU 2010",9,6); will copy the data 'IT-BHU 2010' into string CodeFest \061\x30\088 from location 9 and then the line no 43 will insert the Null character at 15th character of the string and since str2 points to str therefore the statement printf("%s\n",str2); will print the output as CodeFest IT-BHU.
Next line of output is specifically given to show you that the transfermem() function irrespective of the type of data copies the data from source to destination of the same type. [ 3 points]
Submit your solution
You need to be logged in to submit a solution.
discussions
| firebird4711 | Borland C |
| Q: | Can we use Borland C++ for C/C++ programming?? I dont have linux. |
| A: | No only gcc compiler is to be used for this problem. You can easily download Devcpp for windows from Internet, which has gcc compiler. |
| devilinprada | editing |
| Q: | is only one single line acceptable in place of original line 7 or multiple lines of code can replace it? |
| A: | You need to edit the expression mentioned in line no 7. No new expressions can be added to that statement. |
| tec | Output changes with different compiler flag |
| Q: | Got different output on line 2 with -O2 (my default CFLAG). gcc version 4.2.1 |
| A: | Do not use any optional flag while compilation. BTW, for the modified code, the output should be same. |
| architjain | Answer to above |
| Q: | Or you can copy paste it into Ms Word and then just click on bullets n numbering to remove the bullets.. ;) |
| A: | Nice Solution :) |
| bhanuvrat | how do I download the code? |
| Q: | the line numbers are getting copied along with the code.. can I get the code explicitly as a source file? |
| A: | Code that can be easily copied to be available on this page by Mar 5, 10:00 PM IST |
