What Is "\t%.10g\n" - c

I'm new at Bison, but in C/C++ no and at this time of development and regular expressions i never heard something like this, only the \n that's used for a new line, but i want to know what is the explanation of \t%.10g, that in the code is like this:
line: '\n'
| exp '\n' { printf ("\t%.10g\n", $1); }
;
Best Regards.

It means "print a tab character (\t) followed by a floating point number with 10 decimal places, either in scientific or fixed point notation depending on the order of magnitude (%.10g), followed by a newline (\n)".

Have a look at the printf reference to decode the pattern:
g Use the shorter of %e or %f
e Scientific notation (mantise/exponent) using e character
f Decimal floating point
Thus, %.10g prints a decimal number with ten significant digits.

It's not a regex but a printf format specification : Print a tab character followed by a floating point number with 10 digits behind the decimal point, either %f (floating point notation) way or %e (scientific notatation) way, whichever is shorter, and end with a newline.
man printf

Related

Is there a way to automatically printf a float to the number of decimal places it has?

I've written a program to display floats to the appropriate number of decimal places:
#include <stdio.h>
int main() {
printf("%.2f, %.10f, %.5f, %.5f\n", 1.27, 345.1415926535, 1.22013, 0.00008);
}
Is there any kind of conversion character that is like %.(however many decimal places the number has)f or do they always have to be set manually?
Is there a way to automatically printf a float to the number of decimal places it has?
Use "%g". "%g" lops off trailing zero digits.
... unless the # flag is used, any trailing zeros are removed from the fractional portion of the result and the decimal-point character is removed if there is no fractional portion remaining. C17dr § 7.21.6.1 8.
All finite floating point values are exactly representable in decimal - some need many digits to print exactly. Up to DBL_DECIMAL_DIG from <float.h> (typically 17) significant digits is sufficient - rarely a need for more.
Pass in a precision to encourage enough output, but not too much.
Remember values like 0.00008 are not exactly encoded in the typical binary floating point double, but a nearby value is used like 8.00000000000000065442...e-05
printf("%.*g\n", DBL_DECIMAL_DIG, some_double);
printf("%.17g, %.17g, %.17g, %.17g\n", 1.27, 345.1415926535, 1.22013, 0.00008);
// 1.27, 345.14159265350003, 1.2201299999999999, 8.0000000000000007e-05
DBL_DIG (e.g. 15) may better meet OP's goal.
printf("%.15g, %.15g, %.15g, %.15g\n", 1.27, 345.1415926535, 1.22013, 0.00008);
// 1.27, 345.1415926535, 1.22013, 8e-05
Function to print a double - exactly may take 100s of digits.
sprintf() could help you
There is no direct way to do this in my experience
here is a simple algorithm to help you with this function
munber = float/double input
n = number of decimal places in float/double
char format[999];
sprintf(format ,"%%.%df" ,n);
printf(format, number);
sprintf is like printf but instead of writing to stdout, sprintf writes to a string.
Now you are left with finding number of digits after the precision.

sscanf("0X80.9", "%f", &value) sets value to a hex float not a float

I have some code that reads letter value pairs. It can be simplified as:
float value = 0.0;
sscanf("0X80.9", "%f", &value);
In Visual Studio 2013, value = 0
In Visual Studio 2015 and above, value = 128.5625 (i.e. 0x80 in hex = 128 in decimal)
Anyone know why this has changed? More importantly, anyone know how to make it work like it used to?
C99 added a new feature, hexadecimal floating-point constants. It also added new formats to the *scanf() functions. (A hexadecimal floating-point constant in source code must have an exponent part; for scanf, the exponent is optional.)
scanf reads as much of the input as it can that's consistent with the format. For pre-1999 C, this is the initial "0"; the following "X80.9"is left. For C99, "0X80.9" is valid, and is converted to the floating-point value 128.5625. (The format is the same as what's accepted by strtof().)
The C++ standard includes most of the C standard library by reference. It didn't update to the C99 version of the C library until c++2012.
Most likely Visual Studio 2015 supports C++12 or later, and Visual Studio 2013 doesn't.
Since the new behavior is now standard, I suggest adapting your code to deal with it rather than trying to force the old behavior. If there's a way to make VS2015 behave in the old way, it should be documented.
C99 adds hexadecimal floating point constants. The printf() formats are %a and %A; there are the corresponding scanf() formats too. But as with %f, %e, %g, the scanf() floating point formats all accept any floating point format (so %f can read output printed using %e, etc).
ISO/IEC 9899:2011 — §6.4.4.2 Floating constants
floating-constant:
decimal-floating-constant
hexadecimal-floating-constant
…
hexadecimal-floating-constant:
hexadecimal-prefix hexadecimal-fractional-constant
binary-exponent-part floating-suffixopt
hexadecimal-prefix hexadecimal-digit-sequence
binary-exponent-part floating-suffixopt
…
hexadecimal-fractional-constant:
hexadecimal-digit-sequenceopt .
hexadecimal-digit-sequence
hexadecimal-digit-sequence .
binary-exponent-part:
p signopt digit-sequence
P signopt digit-sequence
hexadecimal-digit-sequence:
hexadecimal-digit
hexadecimal-digit-sequence hexadecimal-digit
floating-suffix: one of
f l F L
(The hexadecimal prefix is 0x or 0X of course.)
The 0X80.9 notation doesn't exactly correspond to the notation required of hexadecimal floating point constants in C source code because there is no 'binary-exponent-part', but …
the scanf() family of functions can only push back 1 character, so they can't tell there's a problem until far too late, so it ends up treating it as if there was a P0 at the end. The scanf() functions read data items according to a conversion specification:
An input item is read from the stream, unless the specification includes an n specifier. An
input item is defined as the longest sequence of input characters which does not exceed
any specified field width and which is, or is a prefix of, a matching input sequence.285)
The first character, if any, after the input item remains unread.
the strtod() family of functions accept:
— a 0x or 0X, then a nonempty sequence of hexadecimal digits optionally containing a
decimal-point character, then an optional binary exponent part as defined in 6.4.4.2;
and the scanf() family of functions accept:
a, e, f, g
Matches an optionally signed floating-point number, infinity, or NaN, whose
format is the same as expected for the subject sequence of the strtod
function. The corresponding argument shall be a pointer to floating.
In the 1999 C Standard it was added that the input for strtod (which is what %f in scanf refers to) can include a 0x or 0X prefix to indicate a hex float.
16 years later it seems Microsoft have finally gotten around to doing the work.
Your best option would be to move forward with the new behaviour, rather than trying to invoke compiler flags to get the old behaviour (which may not even be possible, I don't know).
To emulate the old behaviour in your project you could use code like:
double my_scan(char const *s)
{
double value = 0.0;
if ( ! memcmp(s, "0X", 2) )
sscanf(s, "%f", &value);
return value;
}
or whatever would suit your use case. Perhaps you might end up writing your own tokenizer.

Standard form in C

After a few hours of searching I have not been able to find an answer, but if this is a duplicate please point me in the correct direction.
Will a C program accept a standard form input into something like scanf("%f",&float); from the keyboard. Standard form is writing a number like 2400 as 2.4E3 if this helps you understand what I am asking.
I must stress this MUST be from the keyboard.
Yes.
scanf works identically, regardless of whether stdin is connected to a terminal, a file, or some other input stream.
The %a, %e, %f, %g scanf format codes all do the same thing: interpret the longest string which would be acceptable to strtod (§7.21.6.2/12). (And so do %A, %E, %F and %G -- paragraph 14 of the same clause.) The redundancy is because scanf formats accepts the same format codes as printf.
strtod accepts any of the following (§7.22.1.3/3):
a nonempty sequence of decimal digits optionally containing a decimal-point character, then an optional exponent part as defined in 6.4.4.2;
a 0x or 0X, then a nonempty sequence of hexadecimal digits optionally containing a decimal-point character, then an optional binary exponent part as defined in 6.4.4.2;
INF or INFINITY, ignoring case
NAN or NAN(n-char-sequenceopt), ignoring case in the NAN part,…
Yes, it is being accepted from my terminal and also the IDEone interpreter (added it in stdin which is the same as "from the keyboard").
And probably a typo, but you have missed the "" in
scanf("%f", &float)

Read scientific notation scanf

I am developing a program which should have only one scanf function and it should be able to accept input in scientific notation and real numbers.
Any help will be appreciated
According to the scanf documentation:
%f matches a floating-point number. The format of the number is the same as expected by strtof().
Looking at the strtof documentation
(optional) e or E followed with optional minus or plus sign and nonempty sequence of decimal digits (defines exponent)
Thus, you can use the %f specifier to read numbers in e notation. That is,
1e-3 is 1 * 10 ^ -3.

Making printf do the right thing with floating point

I'm trying to make printf 'do the right thing' with floating point numbers, i.e.:
Never lose information, always print as many decimals as are needed for the exact value
Don't print a bunch of redundant trailing zeros
Switch to scientific notation if the output would otherwise be unreasonably large
%.20g seems to do all that, but there's one more thing I would like to get:
If the value is an integer, do print a trailing '.0' to indicate it is a floating point number with an integer value, not a number of type integer
Is there any way to get the fourth criterion without losing any of the first three?
It looks like the flag "#" will at least put a period at the end. Try %#.20g.
The # flag is for example documented here:
"Used with a, A, e, E, f, F, g or G it forces the written output to contain a decimal point even if no more digits follow. By default, if no digits follow, no decimal point is written."

Resources