Explain the following output [duplicate] - c

This question already has answers here:
for (unsigned char i = 0; i<=0xff; i++) produces infinite loop
(4 answers)
Closed 5 years ago.
#include <stdio.h>
int main() {
unsigned char var = -100;
for(var = 0; var <= 255; var++){
printf("%d ", var);
}
}
the output is attached below (run on codeblocks IDE version 16.01)
why is the output an infinite loop?

This condition var <= 255 is always true for an unsigned char, assuming CHAR_BIT is 8 on your platform. So the loop is infinite since the increment will cause the variable to wrap (that's what unsigned arithmetic does in C).
This initialization:
unsigned char var = -100;
is not an error, it's simply annoying code. The compiler will convert the int -100 to unsigned char, following the rules in the language specification.

You are using an unsigned char and its possible range is 0-255.
You are running your loop from 0-255 (inclusive). The moment your variable goes to 256, it will be converted back to 0. Also, initial value -100 will be treated as +156, due to this possible range.
So, this leads to an infinite loop.

Because unsigned char overflow problem. So, remove = in for loop condition.
for(var=0;var<255;var++){
}
For more information, See this stack overflow question.

unsigned char
Range is 0 to 255.When var =255.When it is incremented we get value as 256 which cannot be stored in unsigned char.That is the reason why it is ending in infinite loop.And when you initialize var as -100.It will not show any error because it converts -100 to binary and takes the 1st eight bits.And the corresponding value will be the value of var

Related

Unexpected output Signed and Unsigned comparison in for loop [duplicate]

This question already has answers here:
Comparison operation on unsigned and signed integers
(7 answers)
sizeof() operator in if-statement
(5 answers)
Closed 2 years ago.
unsigned int array[5],length = 5;
for(int i = -1; i < length; ++i)
{
array[i] = i;
printf("%d\n", array[i]);
}
Output: No Output // nothing is printing
I am expecting It should print the array.
Why no output of this c code ? What is the reason ?
The types of i and length are different (int and unsigned int respectively). So in the comparison i < length, i gets converted to an unsigned int because unsigned int has higher rank as per usual arithmetic conversions.
The value of -1 converted to unsigned int is UINT_MAX. Thus the comparison is equivalent to UINT_MAX < 5 in the first iteration. Which is false and the loop is never entered.

Unsigned vs Signed Integer [duplicate]

This question already has answers here:
Why does counting down an unsigned int loop forever in C?
(5 answers)
Closed 4 years ago.
What's wrong with this code?
#include<stdio.h>
int main()
{
unsigned int i;
for(i=100;i>=0;i--)
{
printf("%u ",i);
}
return 0;
}
This code doesn't work but if i use for(i=100;i>0;i--) then it works!
or another way is to use integer instead of using unsigned integer.
An unsigned int can never be negative, so i >= 0 holds true all the time. So, it is effectively an infinite loop.
Since variable i is declared as unsigned int, this condition i>=0 never fails, hence results in infinite loop rotation.
unsigned int i;
for(i=100;i>=0;i--) { /* i will never become negative */
printf("%u \n",i);
}
Note that UINT_MAX is 4294967295 see this i.e it ranges from 0 to 4294967295 so when i=0 it prints & gets decremented, next it won't be -1, it will be 4294967295, hence above for loop results in infinite loop.
another way is to use integer instead of using unsigned integer ? you can do the same using unsigned integer also by replacing the condition part as i>0 so that when i=0 it fails & comes out of loop.
What's wrong with this code?
i>=0 is always true as i is unsigned. Then for(i=100;i>=0;i--) loops forever.
To continue using unsigned i:
Since the coding goal always wants to enter the loop at least once, instead of testing the loop condition in the begining, test at the end.
//for(i=100;i>=0;i--) {
// printf("%u ",i);
//}
i = 100; // or any unsigned constant.
do {
printf("%u ",i);
} while (i-- > 0);
another way is to use integer (int) instead of using unsigned integer (unsigned).(?)
Use int. Of course this will not work if i needs to start at values greater than INT_MAX. If such large values are needed, consider a wider signed type like long long.
int i;
for(i=100;i>=0;i--) {
printf("%u ",i);
}

why the value of sum is coming out to be negative? [duplicate]

This question already has answers here:
Sum of positive values in an array gives negative result in a c program
(4 answers)
Closed 4 years ago.
I have written the following c code to find the sum of first 49 numbers of a given array, but the sum is coming out to be negative.
#include<stdio.h>
int main()
{
int i;
long int sum=0;
long int a[50]={846930887,1681692778,1714636916, 1957747794, 424238336, 719885387, 1649760493, 596516650, 1189641422, 1025202363, 1350490028, 783368691, 1102520060, 2044897764, 1967513927, 1365180541, 1540383427, 304089173, 1303455737, 35005212, 521595369, 294702568, 1726956430, 336465783, 861021531, 278722863, 233665124, 2145174068, 468703136, 1101513930, 1801979803, 1315634023, 635723059, 1369133070, 1125898168, 1059961394, 2089018457, 628175012, 1656478043, 1131176230, 1653377374, 859484422, 1914544920, 608413785, 756898538, 1734575199, 1973594325, 149798316, 2038664371, 1129566414};
for(i=0;i<49;i++)
{
sum=sum+a[i];
printf("sum is : %ld\n",sum);
}
printf("\nthe total sum is %ld",sum);
}
i don't know why it is coming so?please help.
Using long long instead of long, the program works:
Ouput: 56074206897
Reason
Range of long: -2^31+1 to +2^31-1
Range of long long: -2^63+1 to +2^63-1
As you can see 2^31-1 = 2147483647 <
56074206897; but 2^63-1 = 9,223,372,036,854,775,807 > 56074206897
This leads to overflow. According to the C standard, the result of signed integer overflow is undefined behavior. What that means is that if this condition ever happens at runtime, the compiler is allowed to make your code do anything. Your program could crash, or produce the wrong answer, or have unpredictable effects on other parts of your code, or it might silently do what you intended.
In your case it is overflowing the maximum value of long int on your system. Because long int is signed, when the most significant bit gets set, it becomes a negative number.
I didn't actually add them up, but just looking at them, I'd say its a pretty safe guess that you are running into an integer overflow error.
A long int has a maximum size of about 2 billion (2^31). If you add more than that, it'll look back around and go to -2^31.
You'll need to use a data type that can hold more than that if you want to sum up those numbers. Probably a long long int should work. If you're sure it'll always be positive, even better to use an unsigned long long int.
As long int has maximum range upto 2,147,483,647, and the value of sum is more than the range.So, it is coming as negative value. You can use the following code...
#include<stdio.h>
int main()
{
int i;
long long int sum=0; //Taking long long int instead of long int
int a[50]={846930887,1681692778,1714636916, 1957747794, 424238336,
719885387, 1649760493, 596516650, 1189641422, 1025202363, 1350490028,
783368691, 1102520060, 2044897764, 1967513927, 1365180541, 1540383427,
304089173, 1303455737, 35005212, 521595369, 294702568, 1726956430,
336465783, 861021531, 278722863, 233665124, 2145174068, 468703136,
1101513930, 1801979803, 1315634023, 635723059, 1369133070, 1125898168,
1059961394, 2089018457, 628175012, 1656478043, 1131176230, 1653377374,
859484422, 1914544920, 608413785, 756898538, 1734575199, 1973594325,
149798316, 2038664371, 1129566414};
for(i=0;i<49;i++)
{
sum=sum+a[i];
printf("sum is : %lld\n",sum);
}
printf("\nTotal sum is %lld",sum);
}
As Vlad from Moscow said this is a overflow issue, which made an undefined behavior. In you system (long int sum) sum does not have capacity to hold the total value. Not sure but you can use long long int sum =0;(after C99). If it still cannot work properly, search for "BigInteger" implement.

C Union and simultaneous assignment to members [duplicate]

This question already has answers here:
Floating point numbers do not work as expected
(6 answers)
Closed 8 years ago.
In the following code
#include<stdio.h>
int main()
{
union myUnion
{
int intVar;
char charVar;
float floatVar;
};
union myUnion localVar;
localVar.intVar = 10;
localVar.charVar = 'A';
localVar.floatVar = 20.2;
printf("%d ", localVar.intVar);
printf("%c ", localVar.charVar);
printf("%f ", localVar.floatVar);
}
I understand that union can hold only one value at a time. So when I assign char value, int would be overwritten, n then when I assign floatValue, char would be overwritten. So I was expecting some garbage values for int and char variables and 20.200000 for float variable as it was last value to be assigned. But following is the output I'm getting on VS Express as well as gcc
1101109658 Ü 20.200001
unable to understand why float value is changed ?
This has nothing to do with union, and the float value was not changed.
It simply doesn't have enough bits to represent 20.2 exactly as a binary float. But that's okay, nobody has that many bits.
You should read What Every Computer Scientist Should Know About Floating-Point Arithmetic.

c code output unexpected/expected behaviour

what is wrong with this code ? can anyone explain ?
#include <stdio.h>
#include <malloc.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
int num;
int d;
int size = TOTAL_ELEMENTS -2;
printf("%d\n",(TOTAL_ELEMENTS-2));
for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
printf("%d\n",array[d+1]);
return 0;
}
when i print it gives 5, but inside for loop what is happening ?
The sizeof operator returns a value of type size_t, which is an unsigned value. In your for loop condition test:
d <= (TOTAL_ELEMENTS-2)
you are comparing a signed value (d) with an unsigned value (TOTAL_ELEMENTS-2). This is usually a warning condition, and you should turn up the warning level on your compiler so you'll properly get a warning message.
The compiler can only generate code for either a signed or an unsigned comparison, and in this case the comparison is unsigned. The integer value in d is converted to an unsigned value, which on a 2's complement architecture ends up being 0xFFFFFFFF or similar. This is not less than your TOTAL_ELEMENTS-2 value, so the comparison is false.
You're starting the loop by setting d = -1, it should be d = 0. So for the first element you're reading random bits of memory.
If you fix that, then you can change your printf to be
printf("%d\n",array[d]);
As you've also marked this as homework, I'd advise also take a look at your loop terminating condition.

Resources