C: strtof wrong conversion by a unit [duplicate] - c

This question already has answers here:
Why are floating point numbers inaccurate?
(5 answers)
Why is scanf taking the wrong input for large float numbers? [duplicate]
(1 answer)
Is floating point math broken?
(31 answers)
Closed 5 years ago.
I'm having problems with strtof conversions, some values it works well but another ones it returns +1 or -1 of the value. My program reads the value from a file but for simplicity I have tried putting directly the value to strtof and it has the same behavior.
My simple code:
#include <stdlib.h>
int main(int argc, char **argv)
{
printf("%f", strtof("17309217",NULL));
}
It returns
17309216.000000
The same value that it gives if I convert "17309216" or "17309215".
I have been doing some more tests and it seems a "pattern", "17309214" works well but "17309213", "17309212" and "17309211" all return "17309212". After this "17309210" works well but "17309209", "17309208" and "17309207" return "17309208", and so on...
What is the explanation for this behaviour? Now I convert the string with other methods, I don't need a method to convert it. I only want to know why strtof is doing this, so I can decide where I can use it and where can't.
I have been reading some other questions asked related to wrong conversions but all are related to the decimal rounding, not an entire unit.
Thanks in advance,

You're converting to a 32-bit floating point which may not have the precision to handle that many digits.

Related

About the division of floating point numbers in C language。 [duplicate]

This question already has answers here:
What happens when I use the wrong format specifier?
(2 answers)
Closed 5 months ago.
I am a university student. When learning C language, I encountered the problem of floating point division. Can anyone help me to see why the results are different every time I run it. thank you very much.( I am running in a Linux)
My English is not good, hope you can understand the meaning of my question。
#include <stdio.h>
int main()
{
double a = 1;
double b = 2;
printf("%d\n",b/a);
return 0;
}
You're using the wrong format specifier.
The %d former specifier for printf expects an int as an argument, but you're passing in a double. Using the wrong format specifier triggers undefined behavior.
You should instead use %f which is for printing a double.
printf("%f\n",b/a);

Why is there no output for this program? [duplicate]

This question already has answers here:
Comparing float and double in C
(2 answers)
strange output in comparison of float with float literal
(8 answers)
Closed 1 year ago.
Can someone pls explain me why this is not printing hello?
int main(){
float i;
i=1.2;
while (i==1.2){
printf("hello");
}
Computers only store digital information. Integers can be represented accurately in binary, but floating point numbers are approximated.
It seems that in the approximations, additional tiny values are preventing your exact comparison from being true.
Now is a good time to google "what every programmer should know about floating point numbers" and read it. It will save you countless hours of future programming and debugging if you learn it early.
In addition, there are two floating point types "float" and "double". You are comparing a float to a double, so the approximations of the value are likely not the same approximation, creating more of a chance that the two values won't be equal.

how can I convert a fraction inputted as string to float in C [duplicate]

This question already has answers here:
How to Write a Boolean Expression Evaluator in C?
(9 answers)
Closed 5 years ago.
A string is input as a fraction, how can I convert this string to float?
In the below code it always show the first number only without any calculations i.e : 2.00
int main (void)
{
string fraction = "2/4";
float sum = atof(fraction);
printf("sum : %.2f\n",sum);
return 0;
}
First of all, your assumption is wrong.
A string like "2/4", is "2/4", it's not "0.5", i.e., it does not evaluate itself to produce the result of the expected expression.
That said, atof() family is not safe (at least, poor with reporting / handling error conditions, which, in your particular case, would have been very useful, should you have checked the return code), please use strtod() and family.
You cannot do this directly. With atof you e.g. change "2.034" to 2.034 (f), but not an expression (with a division in your case).
Instead, if you know there will be always a divider symbol, search for the divider symbol, than extract the left and right part, use atoi (string to integer), and divide the two integers (after casting to float).

limits on sprintf precision [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 5 years ago.
I came across this code recently. It produces strange results (lots of random digits after about the 18th digit.) I tried to find information on the limits to sprintf but could not find it. I am trying to figure out if the answer is actually correct or just garbage. When passed 0.025 (as a double) it prints out:
0.025000000000000001387778780781445675529539585113525390625
#define MAX_NUM_STR_LEN 128
void File_WriteNumber(File *fp, double value) {
char numbuf[MAX_NUM_STR_LEN];
int sz = sprintf(numbuf, "%.100g", value);
fwrite (numbuf , sizeof(char), sz, fp);
}
Answer is actually correct - not random digits.
double can typically represent exactly about 264 different values.
0.025 is not one of them with a binary64 double.
The closest double is 0.025000000000000001387....
The next closest double is 0.024999999999999997918...
sprintf() is doing just fine.

How to convert char to double in C? [duplicate]

This question already has answers here:
Floating point does not print accurately [duplicate]
(4 answers)
Closed 8 years ago.
I want to convert a char like "12345678901234567890.123 " to double,
so I use sscanf(str, "%lf", &d),
and I print it use printf("%20.3lf", d);
But I get the result is "12345678901234567178.000",
How can I fix it?
You probably can't, since you're trying to store a number with more digits of precision than will fit in your machine's double data type.
You need to use a big-number library, that "manually" computes with arbitrary number of digits and thus can go beyond the limits of your machine's basic data types.
Oh, and "12345678901234567890.123" is not "a char", it's called "a string".

Resources