giving parameters into math function - c

If I call in C, math function `"trunc" in math library is define as:
extern double trunc _PARAMS((double));
and in my main file call it:
int i = (int)trunc(2.5);
It works fine, no problems. But if I try to pass double passively, like:
double d = 2.5;
int i = (int)trunc(d);
It won't work?!? In my microprocessor STM32F4 IDE it goes in debugger mode into:
Infinite_Loop:
b Infinite_Loop
and it stuck there. I also change double and try float, int, unit8_t,... no one isn't working.
Also other math functions will work fine as I call them like this:
i = sin(1);
i = cos(1);
But, it will crashed the same, if called like this:
int a = 1;
i = sin(a);
i = cos(a);
I am running this code on microprocessor STM32F4 Discovery,IDE is Eclipse Ac6.

If you refer the man page for trunc() you should note that, it says
Link with -lm
So, make sure that you are linking with -lm.
Secondly, when synopsis say double trunc(double x);, there is no point in trying it out with other data types.
If you want to try with other data types then you should look for these variants:
float truncf(float x);
long double truncl(long double x);
Test code:
#include<stdio.h>
#include<math.h>
int main(void)
{
// using trunc function which return
// Truncated value of the input
double d = 2.7;
printf(" Truncated value is %d \n", (int)trunc(d));
return 0;
}
This generated an output:
Truncated value is 2
And it was compiled with gcc version 5.3.0
When I compile the same code gcc version 7.2.0 without -lm option,
I get following warning:
undefined reference to `trunc'
error: ld returned 1 exit status

Related

How does one link with the SoftFloat library?

I am designing hardware to do floating point arithmetic in compliance with the IEEE-754 standard. SoftFloat is a library (written by John Hauser - UC Berkeley) which is a reference model (in C++) of IEEE-754 floating point behavior. It implements functions to do all the floating point computations specified by the standard. I want to use SoftFloat to generate test cases for my hardware implementation. The link for the author's page is http://www.jhauser.us/arithmetic/SoftFloat.html.
I downloaded the zip file from the link on that page (http://www.jhauser.us/arithmetic/SoftFloat-3e.zip), unzipped it, and used to provided Makefile to build it. I am running under bash on Windows10. At the end of the build process, I end up with an archive "softfloat.a".
One of the functions which SoftFloat implements is fused floating-point multiply-add. Per the documentation, this can be invoked by calling the function f32_mulAdd, and a template for it is in the provided header file softfloat.h.
In my main code (sf.cc), I include that header, define arguments to that function using types defined in the same header, and build the code with:
gcc -o sf -I. sf.cc softfloat.a
This gives the following error:
/tmp/ccALxpC8.o: In function `main':
sf.cc:(.text+0x4f): undefined reference to `f32_mulAdd(float32_t, float32_t, float32_t)'
collect2: error: ld returned 1 exit status
f32_mulAdd IS defined in softfloat.h (I checked), and the archive file softfloat.a DOES contain f32_mulAdd.o (checked with ar -t softfloat.a) and f32_mulAdd.c in the SoftFloat source code DOES define the function (as "float32_t f32_mulAdd( float32_t a, float32_t b, float32_t c)") and my call to that function is consistent with the definition, so I don't understand why I get this message. If anyone has used SoftFloat please chime in.
The source code in which I call the SoftFloat function f32_mulAdd is as follows (I want to get this to compile/link cleanly first, then I will add statements to initialize the variables multiplier, multiplicand and addend to specific values):
#include "platform.h"
#include "internals.h"
#include "softfloat.h"
#include "softfloat_types.h"
int float_rounding_mode = 0;
int main()
{
uint8_t rounding_mode;
uint8_t exceptions;
uint32_t multiplier, multiplicand, addend, result;
float32_t f_multiplier, f_multiplicand, f_addend, f_result;
f_multiplier.v = multiplier;
f_multiplicand.v = multiplicand;
f_addend.v = addend;
softfloat_roundingMode = rounding_mode;
softfloat_exceptionFlags = 0;
softfloat_detectTininess = softfloat_tininess_beforeRounding;
f_result = f32_mulAdd(f_multiplier, f_multiplicand, f_addend);
result = f_result.v;
exceptions = softfloat_exceptionFlags & 0x1f;
return 0;
}
The key is to change the header file inclusion to:
extern "C" {
#include "softfloat.h"
}
Also, softfloat.h was the only header file required.
There is no need to use a softfloat library.
The GCC compiler already have a floating point implementation.
For-eg - You can just do a A + B on float types and you should get the result.
You can also control the rounding mode using std::fesetround() and get the exceptions by using.

Passing variables to fmax

So I have the following code:
#include <math.h>
int main (void) {
float max = fmax (1.0,2.0);
return 0;
}
Which compiles and runs fine, but if instead of passing 1.0 and 2.0 to the function I pass a, b with those values:
#include <math.h>
int main (void) {
float a = 1.0; float b = 2.0;
float max = fmax (a,b);
return 0;
}
I get the following error:
undefined reference to `fmax'
What is the diffrence? What I'm doing wrong?
I'm using this command to compile:
c99 fmax_test.c
In the first case fmax probably gets optimised away at compile time. In the second case it does not and you then get a link error. Without knowing what compiler you are using it's hard to give a specific remedy, but if it's gcc then you may need to add -lm, e.g.
c99 -Wall fmax_test.c -lm
Note also that fmax is for doubles - you should be using fmaxf for floats.
compile with -lm
i'm using gcc. maybe not OK with your compiler.
try this:
c99 fmax_test.c -lm

gcc 4.2.1 Linking issue: Undefined Symbols for Architecture x86_64

Yes, it's been asked before, but every answer I come up with on SO and elsewhere has to do with compiling C++ code in gcc instead of g++, or a issue of some kind with standard libraries. So far, nothing actually lining up right for me here.
So, I'm going through a basic crash course on C, and trying to compile an example used to illustrate linking to files that you create, rather than from the standard libraries. Here's the code:
math_functions.h
int sum (int x, int y);
float average (float x, float y, float z);
math_functions.c
int sum (int x, int y)
{
return (x + y);
}
float average (float x, float y, float z)
{
return (x + y + z) / 3;
}
and finally
test3.c
#include <stdio.h>
#include "math_functions.h"
main ()
{
int theSum = sum (8, 12);
float theAverage = average (16.9, 7.86, 3.4);
printf ("the sum is: %i ", theSum);
printf ("and the average is: %f \n", theAverage);
printf ("average casted to an int is: %i \n", (int)theAverage);
}
These are all in the same folder. When I open the Terminal, cd to the folder and run:
gcc test3.c -o test3
I get:
Undefined symbols for architecture x86_64:
"_average", referenced from:
_main in ccmf69Tt.o
"_sum", referenced from:
_main in ccxms0fF.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
This happens if I use gcc or g++ (which I shouldn't have to do, since this should all be C), and everything I've compiled before now works fine with the
#include <stdio.h>
at the top.
I can get it to compile and run fine by removing the
#include "math_functions.h"
from the test3.c file, putting the contents of math_functions.h before main() and the contents of math_functions.c after main(). And yes, that is copy and paste, so its definitely the same code.
So yeah, I can get my code to work, but it defeats the purpose of the exercise, in that I don't end up being able to use that code in any other C files without copying it and pasting it into the one file...
So I'm wondering, is there a way I can fix this, so I can include more that just the standard C, C++ and Objective-C libraries?
This happens through box the Terminal, manually typing out the gcc command, and through CodeRunner, which has the standard commands all tucked away into a button, so I can't stuff it.
I'm running Mountain Lion 10.8.4 (12E55) on a 2012 Mac Mini, using the Command Line Tools from Xcode 4.6.2 (installed them just a few hours ago, I haven't actually done much then standard use of the Mini till now)
I have all the same software installed on my MacBook Air, but haven't tested it to see if the same goes down yet.
Any pointers? If someone else has had this and worked it out somewhere here on SO, please point me at it, I have been looking for round an hour but like I said before, all the solutions that I've found so far end up being when there is C++ code or something weird with the standard libraries.
You just need to compile the maths_function. The linker is complaining it does not have the definitions contained in that module.
gcc test3.c math_functions.c -o test3

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

pow doesn't accept the second parameter to be a variable on gcc

pow doesn't accept the second parameter to be a variable on gcc
The following code works fine on VC++10
// file test.cc
#include "stdafx.h"
#include <stdio.h>
#include <math.h>
int main(void)
{
double x = 10;
int y = 20;
printf("%f\n", pow(x, y));
return 0;
}
But the following code doesn't not work on gcc:
// test.c
#include <stdio.h>
#include <math.h>
int main(void)
{
double x = 10;
int y = 20;
printf("%f\n", pow(x, y)); // error here, says no such function, however when pass the second argument in `pow` for the code runs by gcc, It works fine!
return 0;
}
You're mistaken. It has nothing to do with the second parameter.
In POSIXish systems pow() is in libm, whereas in win32ish systems it is part of the standard C library. That means instead of this:
$ gcc program.c
/tmp/ccTw1gCA.o: In function `main':
program.c:(.text+0x30): undefined reference to `pow'
you need to do this:
$ gcc program.c -lm
The reason it may appear that the second parameter works as a constant but not as a variable is that gcc has a built-in implementation of pow(). If the second parameter is a constant it might be using that where if it's a variable it's falling back on the glibc pow() function. See:
http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Other-Builtins.html#Other-Builtins
If you pass -fno-builtin to gcc you should see consistent behavior--in this case error messages no matter what you pass to pow(). As others have mentioned whenever you use anything out of math.h you need to link with -lm.

Resources