Float data without fraction part [duplicate] - c

This question already has answers here:
Why isn't "0f" treated as a floating point literal in C++?
(6 answers)
Closed 8 years ago.
The make difference between double and float data, we add f. But when i tried to write:
float Value = 255f;
The compiler diplays the following error.:
line 50: error (dcc:1633): parse error near 'f'
line 50: error (dcc:1206): syntax error
line 50: fatal error (dcc:1340): can't recover from earlier errors
Why ?

According to draft n1570, §6.4.4.2, paragraph ¶2
Description
A floating constant has a significand part that may be followed by an exponent part and a
suffix that specifies its type. The components of the significand part may include a digit
sequence representing the whole-number part, followed by a period (.), followed by a
digit sequence representing the fraction part. The components of the exponent part are an
e, E, p, or P followed by an exponent consisting of an optionally signed digit sequence.
Either the whole-number part or the fraction part has to be present; for decimal floating
constants, either the period or the exponent part has to be present.
I made the relevant part bold, so you can see why it doesn't work.
Note that this also implies that
float value = 255e0f;
works.

You need a period in addition, in order the compiler to accept it:
float Value = 255.f;
It's part of the standard specification but I guess it was chosen this way in order to simplify the implementation of the lexical analyzer and also improve the readability of the number, since it's easy to think it's a hex number otherwise.

My guess would be that you are missing a period in your code.
float Value = 255.f;
Add a period before f and you should be good to go. If this doesn't work, please tell us what Error you're receiving.

Related

How does printf for float does not print the correct value for floating point [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
So i have been trying to make my own printf and now i stuck at %f.
The problem i have is i don't know what printf does in the background when i give it a float number like: f = 1.4769996 it print 1.477000.
but when i give it f = 1.4759995 it print the value 1.475999
float f = 1.4769996;
printf("%f\n", f); // 1.477000
f = 1.4759995;
printf("%f\n", f); // 1.475999
what i thought of is that printf see the 5 at last and it adds one but not working in the second example.
What is the logic behind this floating point ?
Your C implementation likely uses the IEEE-754 binary32 and binary64 formats for float and double. Given this, float f = 1.4769996; results in setting f to 1.47699964046478271484375, and f = 1.4759995; results in setting f to 1.47599947452545166015625.
Then it is easy to see that rounding 1.47699964046478271484375 to six digits after the decimal point results in 1.477000 (because the next digit is 6, so we round up), and rounding 1.47599947452545166015625 to six digits after the decimal point results in 1.475999 (because the next digit is 4, so we round down).
When working with floating-point numbers, it is important to understand each floating-point value represents one number exactly (unless it is a Not a Number [NaN] encoding). When you write 1.4769996 in source code, it is converted to a value representable in double. When you assign it to a float, it is converted to a value representable in float. Operations on the floating-point object behave as if the object have exactly the value it represents, not as if its value is the numeral you wrote in source code.
To provide some further details, the C standard requires (in C 2018 7.21.6.1 13) that formatting with f be correctly rounded if the number of digits requested is at most DECIMAL_DIG. DECIMAL_DIG is the number of decimal digits in the widest floating-point format the implementation supports such that converting any number in that format to a numeral with DECIMAL_DIG significant decimal digits and back to the floating-point format yields the original value (5.2.4.2.2 12). DECIMAL_DIG must be at least 10. If more than DECIMAL_DIG digits are requested, the C standard allows some leeway in rounding. However, high-quality C implementations will round correctly as specified by IEEE-754 (to the nearest number with the requested number of digits, with ties favoring an even low digit).
If you are trying to write your own printf, and if you are stuck on %f, there are three or four things you need to know:
When a "varargs" function like printf is called, arguments of type float are always implicitly promoted to type double. So when you've seen %f in the format string, and you're using va_arg() to pluck the next argument from the list, you'll want to pluck an argument of type double, not float. (This also means that you have just one case to handle, not two. Inside printf, you don't have to worry about handling type float at all.)
Printing the whole-number part of a double is easy; it's more or less the same problem as printing an int, which I'm guessing you've already figured out, if you've got %d working. And to do a straightforward, simpleminded job of printing the fractional part, it usually works pretty well to just repeatedly multiply by 10. That is, if you're trying to print 123.456, and you've already got the 123 part taken care of, you can then proceed to print the rest by taking the fractional part 0.456, multiplying by 10 to get 4.56 then truncating to get 4, then taking the new fractional part 0.56 and repeating.
There is no such number as 1.4769996. (There's no such number as the 123.456 I was just using, either.) When we write numbers like 1.4769996 and 123.456 we're thinking about decimal fractions, but most computers (including the one you're using) use binary fractions internally, and you can't represent decimal fractions like 1.4769996 and 123.456 exactly in binary, so the actual numbers are always a little bit different than you expect, which is why you often get slight "roundoff error", or extra 999's at the end when you expected 000.
Doing a proper job on this stuff is really, really hard. If you're trying to write your own printf, and you've gotten to %f, and if you can get it working pretty well most of the time, consider yourself lucky, and call it a day. Don't get bogged down on the last digit -- or if you're bound and determined to get the last digit right in every case (which is certainly a noble goal), do some research and set aside some time, because you're going to be working at it for a while.

Simple floating point multiplication not giving expected result [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
When given the input 150, I expect the output to be the mathematically correct answer 70685.7750, but I am getting the wrong output 70685.7812.
#include<stdio.h>
int main()
{
float A,n,R;
n=3.14159;
scanf("%f",&R);
A=n*(R*R);
printf("A=%.4f\n",A);
}
float and double numbers are not represented very accurately in the memory. The main reason is that the memory is limited, and most non-integers are not.
The best example is PI. You can specify as many digits as you want, but it will still be an approximation.
The limited precision of representing the numbers is the reason of the following rule:
when working with floats and double numbers, not not check for equality (m == n), but check that the difference between them is smaller than a certain error ((m-n) < e)
Please note, as mentioned in the comments too, that the above rule is not "the mother rule of all rules". There are other rules also.
Careful analysis must be done for each particular situation, in order to have a properly working application.
(Thanks #EricPostpischil for the reminder)
It is common for a variable of type float to be an IEEE-754 32-bit floating point number.
The number 3.14159 cannot be stored exactly in an IEEE-754 32-bit float - the closest value is approximately 3.14159012. 150 * 150 * 3.14159012 is 70685.7777, and the closest value to this that can be represented in a 32-bit float is 70685.78125, which you are then printing with %.4f so you see 70685.7812.
Another way of thinking about this is that your n value only ends up being accurate to the sixth significant figure, so - as you are just calculating a series of multiplications - your result is also only acccurate to the sixth significant figure (ie 70685.8). (In the general case this can be worse - for example subtraction of two close values can lead to a large increase in the relative error).
If you switch to using variables of type double (and change the scanf() to use %lf), then you will likely get the answer you are after. double is typically a 64-bit float, which means that the error in the representation of your n values and the result is small enough not to affect the fourth decimal place.
Have you heard that float and double values aren't always perfectly accurate, have limited precision? Have you heard that type float gives you the equivalent of only about 7 decimal digits' worth of precision? This is what that means. Your expected and actual answers, 70685.7750 and 70685.7812, differ in the seventh digit, just about as expected.
I expect the output to be the mathematically correct answer
I am sorry to disappoint you, but that's your mistake. As a general rule, when you're doing floating-point arithmetic, you will never get the mathematically correct answer, you will always get a limited-precision approximation of the mathematically correct answer.
The canonical SO answers to this sort of question are collected at Is floating point math broken?. You might want to read some of those answers for more enlightenment.

How does printf in C round floating-point numbers?

I'm trying to implement printf and I want to know how printf rounds floating-point numbers because I cannot find a general rule
If for example input => printf("|%.f| |%.1f| |%.2f| |%.5f| |%.12f", 0.000099, 0.000099, 0.000099, 0.000099, 0.000099);
Here is the output => |0| |0.0| |0.00| |0.00010| |0.000099000000
I use the method from IEEE-754 so our floating-point number in memory is: 0.000098999999999999994037755413067714016506215557456016540527343750
My question is when and how should I round my floating-point number?
I am looking for a general rule that I must follow for all floating-point numbers.
Not sure if this is exactly how printf does it, but this seems to work for your example:
Add 5/(10^(number of decimal points+1). Then truncate.
Your interpretation is flawed: Your C compiler is upcasting your constants to doubles. So it's not using 0.0000989999.... It's using the more accurate double equivalent.
Try this:
printf("|%.f| |%.1f| |%.2f| |%.5f| |%.12f", (float)0.000099, (float)0.000099, (float)0.000099, (float)0.000099, (float)0.000099);
Output:
|0| |0.0| |0.00| |0.00010| |0.000098999997
The problem you are trying to address is actually very difficult to solve correctly.
Many existing printf implementations use conversion code dtoa.c written by David M. Gay almost 30 years ago.
You can learn more about this from this question, which is not an exact duplicate:
Why does "dtoa.c" contain so much code?
And these sites:
Rick Regan's blog article https://www.exploringbinary.com/quick-and-dirty-floating-point-to-decimal-conversion/
Clinger's How to Read Floating Point Numbers Accurately
David M. Gay's paper, Correctly Rounded Binary-Decimal and Decimal-Binary Conversions.
David Goldberg's What Every Computer Scientist Should Know About Floating Point Arithmetic.
The C standard provides the following in §7.21.6.1p13:
For e, E, f, F, g, and G conversions, if the number of significant decimal digits is at most DECIMAL_DIG, then the result should be correctly rounded. If the number of significant decimal digits is more than DECIMAL_DIG but the source value is exactly representable with DECIMAL_DIG digits, then the result should be an exact representation with trailing zeros. Otherwise, the source value is bounded by two adjacent decimal strings L<U, both having DECIMAL_DIG significant digits; the value of the resultant decimal string D should satisfy L ≤ D ≤ U, with the extra stipulation that the error should have a correct sign for the current rounding direction.
However, that paragraph is part of a subsection headed "Recommended Practice". (If Annex F is in effect, then the recommended practice is required. See F.5.)
"Correctly rounded" is defined by the current rounding direction. See fesetround.

Why does printing a float having value 2.5367 using `%3.3f` output 2.537 instead of 2.536? [duplicate]

This question already has answers here:
Why is printf round floating point numbers up?
(3 answers)
Closed 6 years ago.
#include<stdio.h>
void main()
{
float f = 2.5367;
printf("%3.3f",f);
}
Output is : 2.537
But how?
I think output should be 2.536 but the output is 2.537.
Because 2.5367 is closer to 2.537. Delta from 2.536 is 0.007 while delta from 2.537 is just 0.003.
What you want to do is just deleting last character of its string representation and is wrong in math.
In addition to existing answers, note that many C compilers try to follow IEEE 754 for floating-point matters. IEEE 754 recommends rounding according to the current rounding mode for conversions from binary floating-point to decimal. The default rounding mode is “round to nearest and ties to even”. Some compilation platforms do not take the rounding mode into account and always round according to the default nearest-even mode in conversions from floating-point to decimal.
since float f = 2.5367 needs to rounding up and there should be 3 digit after decimal, so the value will be 2.*** , means 2.537.
The documentation says:
The precision value specifies the number of digits after the decimal point. If a decimal point appears, at least one digit appears before it. The value is rounded to the appropriate number of digits.
That said, please use another book or resource for learning, whoever taught you that it's ok to use void main() is plain wrong and should not teach C.

Correct strtod implementation?

Simple question: what is the correct bit-representation of the number 1.15507e-173, in double precision?
Full question: how does one determine the correct parsing of this number?
Background: my question follows from this answer which shows two different bit-representations from three different parsers, namely
0x1c06dace8bda0ee0
and
0x1c06dace8bda0edf
and I'm wondering which parser has got it right.
Update Section 6.4.4.2 of the C99 specification says that for the C parser,
"...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."
This implies that the parsed number need not be the nearest, nor even one of the two adjacent representable numbers. The same spec in 7.20.1.3 says that strtod() behaves essentially the same way as the built-in parser. Thanks to the answerers who pointed this out.
Also see this answer to a similar question, and this blog.
:= num1 = ImportString["\.1c\.06\.da\.ce\.8b\.da\.0e\.e0", "Real64", ByteOrdering->1] // First;
:= num2 = ImportString["\.1c\.06\.da\.ce\.8b\.da\.0e\.df", "Real64", ByteOrdering->1] // First;
:= SetPrecision[num1, Infinity]-numOr //N
:= numOr = SetPrecision[1.15507, Infinity] * 10^-173;
-190
= -6.65645 10
:= SetPrecision[num2, Infinity]-numOr //N
-189
= -2.46118 10
Given that both deviate for the same side, it follows that the correct representation is the first one.

Resources