Weird C program behaviour - c

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)));

Related

C program to find roots error

I am writing a function in C with the below specifications:
float find_root(float a, float b, float c, float p, float q);
find_root takes the coefficients a,b,c of a quadratic equation and an interval (p, q). It will return the root of this equation in the given interval.
For example: find_root(1, -8, 15, 2, 4) should produce a root "close to" 3.0
I have written the below code, and I don't understand why it doesn't work:
#include<stdio.h>
#include<math.h>
main()
{
printf("Hello World");
}
float find_root(float a, float b, float c, float p, float q) {
float d,root1,root2;
d = b * b - 4 * a * c;
root1 = ( -b + sqrt(d)) / (2* a);
root2 = ( -b - sqrt(d)) / (2* a);
if (root1<=q || root1>=p)
{
return root1;
}
return root2;
}
Please let me know what the error is.
Your program doesn't work, because, you never called find_root() from your main().
find_root() is not suppossed to run all-by-itself. Your program statrs execution from main(). You need to call your sub-function from main() in order to make them execute.
Change your main to have a call to find_root(), something like below.
int main() //put proper signature
{
float anser = 0;
answer = find_root(1, -8, 15, 2, 4); //taken from the question
printf("The anser is %f\n", answer); //end with a \n, stdout is line buffered
return 0; //return some value, good practice
}
Then, compile the program like
gcc -o output yourfilename.c -lm
Apart from this, for the logical issue(s) in find_root() function, please follow the way suggested by Mr. #paxdiablo.
For that data, your two roots are 5 and 3. With p == 2 and q == 4:
if (root1<=q || root1>=p)
becomes:
if (5<=4 || 5>=2)
which is true, so you'll get 5.
The if condition you want is:
if ((p <= root1) && (root1 <= q))
as shown in the following program, that produces the correct 3:
#include<stdio.h>
#include<math.h>
float find_root (float a, float b, float c, float p, float q) {
float d,root1,root2;
d = b * b - 4 * a * c;
root1 = ( -b + sqrt(d)) / (2* a);
root2 = ( -b - sqrt(d)) / (2* a);
if ((p <= root1) && (root1 <= q))
return root1;
return root2;
}
int main (void) {
printf ("%f\n", find_root(1, -8, 15, 2, 4));
return 0;
}
That's the logic errors with your calculations of the roots.
Just keep in mind there are other issues with your code.
You need to ensure you actually call the function itself, your main as it stands does not.
It also wont produce a value within the p/q bounds, instead it will give you the first root if it's within those bounds, otherwise it'll give you the second root regardless of its value.
You may want to catch the situation where d is negative, since you don't want to take the square root of it:
a = 1000, b = 0, c = 1000: d <- -4,000,000
And, lastly, if your compiler is complaining about not being able to link sqrt (as per one of your comments), you'll probably find you can fix that by specifying the math library, something like:
gcc -o myprog myprog.c -lm
Your program starts at main by definition.
Your main function is not calling find_root but it should.
You need to compile with all warnings & debug info (gcc -Wall -Wextra -g) then use a debugger (gdb) to run your code step by step to understand the behavior of your program, so compile with
gcc -Wall -Wextra -g yoursource.c -lm -o yourbinary
or with
clang -Wall -Wextra -g yoursource.c -lm -o yourbinary
then learn how to use gdb (e.g. run gdb ./yourbinary ... and later ./yourbinary without a debugger)
Then you'll think and improve the source code and recompile it, and debug it again. And repeat that process till you are happy with your program.
BTW, you'll better end your printf format strings with \n or learn about fflush(3)
Don't forget to read the documentation of every function (like printf(3) ...) that you are calling.
You might want to give some arguments (thru your main(int argc, char**argv) ...) to your program. You could use atof(3) to convert them to a double
Read also about undefined behavior, which you should always avoid.
BTW, you can use any standard C compiler (and editor like emacs or gedit) for your homework, e.g. use gcc or clang on your Linux laptop (then use gdb ...). You don't need a specific seashell
Change this condition
if (root1<=q || root1>=p)
to
if (root1<=q && root1>=p)
otherwise if anyone of the conditions is satisfied, root1 will be returned and root2 will almost never be returned. Hope this fixes your problem.

static pre-calculation optimization in clang

I have
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <stdio.h>
#include <math.h>
int fib(int n) {
return n < 2 ? n : fib(n-1) + fib(n-2);
}
double clock_now()
{
struct timeval now;
gettimeofday(&now, NULL);
return (double)now.tv_sec + (double)now.tv_usec/1.0e6;
}
#define NITER 5
and in my main(), I'm doing a simple benchmark like this:
printf("hi\n");
double t = clock_now();
int f = 0;
double tmin = INFINITY;
for (int i=0; i<NITER; ++i) {
printf("run %i, %f\n", i, clock_now()-t);
t = clock_now();
f += fib(40);
t = clock_now()-t;
printf("%i %f\n", f, t);
if (t < tmin) tmin = t;
t = clock_now();
}
printf("fib,%.6f\n", tmin*1000);
When I compile with clang -O3 (LLVM 5.0 from Xcode 5.0.1), it always prints out zero time, except at the init of the for-loop, i.e. this:
hi
run 0, 0.866536
102334155 0.000000
run 1, 0.000001
204668310 0.000000
run 2, 0.000000
307002465 0.000000
run 3, 0.000000
409336620 0.000000
run 4, 0.000001
511670775 0.000000
fib,0.000000
It seems that it statically precalculates the fib(40) and stores it somewhere. Right? The strange lag at the beginning (0.8 secs) is probably because it loads that cache?
I'm doing this for benchmarking. The C compiler should optimize fib() itself as much as it can. However, I don't want it to precalculate it already at compile time. So basically I want all code optimized as heavily as possible, but not main() (or at least not this specific optimization). Can I do that somehow?
What optimization is it anyway in this specific case? It's somehow strange and quite nice.
I found a solution by marking certain data volatile. Esp, what I did was:
volatile int f = 0;
//...
volatile int FibArg = 40;
f += fib(FibArg);
That way, it forces the compiler to read FibArg when calling the function and it forces it to not assume that it is constant. Thus it must call the function to calculate it.
The volatile int f was not necessary for my compiler at the moment but it might be in the future when the compiler figures out that fib has no side effects and its result nor f is every used.
Note that this is still not the end. A future compiler could have advanced so far that it guesses that 40 is a likely argument for fib. Maybe it builds a database for likely values. And for the most likely values, it builds up a small cache. And when fib is called, it does a fast runtime-check whether it has that value cached. Of course, the runtime-check adds some overhead but maybe the compiler estimates that this overhead is minor for some particular code in relation to the speed gained by the cached.
I'm not sure if a compiler will ever do such optimization but it could. Profile Guided Optimization (PGO) goes already in that direction.

C fabs returning integer

I have a strange problem with fabs function in C code. I have two double values and I want to find the absolute value of their difference using code like this:
a = 87.967498;
b = 218.025015;
if (fabs(a-b)<2.0)
...code to execute
The value of fabs(a-b) is an int and is equal to 1. I don't know whats the problem here and I can't find anything on the net. Any help would be great!!
You didn't include <math.h>. Add the following line to your other includes:
#include <math.h>
In order to find such errors easier I recommend you to use verbose compiler warnings (gcc -Wall -Wextra ... if you use gcc).
The only way that fabs could return an int is either:
Your program uses a declaration of fabs other than the version declared in math.h.
Your program failed to include math.h and so does not declare fabs at all. In which case parameters and return values default to int. Which is of course an error because the actual implementation of fabs does not match and so the value returned is nonsense.
See this code:
#include <math.h>
#include <stdio.h>
int main()
{
float a = 87.967498;
float b = 218.025015;
float diff = a-b;
printf("diff=%f\nfabs(diff)=%f\n",diff,fabs(diff));
if (fabs(diff)<2.0) {
printf("OK\n");
} else {
printf("FAIL\n");
}
return 0;
}
It produces this output:
diego#malti:~/tmp$ clang test-math.c -o test-math -lm
diego#malti:~/tmp$ ./test-math
diff=-130.057510
fabs(diff)=130.057510
FAIL
See? The application is OK, the diff (218-87=130), which is not smaller then 2.
See also then when I am compile, I also link -lm to get the mathematical library. The same syntax applies for gcc, I just love using clang :)

double-precision numbers in inline assembly (GCC, IA-32)

I'm just starting to learn assembly and I want to round a floating-point value using a specified rounding mode. I've tried to implement this using fstcw, fldcw, and frndint.
Right now I get a couple of errors:
~ $ gc a02p
gcc -Wall -g a02p.c -o a02p
a02p.c: In function `roundD':
a02p.c:33: error: parse error before '[' token
a02p.c:21: warning: unused variable `mode'
~ $
I'm not sure if I am even doing this right at all. I don't want to use any predefined functions. I want to use GCC inline assembly.
This is the code:
#include <stdio.h>
#include <stdlib.h>
#define PRECISION 3
#define RND_CTL_BIT_SHIFT 10
// floating point rounding modes: IA-32 Manual, Vol. 1, p. 4-20
typedef enum {
ROUND_NEAREST_EVEN = 0 << RND_CTL_BIT_SHIFT,
ROUND_MINUS_INF = 1 << RND_CTL_BIT_SHIFT,
ROUND_PLUS_INF = 2 << RND_CTL_BIT_SHIFT,
ROUND_TOWARD_ZERO = 3 << RND_CTL_BIT_SHIFT
} RoundingMode;
double roundD (double n, RoundingMode roundingMode)
{
short c;
short mode = (( c & 0xf3ff) | (roundingMode));
asm("fldcw %[nIn] \n"
"fstcw %%eax \n" // not sure why i would need to store the CW
"fldcw %[modeIn] \n"
"frndint \n"
"fistp %[nOut] \n"
: [nOut] "=m" (n)
: [nIn] "m" (n)
: [modeIn] "m" (mode)
);
return n;
}
int main (int argc, char **argv)
{
double n = 0.0;
if (argc > 1)
n = atof(argv[1]);
printf("roundD even %.*f = %.*f\n",
PRECISION, n, PRECISION, roundD(n, ROUND_NEAREST_EVEN));
printf("roundD down %.*f = %.*f\n",
PRECISION, n, PRECISION, roundD(n, ROUND_MINUS_INF));
printf("roundD up %.*f = %.*f\n",
PRECISION, n, PRECISION, roundD(n, ROUND_PLUS_INF));
printf("roundD zero %.*f = %.*f\n",
PRECISION, n, PRECISION, roundD(n, ROUND_TOWARD_ZERO));
return 0;
}
Am I even remotely close to getting this right?
A better process is to write a simple function that rounds a floating point value. Next, instruct your compiler to print an assembly listing for the function. You may want to put the function in a separate file.
This process will show you the calling and exiting conventions used by the compiler. By placing the function in a separate file, you won't have to build other files. Also, it will give you the opportunity to replace the C language function with an assembly language function.
Although inline assembly is supported, I prefer to replace an entire function in assembly language and not use inline assembly (inline assembly isn't portable, so the source will have to be changed when porting to a different platform).
GCC's inline assembler syntax is arcane to say the least, and I do not claim to be an expert, but when I have used it I used this howto guide. In all examples all template markers are of the form %n where n is a number, rather then the %[ttt] form that you have used.
I also note that the line numbers reported in your error messages do not seem to correspond with the code you posted. So I wonder if they are in fact for this exact code?

log2 not found in my math.h?

I'm using a fairly new install of Visual C++ 2008 Express.
I'm trying to compile a program that uses the log2 function, which was found by including using Eclipse on a Mac, but this Windows computer can't find the function (error C3861: 'log2': identifier not found).
The way I understood it, include directories are specific to the IDE, right? math.h is not present in my Microsoft SDKs\Windows\v6.0A\Include\ directory, but I did find a math.h in this directory: Microsoft Visual Studio 9.0\VC\include. There is also a cmath in that directory...
Where is log2?
From here:
Prototype: double log2(double anumber);
Header File: math.h (C) or cmath (C++)
Alternatively emulate it like here
#include <math.h>
...
// Calculates log2 of number.
double Log2( double n )
{
// log(n)/log(2) is log2.
return log( n ) / log( 2 );
}
Unfortunately Microsoft does not provide it.
log2() is only defined in the C99 standard, not the C90 standard. Microsoft Visual C++ is not fully C99 compliant (heck, there isn't a single fully C99 compliant compiler in existence, I believe -- not even GCC fully supports it), so it's not required to provide log2().
If you're trying to find the log2 of strictly integers, some bitwise can't hurt:
#include <stdio.h>
unsigned int log2( unsigned int x )
{
unsigned int ans = 0 ;
while( x>>=1 ) ans++;
return ans ;
}
int main()
{
// log(7) = 2 here, log(8)=3.
//for( int i = 0 ; i < 32 ; i++ )
// printf( "log_2( %d ) = %d\n", i, log2( i ) ) ;
for( unsigned int i = 1 ; i <= (1<<30) ; i <<= 1 )
printf( "log_2( %d ) = %d\n", i, log2( i ) ) ;
}
With Visual Studio 2013, log2() was added. See C99 library support in Visual Studio 2013.
Note that:
log2(x) = log(x) * log(e)
where log(e) is a constant. math.h defines M_LOG2E to the value of log(e) if you define _USE_MATH_DEFINES before inclusion of math.h:
#define _USE_MATH_DEFINES // needed to have definition of M_LOG2E
#include <math.h>
static inline double log2(double n)
{
return log(n) * M_LOG2E;
}
Even though usual approach is to do log(n)/log(2), I would advise to use multiplication instead as division is always slower especially for floats and more so on mobile CPUs. For example, on modern Intel CPUs the difference in generated code in just one instruction mulsd vs divsd and according to Intel manuals we could expect the division to be 5-10 times slower. On mobile ARM cpus I would expect floating point division to be somewhere 10-100 slower than multiplication.
Also, in case if you have compilation issues with log2 for Android, seems like log2 is available in headers starting from android-18:
#include <android/api-level.h>
#if __ANDROID_API__ < 18
static inline double log2(double n)
{
return log(n) * M_LOG2E;
}
#endif

Resources