Floating Point Mathematics

From NutWiki

Jump to: navigation, search

Contents

Test Environments

Hardware Comments Nut/OS
4.8.7
Ethernut 1.3 H OK
Binaries
Compiler: AVR-GCC 4.3.2
Ethernut 2.1 B OK
Binaries
Compiler: AVR-GCC 4.3.2
Ethernut 3.0 E NO

Overview

This example demonstrates Floating Point Math using Nut/OS and the math lib corresponding to your platform (avr-libc for AVR, newlib for ARM).

For this example it is also assumed that you have a working knowledge of how Nut/OS handles floatint point values. If you did not read the Floating Point Input and Ouput example yet, that should be your first stop before continuing with this part.

Before you begin, please enable floating point support for your project. In order to do this, open the configurator, load the appropriate config file for your project and then activate the following option:

Image:Floatactivation.png

Now rebuild Nut/OS to apply the changed configuration.

Source Code

#include <dev/board.h>
#include <stdio.h>
#include <io.h>
#include <math.h>
 
int main(void)
{
    unsigned long baud = 115200;
    double val = 0.0;
    double val2 = 0.0;
 
    NutRegisterDevice(&DEV_UART, 0, 0);
    freopen(DEV_UART_NAME, "w", stdout);
    freopen(DEV_UART_NAME, "r", stdin);
    _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
 
    puts("\nNut/OS Floating Point Math Demo");
 
    puts("Please enter a first floating point value:");
    scanf("%lf", &val);
 
    puts("Please enter a second floating point value:");
    scanf("%lf", &val2);
 
    printf("We will now perform some advanced math operations using the numbers %lf and %lf:\n\n", val, val2);
    printf("Sine: sin(%lf) -> %lf\n", val, sin(val));
    printf("Tangens: tan(%lf) -> %lf\n", val, tan(val));
    printf("Arc Tangens: atan(%lf) -> %lf\n\n", val, atan(val));
    printf("Exponential: exp(%lf) -> %lf\n", val, exp(val));
    printf("Power: pow(%lf, %lf) -> %lf\n", val, val2, pow(val, val2));
    printf("Square Root: sqrt(%lf) -> %lf\n", val, sqrt(val));
    printf("Logarithm: log(%lf) -> %lf\n", val, log(val));
    printf("Base 10 Logarithm: log10(%lf) -> %lf\n\n", val, log10(val));
    printf("Floating Point Absolute: fabs(%lf) -> %lf\n", val, fabs(val));
    printf("Floor: floor(%lf) -> %lf\n", val, floor(val));
#if defined(__arm__)
    /* This only exists in newlib so we'll not use it when compiling vor AVR */
    printf("Remainder: remainder(%lf%, %lf) -> %lf\n", val, val2, remainder(val, val2));
#endif
    printf("Round: round(%lf) -> %lf\n", val, round(val));
    printf("Truncate to Integer: trunc(%lf) -> %lf\n", val, trunc(val));
 
    for (;;);
    return 0;
}

Details

unsigned long baud = 115200;
double val = 0.0;
double val2 = 0.0;
 
NutRegisterDevice(&DEV_UART, 0, 0);
freopen(DEV_UART_NAME, "w", stdout);
freopen(DEV_UART_NAME, "r", stdin);
_ioctl(_fileno(stdout), UART_SETSPEED, &baud);
 
puts("\nNut/OS Floating Point Math Demo");

Up to this point, this example looks exactly the same as the first example on floating point values. The only difference is the name of the application so far.

puts("Please enter a first floating point value:");
scanf("%lf", &val);
 
puts("Please enter a second floating point value:");
scanf("%lf", &val2);

Since we want to do calculations with floating point values, we first ask for 2 of them. Most of the functions demonstrated hereafter will only need 1 but some need 2.

That's it, we're ready to calculate some things.

printf("Sine: sin(%lf) -> %lf\n", val, sin(val));

Since the example uses the same line over and over again for each function, it is pretty easy to understand how it works:

First the normal, english name of the mathematical operation is printed, then the function name with the values inserted. After that, we print the return value of the function.

Since the functions themselves are pretty much self-explaining, you should be easily able to understand what each function does. If you still get stuck, take a look at the corresponding documentation for your platform:

AVR: avr-libc

ARM & AVR32: newlib

#if defined(__arm__)
    /* This only exists in newlib so we'll not use it when compiling vor AVR */
    printf("Remainder: remainder(%lf%, %lf) -> %lf\n", val, val2, remainder(val, val2));
#endif

By the way: The remainder function only exists in newlib. If you try to use it on AVR, the compiler will throw an error.

A homebrew remainder function for the AVR could look something like this:

float remainder(float num1, float num2) {
    while(num1 >= num2) {
        num1 -= num2;
    }
    return num1;
}

Keep in mind that floating point math is very slow on AVR and ARM CPUs. Use it only when absolutely needed.

Output

Nut/OS Floating Point Math Demo
Please enter a first floating point value:
Please enter a second floating point value:
We will now perform some advanced math operations using the numbers 4.600000 and
 3.100000:
 
Sine: sin(4.600000) -> -0.993691
Tangens: tan(4.600000) -> 8.860168
Arc Tangens: atan(4.600000) -> 1.356736
 
Exponential: exp(4.600000) -> 99.484299
Power: pow(4.600000, 3.100000) -> 113.383360
Square Root: sqrt(4.600000) -> 2.144761
Logarithm: log(4.600000) -> 1.526056
Base 10 Logarithm: log10(4.600000) -> 0.662758
 
Floating Point Absolute: fabs(4.600000) -> 4.600000
Floor: floor(4.600000) -> 4.000000
Round: round(4.600000) -> 5.000000
Truncate to Integer: trunc(4.600000) -> 4.000000

See also

Personal tools