Convert string to float - c

I'm programming on a AVR XMEGA microcontroller, using AtmelStudio.
I'm having trouble converting a string to a float. The string is called token2 and has the value "8.604165"
I've already tried a couple of functions:
float lon = atof(token2); printf("lon=%f", lon); returns lon=?
float lon = strtod(token2, NULL); printf("lon=%f", lon); returns lon=?
float lon = strtof(token2, NULL); printf("lon=%f", lon); gives an error undefined reference to strtof, even including <stdlib.h>
Am I doing something wrong?

By default, AVR-libc tries to save space in the binary by not linking in floating-point-related stuff. For functions like atof that's easy because if you don't call them then the linker won't include them. For printf, though, the linker can't tell whether you're planning on using it for floating-point numbers.
Instead, AVR-libc has multiple libraries which define printf. The printf in the default library has full functionality except that it doesn't support floating-point numbers. If you want to save space in your binary and you're not using the more advanced features of printf (namely format flags), you can link with printf_min to replace that with a teenier version. And if you want to print floating-point numbers, you need the full powered version defined in printf_flt.
This page describes the proper linker options to select those alternative versions. In short, add -Wl,-u,vfprintf -lprintf_flt -lm to your linker options.

Ok, so this is something specific of microcontrollers.
Similar to what #Sneftel said, I just had to add the libraries libprintf_flt.a and libm.a in AtmelStudio.

Related

why is abs() and fabs() defined in two different headers in C

The standard library function abs() is declared in stdlib.h, while fabs() is in math.h.
Why are they reside in different headers?
math.h first appears in 7th Research Unix. It is hard to tell how it got there. For example, [1] claims that bits of C library were merged from "PWB/Unix" which included troff and C compiler pcc, but I cannot prove it.
Another interesting piece of information is library manual from V7 Unix:
intro.3:
(3) These functions, together with those of section 2 and those marked (3S),
constitute library libc, which is automatically loaded by the C compiler
cc(1) and the Fortran compiler f77(1). The link editor ld(1) searches
this library under the `-lc' option. Declarations for some of these
functions may be obtained from include files indicated on the appropri-
ate pages.
<...>
(3M) These functions constitute the math library, libm. They are automati-
cally loaded as needed by the Fortran compiler f77(1). The link editor
searches this library under the `-lm' option. Declarations for these
functions may be obtained from the include file <math.h>.
If you look into V7 commands makefiles, only few C programs are linked with -lm flag. So my conclusion is speculative:
libm.a (and math.h) was primarily needed for FORTRAN programs mostly, so it was separated into library to reduce binary footprint (note that it was linked statically).
Not many machines had floating point support. For example, you would need to buy an optional FPP for PDP-11 [2], there is also libfpsim simulation library in Unix to mitigate that, so floating point can be hardly used in early C programs.
1. A History of UNIX before Berkeley: UNIX Evolution: 1975-1984
2. PDP-11 architecture
Most operators like + - / * are also math operators yet these are also readily available. When programming you use so much math, that developers have started to differentiate between math that is needed for everyday stuff and math that is more specialized that you only use some of the time. Abs is one of those functions that are just used to often. Like with pointer arithmetic when you just want to know the difference to calculate the size of a memory block. But you are not interested in knowing which is higher in memory and which is lower.
So to sum up: abs is used often because it calculates the difference of two integers. The difference between two pointers for instance is also an integer. And so it is in stdlib.h. fabs how ever is not something you will need much unless you are doing math specific stuff. Thus it is in math.h.

snprintf not working float

I'm programming on a STM32F437. I'm using SafeRTOS. The compiler is GCC.
In one task I'm using snprintf() to prepare a string with values.
The problem is that the snprintf() fails to handle floating point numbers. It just ends the resulting string (with '\0') when it reaches any %f or %g in the formatting string.
But, and this is strange. The snprintf() in the task works with no problem if I add a dummy call to snprintf() in main() before starting the RTOS.
The dummy call:
char dummy[20];
snprintf(dummy, sizeof(dummy), "%g", 3.14159);
I found a similar solution here
But no answer why it works.
Any ideas what is going on?
The printf library in some small implementations does not include floating point support. Perhaps the dummy call is somehow causing a more complete (and larger) library to be used?
The dummy call may be optimized away by compiler. As you are printing only constant. Try to look in disassembly or try to compile it with -O0 flag set.
Float support in general tends to be large, especially on platforms without hardware FPU available where all computing operation have to be done by calls to the library. So many standard libraries just omit it unless you explicitly specify that you want it enabled.

AIX equivalent of ieee754.h

I wrote some C code that serializes certain values into a file that is subsequently deserialized (using custom code) in Java on another machine.
Among values I'm serializing are 64-bit double precision floating point real numbers. When I wrote the code, it was going to be compiled and run only on Linux with a gcc available to compile it. I used ieee754.h to get access to all parts of the value, as per IEEE 754 standard, and write those parts to a file. On Java end, I would simply use Double.longBitsToDouble(long) to reassemble the value.
The problem is that I've been asked to make the code able to compile and run on AIX 5.3, using xlc 10.
Is there any equivalent of ieee754.h on AIX?
Short of endianness issues, IEEE754 is a fixed format. There's no need for a system header to tell you what it looks like. Just do something like:
uint64_t rep;
double x;
memcpy(&rep, &x, sizeof rep);
You might want to include some code for conditionally byte-order-swapping the result if you're on a platform where you have to do that, but as far as I know, AIX is not going to be one of those.

How to enable linking floating point library in TurboC?

I'm newbie in C language... Just want to ask how to enable linking floating point library in TurboC?
From the comp.os.msdos.programmer FAQ:
"Floating point formats not linked" is
a Borland run-time error (Borland C or
C++, Turbo C or C++). Borland's
compilers try to be smart and not link
in the floating- point (f-p) library
unless you need it. Alas, they all get
the decision wrong. One common case is
where you don't call any f-p
functions, but you have %f or other
f-p formats in scanf() or printf()
calls. The cure is to call an f-p
function, or at least force one to be
present in the link.
To do that, define this function
somewhere in a source file but don't
call it:
static void forcefloat(float *p)
{
float f = *p;
forcefloat(&f);
}
It doesn't have to be in the module
with the main program, as long as it's
in a module that will be included in
the link.

Floating point library for embedded application

I'm developing program for Cortex-M3. It doesn't have floating point coprocessor. Standard C library can emulate floating point operations, but I don't use it due to its size.
Is there any good and free c library, which can emulate floating point arithmetics, targeted on ARM processors?
Currently, when I use floating point operators I have such linkage errors:
undefined reference to `__adddf3'
undefined reference to `__subdf3'
undefined reference to `__divdf3'
undefined reference to `__extendsfdf2'
undefined reference to `__muldf3'
So probably such library should implement them.
Would you not be better off (performance and size wise) using fixed point? For simple arithmetic, this is trivial to implement either directly or with a function interface. If you could bare to use C++, using operator overloading could make the use of fixed almost seamless (at no runtime overhead compared to a C function interface).
If you have more complex requirements (trig, roots etc), a good fixed-point library is presented in this Dr. Dobb's Article.
If you want to perform your floating arithmetic using built in operators, then you'll need to provide the library routines that the compiler expects, so you'd end up with something that's likely to be as large as the library that came with the compiler.
You likely have the source code to the compiler's floating support routines, so if you want to look at them to see if you can improve them that's probably your best chance. If you don't think that'll work for whatever reason, you should talk to your compiler vendor about the requirements the compiler expects of the floating support routines and the best way to replace the vendor's library.
If you want to circumvent the compiler's requirements, you'll probably need to avoid using the built in operators and perform you arithmetic using explicit function calls. I have no experience with 3rd party floating point library routines, so unfortunately I can't point you to an possible good alternatives.
Those should be defined in the runtime support library for your compiler. Those names look like the floating-point functions from libgcc (the support library for gcc), which is pretty small. You should be able to pull in those functions by setting your link flags appropriately.
Perhaps newlib would be useful here? It can be a pain to set up the toolchain, but I've had success in reducing embedded flash usage versus gcc and its standard library.
Any static linker worth its salt is going to remove unused calls. This is particularly true for embedded compilers.
gcc has all of those functions, there is gcc build voodoo (multilib, thumb, thumb2, and soft float) you can use to have that automatically have it show up. I have years ago given up and just go grab the files from the gcc sources trim them to a clean source and just build them into my projects. Years ago looking at a commercial compiler or two then looking at newlib and gcc, at least at the time they were all using pretty much the same math library. I want to say it was from Sun.
Assuming your using gcc try compiling with the -static-libgcc flag and checking the final binary size. I don't know if the linker will optimize out the unused calls but I think it will.
All the below message represent some arithmetic operation
undefined reference to __adddf3'
undefined reference to__subdf3'
undefined reference to __divdf3'
undefined reference to__extendsfdf2'
undefined reference to `__muldf3'
So while linking compiler will give linking error if you are doing some arthamatic operation in two different data type. For example:
Float x;
float y;
y = x * 0.45;
So if you compile this code while linking it will give you below message
undefined reference to `__muldf3'
To resolve this specify the "0.45" explicitly to float
y = x * 0.45F;
Most of the time this type of linking error comes when you are using c++ compiler to compile c file.

Resources