Couldnt understand how numbers are handled in C. Could anyone point to a good tutorial.
#include<stdio.h>
main()
{
printf("%f",16.0/3.0);
}
This code gave: 5.333333
But
#include<stdio.h>
main()
{
printf("%d",16.0/3.0);
}
Gave some garbage value: 1431655765
Then
#include<stdio.h>
main()
{
int num;
num=16.0/3.0;
printf("%d",num);
}
Gives: 5
Then
#include<stdio.h>
main()
{
float num;
num=16/3;
printf("%f",num);
}
Gives: 5.000000
printf is declared as
int printf(const char *format, ...);
the first arg (format) is string, and the rest can be anything. How the rest of the arguments will be used depending on the format specifiers in format. If you have:
printf("%d%c", x, y);
x will be treated as int, y will be treated as char.
So,
printf("%f",16.0/3.0);
is ok, since you ask for float double (%f), pass float double(16.0/3.0)
printf("%d",16.0/3.0);
you ask for int(%d), you pass float double (double and int have different internal representation) so, the bit representation of 16.0/3.0 (double) corresponds to bit representation of 1431655765(int).
int num;
num=16.0/3.0;
compiler knows that you are assigning to int, and converts it for you. Note that this is different than the previous case.
Ok, the first 1 is giving correct value as expected.
Second one you are passing a float while it is treating it as an int (hence the "%d" which is for displaying int datatypes, it is a little complicated to explain why and since it appears your just starting I wouldn't worry about why "%d" does this when passed a float) reading it wrong therefore giving you a wierd value. (not a garbage value though).
Third one it makes 16.0/3.0 an int while assigning it to the int datatype which will result in 5. Because while making the float an int it strips the decimals regardless of rounding.
In the fourth the right hand side (16/3) is treated as an int because you don't have the .0 zero at the end. It evaluates that then assigns 5 to float num. Thus explaining the output.
It is because the formatting strings you are choosing do not match the arguments you are passing. I suggest looking at the documentation on printf. If you have "%d" it expects an integer value, how that value is stored is irrelevant and likely machine dependent. If you have a "%f" it expects a floating point number, also likely machine dependent. If you do:
printf( "%f", <<integer>> );
the printf procedure will look for a floating point number where you have given an integer but it doesn't know its and integer it just looks for the appropriate number of bytes and assumes that you have put the correct things there.
16.0/3.0 is a float
int num = 16.0/3.0 is a float converted to an int
16/3 is an int
float num = 16/3 is an int converted to a float
You can search the web for printf documentation. One page is at http://linux.die.net/man/3/printf
You can understand numbers in C by using concept of Implecit Type Conversion.
During Evaluation of any Expression it adheres to very strict rules of type Conversion.
and your answer of expression is depends on this type conversion rules.
If the oparands are of different types ,the 'lower' type is automatically converted into the 'higher' type before the operation proceeds.
the result is of the higher type.
1:
All short and char are automatically converted to int then
2:
if one of the operands is int and the other is float, the int is converted into float because float is higher than an ** int**.
if you want more information about inplicit conversion you have to refer the book Programming in ANSI C by E Balagurusamy.
Thanks.
Bye:DeeP
printf formats a bit of memory into a human readable string. If you specify that the bit of memory should be considered a floating point number, you'll get the correct representation of a floating point number; however, if you specify that the bit of memory should be considered an integer and it is a floating point number, you'll get garbage.
printf("%d",16.0/3.0);
The result of 16.0/3.0 is 5.333333 which is represented in Single precision floating-point format as follows
0 | 10101010 | 10101010101010101010101
If you read it as 32bit integer value, the result would be 1431655765.
num=16.0/3.0;
is equivalent to num = (int)(16.0/3.0). This converts the result of float value(5.33333) to integer(5).
printf("%f",num);
is same as printf("%f",(float)num);
Related
I have user integer input input and wanted to output the calculation with the input by division. The return had been 0 rather than decimals results. Wanted to prevent use of initialize the variable input with int rather than float to prevent possible errors in later data input with delimiter .
Is there any way to calculate float result w/ int input other than assigning float for the variable input ?
Source:
#include <stdio.h>
#include <stdlib.h>
int main() {
int input;
printf("Enter data:");
scanf("%d", &input);
printf("Output: %f", (input / 7));
return 0;
}
Return:
Input: 6
0.0000
Everything in C has a type, including constants like 7 which is type int, 7.0f which is type float or 7.0 which is type double.
Whenever mixing fixed point and floating point operands in the same operation with two operands (generally a bad idea), then the fixed point operand is converted to floating point. This is called "the usual arithmetic conversions".
Examples:
int input;, input / 7. Both operands are int, no promotion occurs, the result will be of type int. This has everything to do with the / operator and nothing to do with where you place the result. The divison will get carried out on int type, so if you wanted it to be type float, it's already too late. Something like float f = input / 7 will not affect the type used by the division in any way. It will only convert the resulting int to float.
int input;, input / 7.0f. One operand is type int, the other is type float. The usual arithmetic conversions state that the int operand will get converted to float before the division. So this would solve the problem.
However, here is a better idea: Simply never mix fixed point and floating point in the same expression, because the potential for bugs is huge. Instead do this:
scanf("%d", &input);
float f_input = (float)input;
printf("Output: %f", (f_input / 7.0f);
Now nothing goes on implicitly, all implicit conversions have been removed. The cast is not necessary, but creates self-documenting code saying: "yes I do mean to make this a float type rather than had it happen by chance/accident".
(Advanced topic detail: printf actually converts the passed float to double, but we need not worry about that.)
You need input/7 to be performed with floating point math, rather than integer math.
Like this...
printf("Output: %f", (input / 7.0));
This link explains a bit better how C/C++ deals with mixing floats/doubles/ints etc.
Does one double promote every int in the equation to double?
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 4 years ago.
I'm a Little confused about some numbers in C-Code. I have the following piece of Code
int k;
float a = 0.04f;
for (k=0; k*a < 0.12; k++) {
* do something *
}
in this case, what is the type of "0.12" ? double ? float ? it has never been declared anywhere. Anyways, in my program the Loop above is excuted 4 times, even though 3*0.04=0.12 < 0.12 is not true. Once I Exchange 0.12 with 0.12F (because I am globally restricted to float precision in all of the program), the Loop is now executed 3 times. I do not understand why, and what is happening here. Are there any proper Guidelines on how to write such statements to not get unexpected issues?
Another related issue is the following: in the Definition of variables, say
float b = 1/180 * 3.14159265359;
what exactly "is" "1" in this case ? and "180" ? Integers ? Are they converted to float numbers ? Is it okay to write it like that ? Or should it be "1.0f/180.0f*3.14159265359f;"
Last part of the question,
if i have a fuction
void testfunction(float a)
which does some things.
if I call the fuction with testfunction(40.0/6.0), how is that Division handled ? It seems that its calculated with double precision and then converted to a float. Why ?
That was a Long question, I hope someone can help me understand it.
...numbers that are not stored in a variable
They are called "constants".
Any unsuffixed floating point constant has type double.
Quoting C11, chapter §6.4.4.2
An unsuffixed floating constant has type double. If suffixed by the letter f or F, it has
type float. If suffixed by the letter l or L, it has type long double.
For Integer constants, the type will depend on the value.
Quoting C11, chapter §6.4.4.1,
The type of an integer constant is the first of the corresponding list in which its value can
be represented. [..]
and for unsuffixed decimal number, the list is
int
long int
long long int
Regarding the mathematical operation accuracy of floating point numbers, see this post
"0.12" is a constant, and yes, without a trailing f or F, it will be interpreted as a double.
That number can not be expressed exactly as a binary fraction. When you compare k * a, the result is a float because both operands are floats. The result is slightly less than 0.12, but when you compare against a double, it gets padded out with zeros to the required size, which increases the discrepancy. When you use a float constant, the result is not padded (cast), and by good luck, comes out exactly equal to the binary representation of "0.12f". This would likely not be the case for a more complicated operation.
if we use a fractional number for eg, like 3.4 it's default type if double. You should explicitly specify it like 3.4f if you want it to consider as single precision (float).
if you call the following function
int fun()
{
float a= 1.2f;
double b = 1.2;
return (a==b);
}
this will always return zero (false).because before making comparison the float type is converted to double (lower type to higher type) , At this time sometimes it can't reproduce exact 1.2, a slight variations in value can be happen after 6th position from decimal point. You can check the difference by the following print statement
printf("double: %0.9f \n float: %0.9f\n",1.2,1.2f);
It results ike
double: 1.200000000
float: 1.200000481
Ok so this what I must do but i can't make it work:
a) Change to float instead of integers. And assign 0.3 as starting value to "u".
b) Use double precision instead of integers. Asign 0.3x10^45 as starting value for "u".
c) Use characters instead of integers. Assign starting value as 'C' for "u".
#include <stdio.h>
main ()
{
int u = 3;
int v;
int *pu;
int *pv;
pu = &u;
v = *pu;
pv = &v;
printf("\nu=%d &u=%X pu=%X *pu=%d", u, &u, pu, *pu);
printf("\n\nv=%d &v=%X pv=%X *pv=%d", v, &v, pv, *pv);
}
I'll be really grateful if anyone could modify my code to do the things above. Thanks
This question is testing a few things. First do you know your types? You are expected to know that a floating pointing number is declared with float, a double precision number with double, and a character with char.
Second you are expected to know how to assign a literal value to those different types. For the float literal you are probably expected to use 0.3f, since without that suffix it would be double precision by default (although in this context it isn't going to make any difference). For the double, you are expected to know how to use scientific notation (the literal value should be 0.3e45). The character literal I would hope is fairly obvious to you.
Finally you are expected to know the various type characters used in the printf format specification. Both single and double precision numbers use the same type characters, but you have a choice of %e, %f or %g, depending on your requirements. I tend to use %g as a good general purpose choice, but my guess is they are expecing you to use %e for the double (because that forces the use of scientific notation) and possibly %f for the float - it depends what you have been taught. For a character you use %c.
Also, note that you should only be replacing the %d type characters in the format strings. The %X values are used to output a hexadecimal representation of the pointers (&u and pu). A pointer isn't going to change into a floating point value or a character just because the type that is being pointed to has changed - an address is always an integer when you are writing it out.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
print the float value in integer in C language
I am trying out a rather simple code like this:
float a = 1.5;
printf("%d",a);
It prints out 0. However, for other values, like 1.4,1.21, etc, it is printing out a garbage value. Not only for 1.5, for 1.25, 1.5, 1.75, 1.3125 (in other words, decimal numbers which can be perfectly converted into binary form), it is printing 0. What is the reason behind this? I found a similar post here, and the first answer looks like an awesome answer, but I couldn't discern it. Can any body explain why is this happening? What has endian-ness got to do with t?
you're not casting the float, printf is just interpreting it as an integer which is why you're getting seemingly garbage values.
Edit:
Check this example C code, which shows how a double is stored in memory:
int main()
{
double a = 1.5;
unsigned char *p = &a;
int i;
for (i=0; i<sizeof(double); i++) {
printf("%.2x", *(p+i));
}
printf("\n");
return 0;
}
If you run that with 1.5 it prints
000000000000f83f
If you try it with 1.41 it prints
b81e85eb51b8f63f
So when printf interprets 1.5 as an int, it prints zero because the 4 LSBs are zeros and some other value when trying with 1.41.
That being said, it is an undefined behaviour and you should avoid it plus you won't always get the same result it depends on the machine and how the arguments are passed.
Note: the bytes are reversed because this is compiled on a little indian machine which means the least significant byte comes first.
You don't take care about argument promotions. Because printf is a variadic function, the arguments are promoted:
C11 (n1570), § 6.5.2.2 Function calls
arguments that have type float are promoted to double.
So printf tries to interpret your double variable as an integer type. It leads to an undefined behavior. Just add a cast:
double a = 1.5;
printf("%d", (int)a);
Mismatch of arguments in printf is undefined beahivour
either typecast a or use %f
use this way
printf("%d",(int)a);
or
printf("%f",a);
d stands for : decimal. so, nevertheless a is float/double/integer/char,.... when you use : "%d", C will print that number by decimal. So, if a is integer type (integer, long), no problem. If a is char : because char is a type of integer, so, C will print value of char in ASCII.
But, the problem appears, when a is float type (float/double), just because if a is float type, C will have special way to read this, but not by decimal way. So, you will have strange result.
Why has this strange result ?
I just give a short explanation : in computer, real number is presented by two part: exponent and a mantissa. If you say : this is a real number, C will know which is exponent, which is mantissa. But, because you say : hey, this is integer. no difference between exponent part and mantissa part -> strange result.
If you want understand exactly, how can know which integer will it print (and of course, you can guess that). You can visit this link : represent FLOAT number in memory in C
If you don't want to have this trange result, you can cast int to float, so, it will print the integer part of float number.
float a = 1.5;
printf("%d",(int)a);
Hope this help :)
I have written a program in C and when I compare the same values of a float and a string that is converted into float using function atof results in NOT EQUAL .
#include<stdio.h>
main(){
char str[10] = "54.23" ;
float val = 54.23 ;
if( atof(str) == val )
printf("\nconverted correctly");
else
printf("\nThen What is the use of atof\n ");
}
This Program is showing output : "Then What is the use of atof"
Please tell me why this anonymous behavior is shown by this program ?
Never test floats/doubles for equality with ==
Here's a version of your code which actually displays the values in question:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str[10] = "54.23";
float val = 54.23;
printf("atof(str) = %.15f\n", atof(str));
printf(" val = %.15f\n", val);
return 0;
}
When you run it you see this:
$ gcc -Wall atof.c
$ ./a.out
atof(str) = 54.229999999999997
val = 54.229999542236328
$
The values are close, within the expected accuracy of a single precision float, but they are not identical. Also, as others have noted, atof returns a double, so you are comparing the value of a float promoted to a double with a full precision double as returned by atof.
As always with this type of question, read this before proceding any further with floating point arithmetic in your code. The "take home message" is that you should never compare floats or doubles with == - always compare the absolute difference with an appropriate tolerance value.
Because val is an int; when you assign it 54.23 it'll be truncated to 54. And 54 != 54.23.
Even if it was a float, you couldn't expect them to be equal. Here's why.
double atof(char *str);\\it return double not a float
This comparison is between a float and a double.As you compare between two different types you may get some unexpected output.because every data type having different memory representation as well as different access mechanism.
float represent in memory in different form as compare to double .
you can learn more about this in wikipedia also
http://en.wikipedia.org/wiki/Floating_point#Internal_representation
Again you should include the header file
#include <stdlib.h> \\prototype of atof() present in this header.
if you not provide the proper prototype before use of the function then
return type of function by default int .So I think the return result is definitely different as you expected.
You almost never want to check equality with floating point numbers, because teensy differences will be read as unequal. There are other problems, too. For example, even if you use double precision, for instance, the decimal number "0.1" is represented as "0.10000000000000001".
In this case, your "val" variable is a double precision literal, which is cast to a float. The result probably won't be accurate perfectly. Secondly, your string literal needs to convert from base ten to a base 2 double. So, to compare the atof value to your literal, atof converts a base ten string to a base two double, while "val" was converted from a base ten literal to a base two double to a base two float, and then upcast back to a base two double to do the comparison.
Point of fact, I'm not going to pin down exactly where that lost precision went. Do as Paul's code might suggest and compare the values to within a tolerance.