Why does 1/2 in c = -2010232232? - c

I have a very simple C program.
int main(void){
double sum = 1/2;
printf("%d\n", sum);
return 0;
}
Why does it return a number like "-2030243223"?
And why does this number change every time I run the program?
I've tried using int's and float's but I can't seem to get the output to be 0.5!?

Use %f to print a double, not %d. The latter causes undefined behavior.
Also the expression 1/2 uses integer division which yields 0, so to get .5, use 1/2. (note trailing period).
Finally, to actually get .5 instead of something like 0.500000, specify the precision:
printf("%.1f\n", sum);

You're passing an IEEE floating-point number to printf, but telling it it's an integer.
Change
printf("%d\n", sum);
to
printf("%f\n", sum);
As noted in other comments, you probably also want to do floating-point division rather than integer division. 1/2 is zero; you're dividing two integers, so the result is an integer (yes, even though you're about to assign it into a floating-point variable -- each expression's type is determined in isolation) and it has to discard the remainder. You probably want 1.0/2 instead; if either term is a float, then the result is a float, so you'll get 0.5.

You're trying to print a double to an Integer. (%d).
Even though they both are numbers, internally there are huge differences, for example, memory ones.

You're trying to print a double as an int. Try using:
printf("%g\n");
Also, you will want to make you initial division 1.0/2.0 or else you will get 0.

Try this:
int main(void){
double sum = 1.0/2.0;
printf("%10.3f\n", sum);
return 0;
}

There is a couple of issues with your code
int main(void){
// you need to divide a double by a double, not two ints
double sum = 1.0/2.0;
// %d is for int, not doubles. You use %f in the case of printing a double
printf("%f\n", sum);
return 0;
}
Now if you really want to print the variable as an int, you can cast the variable sum as an int by doing printf("%d\n", (int)sum);, but you'll have a rounding issue.

Try the following:
printf("%f\n", sum);
%d is a placeholder for integer, maybe the address of sum has been printed out^^

The bad format can't be the whole answer, because:
With OP's code, the double should be zero, stored as 0x0000000000000000, which couldn't show as "-2030243223" (0x86FCF269).
OP says this value changes all the time.
So there must be something else, such as the fact that the header is missing: I guess the compiler doesn't know printf is a variadic function, and tries to pass the argument through floating-point registers.
printf, being a variadic function, probably attempts to read its input value from the stack, hence garbage.

Related

miscalculation using pow function in C

I'm starting coding in C and I was doing an exercise, but saw a miscalculation testing this code:
int main(){
int number;
int square;
printf("Pick a number: ");
scanf("%d",&number);
while(number<=0)
{
printf("ERROR: The number MUST be greater than zero\nPick a number greater than zero: ");
scanf("%d",&number);
}
square = pow(number,2);
printf("\nThe square of the number is: %d\n\n",square);
system("pause");
return 0;}
now... everything works just fine, but when I use the number "5", it shows the result "24", when it should be "25". anyone knows why this happen?
pow takes double arguments and returns a double. So you're getting a rounding error.
Because in C standard library, pow is defined as a function taking double arguments and returning a double value. Even if nothing is required by the standard concerning the implementation, common implementations use (more or less) the following formula: pow(x, y) = exp(y * log(x)). That means that even if you pass integer values, the internal operations will use non integer values, and rounding errors will occur.
That is what happens with your current implementation with 5. To make sure of it, just print the result as a double:
double dsq = pow(5, 2);
printf("%f", dsq);
dsq (in your implementation) should be slightly off and when rounded you get 24
The function pow() takes a double value as an input parameter and returns a double also, as it is defined in the C standard library. However, the variable you pass to (number) is an int variable. This results in a rounding error as the compiler uses a non-integral value for the calculation process.
To get around this error, declare number with type double instead of int:
double number;
That should sort the rounding issue.
Hum I think you should cast pow in int :
square = (int)pow(number,2);

floating point exception(core dumped)

I tried with putting puts("..") to find where the mistake is, but it didn't help.
this is my third function, first and second are working.
i translated in englih, i hope it's understandably.
void write3(sth_st*E, int n, char* Typ){
int i;
int sum=0;
int count=0;
float result;
for(i=0; i<n; i++){
if(strcmp(Typ, E[i].typ)==0){
sum=sum+E[i].time;
count++;
}
}
FILE*write3;
write3=open("xD", "w");
puts("rand");
result=sum/count;
fprintf(write3, "%f", result);
return;
}
count is most likely integer and 0. The system error message is misleading, especially since dividing by 0 is perfectly valid for floating point values.
With the extra context, we can infer that Typ was not found in the E array or maybe n is too small, so count and sum both stay at 0 and the division sum/count invokes undefined behavior because it is an integer division.
If you convert one or the other to double, you will get a floating point division, which is undoubtedly what you expect and printf will print nan for this case.
result = (double)sum / count;
There is also a possiblity that the sum of all times may overflow the int type. You should make sum a double to avoid that.
Note that %f is the printf format for double. result is a float, but luckily floats are silently converted to double when passed to printf. There is no benefit at using float types, use double instead.

lvalue required as left operand of assignment while type casting

I am trying to write some code, which does some calculations based on variables the user gives. The variables can be of sevral types, among them Integer or Decimal, which is where the problem lies. When I do a calculation, I declare the numbers to be calculated and the result as double. Though, when BOTH numbers are integers, I want the result to also be an int. That said, I tried typecasting, by saying the following:
float result;
float num1, num2;
if (strcmp(varray[var1].type, "Integer\n") == 0 && flag != 1){
if (varray[var2].type[0] == 'I'){
(int)num1 = atoi(varray[var1].value);
printf("The result type is Integer \n");
(int)num2 = atoi(varray[var2].value);
(int)result = num1 + num2;
printf("Result =%d\n", result);
flag = 1;
}
}
I get compiler errors on the lines where I type cast to (int), with the message displayed on the title. Am I doing something wrong here? Should I just declare the numbers and result in the conditional, and not declare them before it and type cast within?
You need to cast the rvalue (the result of atoi) instead of the lvalue (num1):
num1 = (float)atoi(varray[var1].value);
(int)num1 is considered an rvalue, so called because it's expected to be on the right side of an assignment statement.
If you wanted to cast the right side to something more suitable for the variable on the left, the right side is where you would do it, such as:
num1 = (float) atoi (varray[var1].value);
This is perfectly valid though you may lose precision if your integers are large enough1. It's also unnecessary since C will happily convert it for you auto-magically. You can just use:
num1 = atoi (varray[var1].value);
You also have a problem with lines like this:
float result = 32.0f;
printf("Result =%d\n", result);
If your format specifiers don't match the types of the parameters, the behaviour is undefined. In this case, you're specifying an integer with %d but giving a floating point value.
If you want to print a floating point value with no decimals, you use %.0f as a format specifier (%f on its own will give a default number of digits after the decimal point, like 32.000000).
1 Unless you're using arrays of millions of floating point values and space is tight, or you're on a system where there's a clear and needed performance benefit to using float, you really should prefer doubles where possible. Their range and precision are much better.

Floating point rounding in C

I've run into some weird rounding behaviour with floats. The code below demonstrates the problem. What is the best way to solve this? I've been looking for solutions but haven't had much luck.
#include<stdio.h>
int main(void)
{
float t;
t = 5592411;
printf("%f\n", 1.5*t);
t *= 1.5;
printf("%f\n", t);
return 0;
}
The code above should print out the same value, but I get this on my setup using GCC 4.7.2:
8388616.500000
8388616.000000
If I use a calculator, I get the first value, so I assume the second is being rounded somehow. I have identical Fortran code which does not round the value(has the 0.5).
1.5 is a double constant rather than a float and C has automatic promotion rules. So when you perform 1.5*t what happens is (i) t is converted to a double; (ii) that double is multiplied by the double 1.5; and (iii) the double is printed (as %f is the formatter for a double).
Conversely, t *= 1.5 promotes t to a double, performs a double multiplication and then truncates the result to store it back into a [single precision] float.
For evidence, try either:
float t;
t = 5592411;
printf("%f\n", 1.5f*t); // multiply a float by a float, for no promotion
t *= 1.5;
printf("%f\n", t);
return 0;
Or:
double t; // store our intermediate results in a double
t = 5592411;
printf("%f\n", 1.5f*t);
t *= 1.5;
printf("%f\n", t);
return 0;
The first calculation is done with double precision, the second is calculated the same, but truncated to single precision in the assignment to float.
If you use double for your variable, you'll get the same result. It's a good idea to use this type over float whenever accuracy may be a concern.
In the first case, the result is a double which can precisely represent the desired value.
In the second case, the result is a float which can't precisely represent the desired value.
Try the same with double and you'll end up with the same results either way.
#include<stdio.h>
int main(void)
{
double t;
t = 5592411;
printf("%f\n", 1.5*t);
t *= 1.5;
printf("%f\n", t);
return 0;
}
Writing 1.5 in C code is interpreted as a double, which has more precision than the float type.
The first case,
printf("%f\n", 1.5*t);
results in t being implicitly converted to a double (with greater precision) and then multiplied. The printf function, which casts the input corresponding to %f anyway, prints the result, which is also a double.
The second case has the 1.5 being converted to the float type, which has less precision and cannot store as small details.
If you want to avoid this effect, use 1.5f instead on 1.5 to use floats, or change the type of t to double.
Whether this would work at all depends on the machine representation of floats and doubles. Passing a float on a typical 32 bit architecture pushes 4 bytes on the argument stack. Passing a double would push 8 bytes. Passing a double but using %f is asking to treat it as a float which will look at the first 4 bytes pushed in our typical case. Depending on machine representation this might be close to the intended result or might be way out in left field.

Integer conversion to double in C yielding zero values

I originally had a function that uses pow(), and I noticed it was returning zero values every time. While debugging it, I found that this seems to be the source of the problem:
#include <math.h>
#include <stdio.h>
#include <string.h>
int foo(int n)
{
printf("%d is number passed in \n", n);
double base = (double) n;
printf("%d is base \n", base);
printf("%d is power\n", pow(base ,2));
return (1/2 *( pow( (double) n, 2)));
}
If I call foo on any integer value (say, 8), the second printf statement prints zero every time. (And of course, the third one does as well). Shouldn't conversion of double to int be straightforward?
You got several things wrong.
First of all, you're using the %d specifier in printf, but you're passing to it a double value; for doubles, you should use %f1, otherwise the printf will try to interpret the bytes of the double as an int, leading to unexpected results (in your case 0).
Notice that this kind of error is usually noticed by recent compilers with warning level high enough.
Moreover, in the return statement you wrote
1/2 *( pow( (double) n, 2))
This expression will always yield zero, because of the 1/2 factor. Both 1 and 2 are ints, thus an integer division is performed, and obviously it results in 0, that kills the whole expression.
Solution: change the 1/2 to 1/2. (where 2. denotes 2 as a double value, which promotes the operation to a floating-point division), or simply replace it with 0.5, or (even simpler) perform a division by two at the end of the expression.
Trivia: I always had the doubt that %f was for float, and something else was used for doubles; instead, it turns out that there's no specifier for floats, since they are automatically converted to doubles when passed to a function as "variable arguments" (so this applies to printf).
printf("%g is base \n", base);
printf("%g is power\n", pow(base ,2));
Your second problem is that you're doing this:
return (1/2 *( pow( (double) n, 2)));
But have defined your function to return an int. You need to define it to return double and not use integer math there :)
Your version
with correct conversion specifications
with no casts
with 1.0 in the final return
to output a double in c via printf, you should use %g or %lf (lf stands for "long float" which is a double, in fact float stands for single precision :D )
%g truncate to the least significant number, %lf do not.
You can even use something like
%.20g, so you are asking to write the number with 20 decimal number after dot (or comma).
If you want to get a float result from your function, you shoud change the function declaration to
double foo(int n)
I suggest to change the return line to this
return (0.5 * pow( (double) n, 2)));
0.5 is the right way to write 1/2 in floating point.
But if you only want an integer, then you should do this:
return ((int)pow( (double) n, 2)/2);
In fact pow return a double, and you should cast it to integer
Hope that's usefull :)

Resources