about %Lf and %Le can not print rightly - c

I ran a program like this:
#include <stdio.h>
int main(void)
{
float aboat = 32000.0;
double abet = 2.14e9;
long double dip =5.32e-5;
printf("%f can be written %e\n",aboat,aboat);
printf("And it's %a in hexadecimal, powers of 2 notation\n",aboat);
printf("%f can be written %e\n",abet, abet);
printf("%Lf can be written %Le\n",dip,dip);
\\ this statement can not print rightly
return 0;
}
but it print like this :
32000.000000 can be written 3.200000e+004
And it's 0x1.f40000p+14 in hexadecimal, powers of 2 notation
2140000000.000000 can be written 2.140000e+009
-1950228512509697500000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000.0
00000 can be written 272.500183
as you can see , this result must be incorrect. but I can not find error, so is it a bug attribute to IDE ? I use JetBrains CLion 2017.3.4.
thanks for remind.this is my CMakeList.txt:
cmake_minimum_required(VERSION 3.9)
project(untitled1 C)
set(CMAKE_C_STANDARD 11)
add_executable(untitled1 main.c)
And the gcc version is 6.3.0

Related

C format printf(%Lf) have wrong result

I'm a beginner of C. When I use printf format %Lf, I got a wrong result. My code is like below.
long double dip = 5.32e-5;
printf("%Lf can be written %Le\n", dip, dip);
And I got the result as below:
0.000000 can be written 3.172882e-317
I wrote my code in vs code + MinGW. Any mistakes in my code?
It seems MinGW doesn't support %Lf format by default.
Adding -std=c99 compiler option may get it work.
This code worked on my MinGW gcc 4.8.1 with -std=c99 option (I didn't use vs code):
#include <stdio.h>
int main(void) {
long double dip = 5.32e-5;
printf("%Lf can be written %Le\n", dip, dip);
}
output:
0.000053 can be written 5.320000e-005

atan2f gives different results with m32 flag

I'm porting some code from 32 bit to 64 bit, and ensuring the answers are the same. In doing so, I noticed that atan2f was giving different results between the two.
I created this min repro:
#include <stdio.h>
#include <math.h>
void testAtan2fIssue(float A, float B)
{
float atan2fResult = atan2f(A, B);
printf("atan2f: %.15f\n", atan2fResult);
float atan2Result = atan2(A, B);
printf("atan2: %.15f\n", atan2Result);
}
int main()
{
float A = 16.323556900024414;
float B = -5.843180656433105;
testAtan2fIssue(A, B);
}
When built with:
gcc compilerTest.c -m32 -o 32bit.out -lm
it gives:
atan2f: 1.914544820785522
atan2: 1.914544820785522
When built with:
gcc compilerTest.c -o 64bit.out -lm
it gives:
atan2f: 1.914544701576233
atan2: 1.914544820785522
Note that atan2 gives the same result in both cases, but atan2f does not.
Things I have tried:
Building the 32 bit version with -ffloat-store
Building the 32 bit version with -msse2 -mfpmath=sse
Building the 64 bit version with -mfpmath=387
None changed the results for me.
(All of these were based on the hypothesis that it has something to do with the way floating point operations happen on 32 bit vs 64 bit architectures.)
Question:
What are my options for getting them to give the same result? (Is there a compiler flag I could use?) And also, what is happening here?
I'm running on an i7 machine, if that is helpful.
This is easier to see in hex notation.
void testAtan2fIssue(float A, float B) {
double d = atan2(A, B);
printf(" atan2 : %.13a %.15f\n", d, d);
float f = atan2f(A, B);
printf(" atan2f: %.13a %.15f\n", f, f);
printf("(float) atan2 : %.13a %.15f\n", (float) d, (float) d);
float f2 = nextafterf(f, 0);
printf("problem value : %.13a %.15f\n", f2, f2);
}
// _ added for clarity
atan2 : 0x1.ea1f9_b9d85de4p+0 1.914544_797857041
atan2f: 0x1.ea1f9_c0000000p+0 1.914544_820785522
(float) atan2 : 0x1.ea1f9_c0000000p+0 1.914544_820785522
problem value : 0x1.ea1f9_a0000000p+0 1.914544_701576233
what is happening here?
The conversion from double to float can be expected to be optimal, yet arctangent functions may be a few ULP off on various platforms. The 1.914544701576233 is the next smaller float value and reflects the slightly inferior arctangent calculation.
What are my options for getting them to give the same result?
Few. Code could roll your own my_atan2() from an established code base. Yet even that may have subtle implementation differences. #stark
Instead, consider making code checking tolerant of the minute variations.

Weird C program behaviour

I have the following C program:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
int main() {
const int opt_count = 2;
int oc = 30;
int c = 900;
printf("%d %f\n", c, pow(oc, opt_count));
assert(c == (int)(pow(oc, opt_count)));
}
I'm running MinGW on Windows 8.1. Gcc version 4.9.3. I compile my program with:
gcc program.c -o program.exe
When I run it I get this output:
$ program
900 900.000000
Assertion failed: c == (int)(pow(oc, opt_count)), file program.c, line 16
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
What is going on? I expect the assertion to pass because 900 == 30^2.
Thanks!
Edit
I'm not using any fractions or decimals. I'm only using integers.
This happens when the implementation of pow is via
pow(x,y) = exp(log(x)*y)
Other library implementations first reduce the exponent by integer powers, thus avoiding this small floating point error.
More involved implementations contain steps like
pow(x,y) {
if(y<0) return 1/pow(x, -y);
n = (int)round(y);
y = y-n;
px = x; powxn = 1;
while(n>0) {
if(n%2==1) powxn *= px;
n /=2; px *= px;
}
return powxn * exp(log(x)*y);
}
with the usual divide-n-conquer resp. halving-n-squaring approach for the integer power powxn.
You have a nice answer (and solution) from #LutzL, another solution is comparing the difference with an epsilon, e.g.: 0.00001, in this way you can use the standard function pow included in math.h
#define EPSILON 0.0001
#define EQ(a, b) (fabs(a - b) < EPSILON)
assert(EQ((double)c, pow(oc, opt_count)));

Symbolic Constant in Xcode

I'm learning C through The C Programming Language 2nd Edition and it refers to symbolic constants where you use #define before main() to assign a label to a value.
This is the program I am trying to use:
#include <stdio.h>
#define LOWER 0
#define UPPER 300
#define STEP 20
main()
{
int fahr;
for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP)
{
printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}
}
Printing a table of Fahrenheit Celsius conversions. However This code when compiled in xcode using the c tool gives me the response unable to read unknown load command referring to the line starting with for. I've tried retyping the program but it still hasn't worked. Any help would be much appreciated.
The first line should be
#include <stdio.h>
The code is perfectly fine. There's something wrong with your XCode setup (may be related: unable to read unknown load command.
cristi:tmp diciu$ cat test.c
#include <stdio.h>
#define LOWER 0
#define UPPER 300
#define STEP 20
main()
{
int fahr;
for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP)
printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}
cristi:tmp diciu$ gcc test.c
cristi:tmp diciu$ ./a.out
0 -17.8
20 -6.7
40 4.4
[..]
Works for me in XCode - the only warning/error I got was
Control reaches end of non-void function
As defining main() defaults to int it should return something, eg. 0 for a successful program. Convention suggests that 0 means a program runs correctly and anything else is an error.
Better to define
int main()
{
/* code */
return 0;
}
as your main function. But this is a digression - see diciu's answer for a potential explanation of your problem

floating point - absolute value - inline assembly - edited new code

I wrote a function named absD that i want to return the absolute value of its argument..
I am using GCC inline assembly with cygwin..
I dont see why its not working. i m loading into memory. then into st(0)
where i am using fabs - absolute value. Do i have to allocate memory?
I am trying to learn assembly with C here so please be nice. Please give me good help.
Thank you
heres the code and then the error:
#include <stdio.h>
#include <stdlib.h>
#define PRECISION 3
double absD (double n)
{
asm(
"fldl %[nIn]\n"
"fabs\n"
"fstpl %[nOut]\n"
: [nOut] "=m" (n)
: [nIn] "m" (n)
);
return n;
}
int main (int argc, char **argv)
{
double n = 0.0;
printf("Absolute value\n");
if (argc > 1)
n = atof(argv[1]);
printf("abs(%.*f) = %.*f\n", PRECISION, n, PRECISION, absD(n));
return 0;
}
here is the output:
~ $ gc a3
gcc -Wall -g a3.c -o a3
~ $ ./a3
Absolute value
abs(0.000) = 0.000
~ $
Not outputing its absolute value...
Thank you..
It is completely working..!! You are just forgetting to put values to argv. You can run the program with something like this:
./a3 -1.3
and it should return 1.3
you were done before posting it here...
fld (%eax) means "load a float from the value at address %eax". Obviously, the contents of %eax are a double, and not a pointer to a float, which is why you segfault.
Since the input is already on the stack (thus it has an address), there's no need to jump through hoops moving things around.
double absD(double input) {
double output;
asm(
"fldl %[input]\n"
"fabs\n"
"fstpl %[output]\n"
: [output] "=m" (output)
: [input] "m" (input)
);
return output;
}
Also, your printf format is wrong: %f means float, but you're giving it a double; you want to use %g.

Resources