float amount;
printf("Enter the amount:\n");
scanf("%f", &amount);
// input: 100.10
printf("%f", amount);
Output: 100.099998
The problem is that the output is not 100.10 same as the input;
Floating point numbers like 100.10 has no exact binary representations. That's why you encountered rounding error.
Note that there is something more behind, %f in printf actually expects a double argument, so here amount is converted to double in the printf call.
The reason is, variable argument functions like printf always promote their variable argument parts, that's why printf has no format specifier for float, because it always sees double. So a better program to demonstrate your question is to use double instead:
double amount;
printf("Enter the amount:\n");
scanf("%lf", &amount);
printf("%f", amount);
You'll still get rounding error, but no conversion from float to double is done. And to demonstrate the program, you may need to print more digits as double is more accurate.
Related
I know that by default in C when you declare a float it gets automatically saved as a double and that if you want it to be saved as a float you have to declare it like this
float x = 0.11f
but what if my x value comes from a scanf? How can I do so that when I print it it doesn't get rounded down or up?
Here's my code btw, thanks for the help.
#include <stdio.h>
int main() {
float number = 0;
float comparison;
do{
printf("\nEnter a number: ");
scanf("%f", &comparison);
if(comparison > number) {
number = comparison;
}
}while(comparison > 0);
printf("The largest number enteres was: %f\n\n", number);
}
what if my x value comes from a scanf? How can I do so that when I print it it doesn't get rounded down or up?
scanf with an %f directive will read the input and convert it to a float (not a double). If the matched text does not correspond to a number exactly representable as a float then there will be rounding at this stage. There is no alternative.
When you pass an argument of type float to printf() for printing, it will be promoted to type double. This is required by the signature of that function. But type double can exactly represent all values of type float, so this promotion does not involve any rounding. printf's handling of the %f directives is aligned with this automatic promotion: the corresponding (promoted) argument is expected to be of type double.
There are multiple avenues to reproducing the input exactly, depending on what constraints you are willing to put on that input. The most general is to read, store, and print the data as a string, though even this has its complications.
If you are willing to place a limit on the maximum decimal range and precision for which verbatim reproduction is supported, then you may be able to get output rounded to the same representation as the input by specifying a precision in your printf field directives:
float f;
scanf("%f", &f);
printf("%f %.2f %5.2f\n", f, f, f);
If you want to use a built-in floating-point format and also avoid trailing zeroes being appended then either an explicit precision like that or a %g directive is probably needed:
printf("%f %g\n", f, f);
Other alternatives are more involved, such as creating a fixed-point or arbitrary-precision decimal data type, along with appropriate functions for reading and writing it. I presume that goes beyond what you're presently interested in doing.
Note: "double" is short for "double precision", as opposed to notionally single-precision "float". The former is the larger type in terms of storage and representational capability. In real-world implementations, there is never any "rounding down" from float to double.
So what is happening is I ask the user for input, then store that into a variable using scanf.
But when I try to retrieve the value, it just a 0.000000. I'm sure I'm just making a stupid noob mistake, but any help you can provide is appreciated.
printf("Enter the radius of your circle/sphere: ");
scanf("%f", &radius);
printf("\n%f", radius);
Ex:
Enter the radius of your circle/sphere: 10
0.0000000
Thanks for your time!
As answered by #Chris McGrath, you must use the %lf format specifier for doubles. However, this doesn't explain why the %f format works just fine for printf.
%lf stands for long float, i.e. double. When values of type float are passed to variadic functions (those accepting a variable number of arguments, such as printf and scanf), they are implicitly promoted to double:
float val;
printf("%f", val); /* printf receives val cast to double, the same
as printf("%f", (double) val) */
printf("%lf", val); /* printf also receives val cast to double, the
same as printf("%lf", (double) val) */
Since both printf("%lf", ...) and printf("%f", ...) end up receiving a double, the two are completely equivalent.
On the other hand, all arguments to scanf are pointers. scanf("%f", ...) expects to receive a float *, and scanf("%lf", ...) a double *:
float floatval;
double dblval;
scanf("%f", &floatval); /* stores a float value to address received */
scanf("%lf", &dblval); /* stores a double value to address received */
The two pointers point to different types, so one cannot be promoted to the other. If they received the same treatment by scanf, it would end up storing the same value into addresses allocated for types of different size, which cannot work.
This is why scanf strictly requires the use of the %lf specifier when used with double values.
As AntonH said, if radius is declared as a double, you must use the %lf format specifier:
scanf("%lf", &radius);
I want to print out a float with a user-defined precision after decimal point in C, like say,
int dec;
float no;
printf("\nEnter no of decimal places and the number ");
scanf("%d%f",&dec,&no);
Then print the number no with dec decimal places.
You may format the printing of a floating point number, but not its actual size.
You may read this on formatting floating point number.
To save your time, you may use the %f format specifier, as
printf("%.PRECISIONf", fvar);
where PRECISION is the number of digits you want after decimal, for e.g.
int
print_float(float fvar, unsigned int precision) {
char fs[32];
sprintf(fs,"%%.%df", precision);
return printf(fs, fvar);
}
On calling the routine:
print_float(2.0f, 2);
you will get 2.00 as the output.
Hope this solves your issue.
Do
int dec;
float no;
printf("\nEnter no of decimal places and the number ");
scanf("%d%f",&dec,&no);
printf("%.*f",dec,no);
I am writing simple code for homework.
I get one number from user, which is 3.4, when I define it with
scanf("%d",&a)
it takes only 3 and do it that way. I defined a as
int a;
What should I do?
I think you are very new to c programming. This is a very simple job. This can be done as:-
float a;
// to input a data in the variable a
scanf("%f",&a);
//to display the stored data
printf("%f\n",a);
//or
printf("%.nf\n",a);//specify value of n
//maximum value of n is 6 also is its default value
//for e.g. printf("%.2f",a); will display decimal number upto two digits after the decimal place
//you can know more about displaying data as
%d: decimal value (int)
%c: character (char)
%s: string (const char *)
%u: unsigned decimal value (unsigned int)
%ld: long int (long)
%f: float value (float or double)
%x: decimal value in Hexadecimal format
%o: decimal value in octal format
For avialabe list of formatting specifications go here
Use float
float a;
scanf("%f", &a);
%d is for int. 3.4 is not an int type, you can use float.
float x;
scanf("%f", &x);
For detailed information about data types, you can check here: http://en.wikipedia.org/wiki/C_data_types
And also here: http://www.techonthenet.com/c_language/variables/index.php
You should define a as
float a;
and replace %d with %f in scanf
scanf("%f", &a);
What should I do?
Read Basics of Formatted Input/Output in C.
Its very simple for int variable we use %d format specifier and if we want float we use %f format specifier. Because according to IEEE int and float bit map format are different.
You are declaring int a which can take only integer value so what you have to do is make it float which is used for numbers having decimal point
float a;
scanf(%f,&a);
So, I am reading a C prog. book and I read this exercise:
Write a program which asks the user to enter a dollars-and-cents amount, then displays the amount with 5% added?
Solution :
#include <stdio.h>
int main(void) {
float original_amount;
printf("Enter an amount: ");
scanf("%f", &original_amount);
printf("With tax added: $%.2f\n", original_amount * 1.05f);
return 0;
}
I know what .3f means (there should be 3 digits after...), but what does 1.05f mean?
The 1.05f does denote a floating point number with value approximately 1.05 (which is 105% = 100% + 5%). The %.2f is a format specifier and is something very different.
The multiplication with this number actually adds 5% to the value (value * 1.05 = value * (100% + 5%) = value + value * 5%).
Format specifiers occur in the first parameter of printf-like functions and tell the function how to output the argument corresponding to its position.
1.05f is a float type that has value 1.05
The program is apparently using multiplication by 1.05f as a way to add 5% to a number. But, because of representation error 1.05f is not exactly 1.05; it's a single-precsion floating point number close† to 1.05.
The float value closest to 1.05 is 1.0499999523162841796875 (assuming the usual 32-bit float format). Since you round the results you would have to use some fairly big numbers to see the effects of the error; try entering 100000000 when the program asks for amount:
Enter an amount: 100000000
With tax added: $104999992.00
If you used double precision instead of single precision, that is, double instead of float and 1.05 instead of 1.05f, the representation error would be smaller but it would still not be exactly 1.05, since this number cannot be represented exactly as the binary floating point numbers that our computers use.
You would get a correct result for 100000000, but still "incorrect" results for astronomically big numbers.
†) How close? From the standard:
For decimal floating constants, and also for
hexadecimal floating constants when
FLT_RADIX
is not a power of 2, the result is either
the nearest representable value, or the larger or smaller representable value immediately
adjacent to the nearest representable value, chosen in an implementation-defined manner.
It's the 5% part of your exercice. It's equal to: original_amout + (original_amout * 5.0 / 100.0).
it means 1.05 as float float you can take the f away it should work
printf has the prototype as int printf(const char *restrict format, ...);, it uses the const char *restrict format string to format the data printed.
You are confused between the format specifier %.2f which is passed as the 1st parameter to printf and the 1.05f passed as part of argument list. As you point out, first one is used for formatting. The argument list 1.05f is used for calculation purposes.The f indicates to the compiler you want to use a float or else by default it will be considered double datatype and the result of original_amount * 1.05f will be stored in a double.
It is sufficient to use a float when you know the number would fit in the float range.And to indicate this, you append a f to numbers in the argument list