C: Expected output - c

#include <stdio.h>
int main()
{
long long x = 0x8ce4b16b;
long long y = x<<4;
printf("%lx, %lx, abc\n", x, y);
return 0;
}
I'm getting
8ce4b16b, 0, abc... Is this okay?
However if I change printf like printf("%lld, %lx, abc\n", x, y);
The output becomes:
2363797867, ce4b16b0, abc
Why could have been this behaviour!! :(

Using incorrect format specifier in printf invokes Undefined Behaviour. The correct format specifier for long long is %lld.
Also make sure that you dont have signed integer overflow in your code because that's UB too.

You should use printf("%llx, %llx, abc\n", x, y); in my mind. %lx for long integer.

Related

Why double, long double are always showing 0 as output?

I am writing code to find the distance of a point(25,40000) from a fixed point(47,132000). The distance always printed to be 0.0000.
I have tried checking other combinations, giving smaller values of points, and printing them with %d, it works great.
But with %ld,%lf,%Lf something is not fine. Kindly help.
#include<stdio.h>
#include<math.h>
int main()
{
int x=25,y=40000;
//printf("Enter x,y");
//scanf(%d %d,&x,&y)
long double dist;
dist=sqrt((47-x)*(47-x)+(132000-y)*(132000-y));
printf(" x= %d y=%d dist=%Lf\n",x,y,dist);
return 0;
}
Integer overflow takes place in your code. The below code works -
int main()
{
long long int x=25,y=40000; //int was overflowing and causing you error
long double dist;
dist=sqrt((47-x)*(47-x)+(132000-y)*(132000-y)); //this will safely compute within range and return the desired result
printf("After distance\n");
printf(" x= %lld y=%lld dist=%Lf\n",x,y,dist);
return 0;
}
You were getting wrong output(-nan when I tried out ) because the expression value inside sqrt() was overflowing and becoming negative. (132000-y)*(132000-y) won't fit in an integer range and give negative value. Since, negative square root is not defined, sqrt() returned nan as the result. Changing the type of y to long long int will solve the error.
Hope this helps !

Calculating the range of long in C

I am writing a program in C to calculate the range of different data types. Please look at the following code:
#include <stdio.h>
main()
{
int a;
long b;
for (a = 0; a <= 0; --a)
;
++a;
printf("INT_MIN: %d\n", a);
for (a = 0; a >= 0; ++a)
;
--a;
printf("INT_MAX: %d\n", a);
for (b = 0; b <= 0; --b)
;
++b;
printf("LONG_MIN: %d\n", b);
for (b = 0; b >= 0; ++b)
;
--b;
printf("LONG_MAX: %d\n", b);
}
The output was:
INT_MIN: -32768
INT_MIN: 32767
LONG_MIN: 0
LONT_MAX: -1
The program took a long pause to print the long values. I also put a printf inside the third loop to test the program (not mentioned here). I found that b did not exit the loop even when it became positive.
I used the same method of calculation. Why did it work for int but not for long?
You are using the wrong format specifier. Since b is of type long, use
printf("LONG_MIN: %ld\n", b);
In fact, if you enabled all warnings, the compiler probably would warn you, e.g:
t.c:19:30: warning: format specifies type 'int' but the argument has type 'long' [-Wformat]
printf("LONG_MIN: %d\n", b);
In C it is undefined behaviour to decrement a signed integer beyond its minimum value (and similiarly for incrementing above the maximum value). Your program could do literally anything.
For example, gcc compiles your program to an infinite loop with no output.
The proper approach is:
#include <limits.h>
#include <stdio.h>
int main()
{
printf("INT_MIN = %d\n", INT_MIN);
// etc.
}
In
printf("LONG_MIN: %d\n", b);
the format specifier is %d which works for integers(int). It should be changed to %ld to print long integers(long) and so is the case with
printf("LONG_MAX: %d\n", b);
These statements should be
printf("LONG_MIN: %ld\n", b);
&
printf("LONG_MAX: %ld\n", b);
This approach may not work for all compilers(eg gcc) and an easier approach would be to use limits.h.
Also check Integer Limits.
As already stated, the code you provided invokes undefined behavior. Thus it could calculate what you want or launch nuclear missiles ...
The reason for the undefined behavior is the signed integer overflow that you are provoking in order to "test" the range of the data types.
If you just want to know the range of int, long and friends, then limits.h is the place to look for. But if you really want ...
[..] to calculate the range [..]
... for what ever reason, then you could do so with the unsigned variant of the respective type (though see the note at the end), and calculate the maximum like so:
unsigned long calculate_max_ulong(void) {
unsigned long follow = 0;
unsigned long lead = 1;
while (lead != 0) {
++lead;
++follow;
}
return follow;
}
This only results in an unsigned integer wrap (from the max value to 0), which is not classified as undefined behavior. With the result from above, you can get the minimum and maximum of the corresponding signed type like so:
assert(sizeof(long) == sizeof(unsigned long));
unsigned long umax_h = calculate_max_ulong() / 2u;
long max = umax_h;
long min = - max - 1;
(Ideone link)
Assuming two's complement for signed and that the unsigned type has only one value bit more than the signed type. See ยง6.2.6.2/2 (N1570, for example) for further information.

Implicit and explicit casting

Using:
float return1(void);
int main()
{
int x;
x = (float)return1();
printf("%f",x);
return 0;
}
float return1()
{
return 1;
}`
Why is the output -0.000000?
Shouldn't x be implicitly cast to a float and print 1.000000?
Shouldn't x be implicitly cast to a float and print 1.000000?
No, it shouldn't because the compiler may not know what printf does or which format will be used to print x.
x has type int, so %d should be used instead of %f to print it.
Why is the output -0.000000?
because of
printf("%f",x);
and x is int, if you want 1.00:, do
printf("%f", (double) x);
or better change it to:
printf("%i", x);
printf doesn't cast and interpret object according to the flag given in format string (%f currently).
depending of what you want
printf("%d", x);
or
printf("%f", (float)x);
or in C++:
std::cout << x; // or float(x)
No need to cast return1() to float; your x is integer and you want to format it to float in printf
float return1(void);
int main(void)
{
int x;
x = return1();
printf("%d", x);
return 0;
}
float return1()
{
return 1;
}
No, it shouldn't. The compiler does generally not check the correspondence between the format string and the arguments you provide. In your case, it would be able to do so, but what if someone passes a string variable as format string? That is the reason for most compilers not checking the correspondence.

What is wrong with this C program?

I just want to assign the value of pow to a variable, I've used this
#include<stdio.h>
#include<math.h>
int main( void )
{
int x;
int y;
int z;
x=10;
y=2;
z = pow(x,y);
printf ("%d" , &z);
return 0;
}
but in output I get -1076813284 , I am sorry, but I just started learning C and in every tutorial everyone just print the value of pow, like
printf("Value 3.05 ^ 1.98 = %lf", pow(3.05, 1.98));
and I don't know how to assign it to a variable
printf ("%d" , &z);
prints the address of z (*), not its value. printf("%d", z) prints the value.
(*) Actually, the behavior is undefined and on a 64-bit CPU it will likely print half of the address.
&z is the address of the variable z. If you want to print out the value of z, then the code is simply
printf("%d", z);
You would use &z when reading a value into z, because scanf needs a pointer in order to modify your variable.
pow returns a double (and not a reference), you need to make your print statement:
printf ("%f" , z);
After changing z to a double:
double z;
pow returns double and it takes arguments of type double.
double pow(double x, double y)
You need %f specifier in printf and also remove & from z.
Another way is to cast the return value of pow to int and use %d
int z = (int)pow(x, y);
printf ("%d" , z);

How to multiply float with integers in C?

When I execute this code it returns me 1610612736
void main(){
float a=3.3f;
int b=2;
printf("%d",a*b);
}
Why and how to fix this ?
edit : It's not even a matter of integer and float, if i replace int b=2: by float b=2.0f it return the same silly result
The result of the multiplication of a float and an int is a float. Besides that, it will get promoted to double when passing to printf. You need a %a, %e, %f or %g format. The %d format is used to print int types.
Editorial note: The return value of main should be int. Here's a fixed program:
#include <stdio.h>
int main(void)
{
float a = 3.3f;
int b = 2;
printf("%a\n", a * b);
printf("%e\n", a * b);
printf("%f\n", a * b);
printf("%g\n", a * b);
return 0;
}
and its output:
$ ./example
0x1.a66666p+2
6.600000e+00
6.600000
6.6
Alternately, you could also do
printf("%d\n", (int)(a*b));
and this would print the result you're (kind of) expecting.
You should always explicitly typecast the variables to match the format string, otherwise you could see some weird values printed.

Resources