I would like to return +INF but instead, I am only returning "inf":
int main(void)
{
double dubb = HUGE_VAL;
printf("%f \n", dubb);
}
Am I overlooking something here? Or it is just compiler semantics?
Use printf("%+F\n", dubb); instead
'+' makes printf display the sign
'F' makes inf/nan uppercase
You didn't tell us what C library you have. My man page on linux tells me:
The
C99 standard specifies "[-]inf" or "[-]infinity" for infinity, and a string starting with "nan" for NaN, in the case of f
converā
sion, and "[-]INF" or "[-]INFINITY" or "NAN*" in the case of F conversion.
So what you observe seems to be in sync with the C99 standard. Use "%F" to have it all caps, for the + just put it in front.
Related
I'm testing conversion specifiers both for printf() and scanf() function. I hadn't problem with %a format specifier for floating point hexadecimal number used in printf() function. It displayed what I expected. But I encountered problem when I wanted to input hexadecimal float using
scanf("%a", &var);
I'm using the following code:
#include <stdio.h>
int main()
{
float var;
printf("Enter variable:\n");
scanf("%a", &var);
printf("var = %f\n", var);
printf("var = %e\n", var);
printf("var = %a\n", var);
return 0;
}
When I enter a sample value, e.g. 0x1.205b0cp-11 that is 5.5e-4 it gives me that result:
Enter variable: 0x1.205bc0p-11
var = 0.000000 var = 0.000000e+000 var = 0x0.000000p+0
Whatever number I enter it always gives me 0. What's the reason or solution for that problem. I have no idea what I'm making wrong.
That code works on my system(a), producing the expected result:
pax> ./prog
Enter variable: 0x1.205bc0p-11
var = 0.000550
var = 5.500000e-04
var = 0x1.205bcp-11
Keep in mind that hexadecimal floating point constants (and the %a conversion specifier) were introduced in C99, so you should make sure you're using a compiler that handles that. Most modern ones will, but some people may be locked in to a certain level if the vendor isn't keen on keeping up to date(b).
Keep in mind that the scanf family, conversion specifiers a, e, g, and f (and their upper-case variants) are all the same - they each handle every format that strtod handles. The (likely) reason that they all exist is to mirror the printf conversion specifiers where it makes a difference to how the value is output.
It's possibly worth testing with a variety of inputs less advanced than hex floating point, and work your way up to there. For example, the sequence { 0, 3, 3.1, 3.14159. 9e2, 6e-2, ... }. That would at least let you know where the input is failing.
Also, it's a good idea to test the conversion to ensure it works (this is true of all calls where failure can adversely affect future program behaviour). In other words, something like this in place of your scanf statement:
if (scanf("%a", &var) != 1) {
fprintf(stderr, "Something went horribly wrong!\n");
return 1;
}
(a) My system, by the way, is gcc 9.4.0 (from gcc --version) running on Ubuntu 20.04.2 (from cat /etc/lsb_release). It's often a good idea to include that sort of information in questions, it can help us figure out issues more quickly.
(b) Possibly a good reason to consider changing vendors though, of course, subject to normal cost/benefit analysis.
Try computing somehow like with printf("var = %e\n", var/7.0 + var *var);. Sometimes simple code without doing any math does not link in the math library needed by printf().
first of all, compiling with flags -Wall, -ansi, -pedantic. no warnings or errors. and no debugging is helping.
basically my code is working fine however returning very weird and unexpected results when I turn a token from a string to a float using strtof()
the section of code below is:
printf("token is %s\n", token);
newstockdata->unitPrice = strtof(token, NULL);
printf("price is %d\n", newstockdata->unitPrice);
newstockdata is allocated to the correct size: unitPrice is a float variable: the first printf statement prints "150.00": the second printf statement prints "0" but after a few iterations it returns a really long consistent number. any help please?
The problem is here, assuming that unitPrice is a float:
printf("price is %d\n", newstockdata->unitPrice);
To print a float you must use the %f specifier. Otherwise, it is undefined behaviour and anything could happen.
A possible explanation of the changing values you see might be that your system passes floats in a different register to ints. The printf receiving %d is looking in a register that is never set, so you are seeing whatever value was left over from some previous operation.
This is actually pretty common, here is an example - %esi is used for the int, and %xmm0 is used for the floating-point value.
You have to handle overflow cases. After calling strtof() check errno for overflow. If you think the values could be very long, you can use double or long double.
Someone has asked me, why this code produces a random number:
double a = 75.0;
printf("%d\n", a);
I thought the reason was that 4 bytes of the double are interpreted as an integer, but the printed value was different each time the program was run. So i started to try some more things and found that this:
printf("%d\n", 75.0, 6);
actually prints out number 6. So i thought that the compiler is trying to fix the arguments so that they match the format string, but then i tried this:
const char *formats[] = { "%d %.1f\n", "%.1f %d\n" };
int whichFormat = 0;
scanf("%d", &whichFormat);
printf(formats[whichFormat&1], 2.5, 7, 1.2);
The formatting string now isn't even known at compile time, but it still somehow manages to match the argument types to the formatting string, printing either 7 2.5 or 2.5 7 depending on the input. The last value (1.2) was not printed.
All of this can be reproduced at compileonline.com which claims to be using GNU GCC 4.8.1.
What is going on here?
Undefined behavior is going on.
Such behavior is undefined, so it's very hard to reason about, and also somewhat pointless to do experiments, since there's no guarantee that the behavior stays the same (i.e. well-defined) for the same input. The behavior is, after all, undefined.
The first example, for instance, might read an expected integer argument from one register, while the actual floating-point argument is in another. I'm not saying this is what happens on any known machine, but it could be like that.
I have the foll line of code.
int i =125;
char s[]="hello";
char c='z';
printf("%f",i);
printf("%f",c);
printf("%f",s);
output -936283178250000000000.000000 -936283178250000000000.000000 -936283178250000000000.000000 what does this mean??
It means you are using the incorrect formatting directives. Try this instead:
printf("%d", i);
printf("%c", c);
alternatively, cast your two values in i and c to float (but that doesn't make much sense, especially in the case of c), better to use the right formatting directives.
When you use the incorrect specifier, the behavior is undefined, which is what you are observing.
Where did you get %f from? If not mistaken %f is a C++ parameter for floating point numbers.
By you using:
int i =125;
char s[]="hello";
char c='z';
printf("%f",i);
printf("%f",c);
printf("%f",s);
You are telling the compiler that everything you are printing is a floating point number (a.k.a decimal), when in fact it should be
printf("%d",i);
printf("%c",c);
printf("%s",s);
Using a wrong format specifier in printf will result in undefined behavior. When I say undefined behavior, it can give an output but the output may vary from one C implementation to another. Usually this will result in a warning. GCC compiler will issue a warning for this.
I'm trying to parse an argument value in C and convert the number to a double value. I have:
char *stringEnd;
double num = strtod("123.0", &stringEnd);
I used "123.0" just to test the function, but it always returns a value of 0.0. Does anybody know what I'm doing wrong?
Are you including the relevant header? ie: #include <stdlib.h>
First though (and you should be doing this all the time anyway), try compiling with all warnings on (-Wall on GCC).
If you get a warning about strtod being undefined, that shows where the problem is coming from.
This is a nasty one, because C will implicitly declare any function it doesn't have a prototype for as returning int!
You if have to use strtod in order to use:
double num = strtod("123.0", NULL);
you can also use sscanf
double num;
sscanf("123.0", "%lf", &num);
You can use sscanf.
double num;
sscanf("123.0", "%lf", &num);
You need to #include stdlib.h.
In which language is your operating system? I'm not sure how the C function strtod reacts, but I know that the equivalent delphi function takes the settings of the operating system into account. Some languages (french, german, ...) use a "," instead of a "." as decimal separator.