2012-08-04 19:12:36 -03:00
|
|
|
/****************************************************************************
|
|
|
|
*
|
2012-08-13 16:09:08 -03:00
|
|
|
* Copyright (C) 2012 PX4 Development Team. All rights reserved.
|
|
|
|
* Author: @author Lorenz Meier <lm@inf.ethz.ch>
|
2012-08-04 19:12:36 -03:00
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in
|
|
|
|
* the documentation and/or other materials provided with the
|
|
|
|
* distribution.
|
2012-08-13 16:09:08 -03:00
|
|
|
* 3. Neither the name PX4 nor the names of its contributors may be
|
2012-08-04 19:12:36 -03:00
|
|
|
* used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
|
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
|
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2012-08-13 16:09:08 -03:00
|
|
|
/**
|
|
|
|
* @file tests_float.c
|
|
|
|
* Floating point tests
|
|
|
|
*/
|
2012-08-04 19:12:36 -03:00
|
|
|
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <debug.h>
|
|
|
|
#include <arch/board/board.h>
|
|
|
|
#include <arch/board/drv_led.h>
|
|
|
|
#include "tests.h"
|
|
|
|
#include <math.h>
|
|
|
|
#include <float.h>
|
|
|
|
|
|
|
|
typedef union {
|
|
|
|
float f;
|
|
|
|
double d;
|
|
|
|
uint8_t b[8];
|
|
|
|
} test_float_double_t;
|
|
|
|
|
|
|
|
int test_float(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
printf("\n--- SINGLE PRECISION TESTS ---\n");
|
2012-08-13 17:10:03 -03:00
|
|
|
printf("The single precision test involves calls to fabsf(),\nif test fails check this function as well.\n\n");
|
2012-08-04 19:12:36 -03:00
|
|
|
|
|
|
|
float f1 = 1.55f;
|
|
|
|
|
|
|
|
float sinf_zero = sinf(0.0f);
|
|
|
|
float sinf_one = sinf(1.0f);
|
|
|
|
float sqrt_two = sqrt(2.0f);
|
|
|
|
|
|
|
|
if (sinf_zero == 0.0f) {
|
|
|
|
printf("\t success: sinf(0.0f) == 0.0f\n");
|
|
|
|
|
|
|
|
} else {
|
2012-08-26 09:51:52 -03:00
|
|
|
printf("\t FAIL: sinf(0.0f) != 0.0f, result: %8.4f\n", (double)sinf_zero);
|
2012-08-04 19:12:36 -03:00
|
|
|
ret = -4;
|
|
|
|
}
|
|
|
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
2012-08-13 17:10:03 -03:00
|
|
|
if (fabsf((sinf_one - 0.841470956802368164062500000000f)) < FLT_EPSILON) {
|
2012-08-04 19:12:36 -03:00
|
|
|
printf("\t success: sinf(1.0f) == 0.84147f\n");
|
|
|
|
|
|
|
|
} else {
|
2012-08-26 09:51:52 -03:00
|
|
|
printf("\t FAIL: sinf(1.0f) != 0.84147f, result: %8.4f\n", (double)sinf_one);
|
2012-08-04 19:12:36 -03:00
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
float asinf_one = asinf(1.0f);
|
|
|
|
|
2012-08-13 17:10:03 -03:00
|
|
|
if (fabsf((asinf_one - 1.570796251296997070312500000000f)) < FLT_EPSILON * 1.5f) {
|
2012-08-04 19:12:36 -03:00
|
|
|
printf("\t success: asinf(1.0f) == 1.57079f\n");
|
|
|
|
|
|
|
|
} else {
|
|
|
|
printf("\t FAIL: asinf(1.0f) != 1.57079f, result: %f\n", asinf_one);
|
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
float cosf_one = cosf(1.0f);
|
|
|
|
|
2012-08-13 17:10:03 -03:00
|
|
|
if (fabsf((cosf_one - 0.540302336215972900390625000000f)) < FLT_EPSILON) {
|
2012-08-04 19:12:36 -03:00
|
|
|
printf("\t success: cosf(1.0f) == 0.54030f\n");
|
|
|
|
|
|
|
|
} else {
|
2012-08-26 09:51:52 -03:00
|
|
|
printf("\t FAIL: cosf(1.0f) != 0.54030f, result: %8.4f\n", (double)cosf_one);
|
2012-08-04 19:12:36 -03:00
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
|
|
|
|
float acosf_one = acosf(1.0f);
|
|
|
|
|
2012-08-13 17:10:03 -03:00
|
|
|
if (fabsf((acosf_one - 0.000000000000000000000000000000f)) < FLT_EPSILON) {
|
2012-08-04 19:12:36 -03:00
|
|
|
printf("\t success: acosf(1.0f) == 0.0f\n");
|
|
|
|
|
|
|
|
} else {
|
2012-08-26 09:51:52 -03:00
|
|
|
printf("\t FAIL: acosf(1.0f) != 0.0f, result: %8.4f\n", (double)acosf_one);
|
2012-08-04 19:12:36 -03:00
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
|
|
|
|
float sinf_zero_one = sinf(0.1f);
|
|
|
|
|
|
|
|
if (fabs(sinf_zero_one - 0.0998334166f) < FLT_EPSILON) {
|
|
|
|
printf("\t success: sinf(0.1f) == 0.09983f\n");
|
|
|
|
|
|
|
|
} else {
|
2012-08-26 09:51:52 -03:00
|
|
|
printf("\t FAIL: sinf(0.1f) != 0.09983f, result: %8.4f\n", (double)sinf_zero_one);
|
2012-08-04 19:12:36 -03:00
|
|
|
ret = -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sqrt_two == 1.41421356f) {
|
|
|
|
printf("\t success: sqrt(2.0f) == 1.41421f\n");
|
|
|
|
|
|
|
|
} else {
|
2012-08-26 09:51:52 -03:00
|
|
|
printf("\t FAIL: sqrt(2.0f) != 1.41421f, result: %8.4f\n", (double)sinf_zero_one);
|
2012-08-04 19:12:36 -03:00
|
|
|
ret = -3;
|
|
|
|
}
|
|
|
|
|
|
|
|
float atan2f_ones = atan2(1.0f, 1.0f);
|
|
|
|
|
2012-08-13 16:09:08 -03:00
|
|
|
if (fabsf(atan2f_ones - 0.785398163397448278999490867136f) < FLT_EPSILON) {
|
2012-08-04 19:12:36 -03:00
|
|
|
printf("\t success: atan2f(1.0f, 1.0f) == 0.78539f\n");
|
|
|
|
|
|
|
|
} else {
|
2012-08-26 09:51:52 -03:00
|
|
|
printf("\t FAIL: atan2f(1.0f, 1.0f) != 0.78539f, result: %8.4f\n", (double)atan2f_ones);
|
2012-08-04 19:12:36 -03:00
|
|
|
ret = -4;
|
|
|
|
}
|
|
|
|
|
2012-08-13 16:09:08 -03:00
|
|
|
char sbuf[30];
|
|
|
|
sprintf(sbuf, "%8.4f", 0.553415f);
|
|
|
|
|
|
|
|
if (sbuf[0] == ' ' && sbuf[1] == ' ' && sbuf[2] == '0' &&
|
|
|
|
sbuf[3] == '.' && sbuf[4] == '5' && sbuf[5] == '5'
|
|
|
|
&& sbuf[6] == '3' && sbuf[7] == '4' && sbuf[8] == '\0') {
|
2012-08-26 09:51:52 -03:00
|
|
|
printf("\t success: printf(\"%%8.4f\", 0.553415f) == %8.4f\n", (double)0.553415f);
|
2012-08-13 16:09:08 -03:00
|
|
|
} else {
|
2012-08-13 17:10:03 -03:00
|
|
|
printf("\t FAIL: printf(\"%%8.4f\", 0.553415f) != \" 0.5534\", result: %s\n", sbuf);
|
2012-08-13 16:09:08 -03:00
|
|
|
ret = -5;
|
|
|
|
}
|
2012-08-04 19:12:36 -03:00
|
|
|
|
2012-08-26 09:51:52 -03:00
|
|
|
sprintf(sbuf, "%8.4f", -0.553415f);
|
|
|
|
|
|
|
|
if (sbuf[0] == ' ' && sbuf[1] == '-' && sbuf[2] == '0' &&
|
|
|
|
sbuf[3] == '.' && sbuf[4] == '5' && sbuf[5] == '5'
|
|
|
|
&& sbuf[6] == '3' && sbuf[7] == '4' && sbuf[8] == '\0') {
|
|
|
|
printf("\t success: printf(\"%%8.4f\", -0.553415f) == %8.4f\n", (double)-0.553415f);
|
|
|
|
} else {
|
|
|
|
printf("\t FAIL: printf(\"%%8.4f\", -0.553415f) != \" -0.5534\", result: %s\n", sbuf);
|
|
|
|
ret = -6;
|
|
|
|
}
|
|
|
|
|
2012-08-04 19:12:36 -03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("\n--- DOUBLE PRECISION TESTS ---\n");
|
|
|
|
|
|
|
|
double d1 = 1.0111;
|
|
|
|
double d2 = 2.0;
|
|
|
|
|
|
|
|
double d1d2 = d1 * d2;
|
|
|
|
|
|
|
|
if (d1d2 == 2.022200000000000219557705349871) {
|
|
|
|
printf("\t success: 1.0111 * 2.0 == 2.0222\n");
|
|
|
|
|
|
|
|
} else {
|
2012-08-26 09:51:52 -03:00
|
|
|
printf("\t FAIL: 1.0111 * 2.0 != 2.0222, result: %8.4f\n", d1d2);
|
|
|
|
ret = -7;
|
2012-08-04 19:12:36 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
// Assign value of f1 to d1
|
|
|
|
d1 = f1;
|
|
|
|
|
|
|
|
if (f1 == (float)d1) {
|
|
|
|
printf("\t success: (float) 1.55f == 1.55 (double)\n");
|
|
|
|
|
|
|
|
} else {
|
2012-08-26 09:51:52 -03:00
|
|
|
printf("\t FAIL: (float) 1.55f != 1.55 (double), result: %8.4f\n", f1);
|
|
|
|
ret = -8;
|
2012-08-04 19:12:36 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
|
|
|
|
double sin_zero = sin(0.0);
|
|
|
|
double sin_one = sin(1.0);
|
|
|
|
double atan2_ones = atan2(1.0, 1.0);
|
|
|
|
|
|
|
|
if (sin_zero == 0.0) {
|
|
|
|
printf("\t success: sin(0.0) == 0.0\n");
|
|
|
|
|
|
|
|
} else {
|
2012-08-26 09:51:52 -03:00
|
|
|
printf("\t FAIL: sin(0.0) != 0.0, result: %8.4f\n", sin_zero);
|
|
|
|
ret = -9;
|
2012-08-04 19:12:36 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (sin_one == 0.841470984807896504875657228695) {
|
|
|
|
printf("\t success: sin(1.0) == 0.84147098480\n");
|
|
|
|
|
|
|
|
} else {
|
2012-08-26 09:51:52 -03:00
|
|
|
printf("\t FAIL: sin(1.0) != 1.0, result: %8.4f\n", sin_one);
|
|
|
|
ret = -10;
|
2012-08-04 19:12:36 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (atan2_ones != 0.785398) {
|
|
|
|
printf("\t success: atan2(1.0, 1.0) == 0.785398\n");
|
|
|
|
|
|
|
|
} else {
|
2012-08-26 09:51:52 -03:00
|
|
|
printf("\t FAIL: atan2(1.0, 1.0) != 0.785398, result: %8.4f\n", atan2_ones);
|
|
|
|
ret = -11;
|
2012-08-04 19:12:36 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
printf("\t testing pow() with magic value\n");
|
2012-08-13 17:10:03 -03:00
|
|
|
printf("\t (44330.0 * (1.0 - pow((96286LL / 101325.0), 0.190295)));\n");
|
2012-08-04 19:12:36 -03:00
|
|
|
fflush(stdout);
|
|
|
|
usleep(20000);
|
|
|
|
double powres = (44330.0 * (1.0 - pow((96286LL / 101325.0), 0.190295)));
|
2012-08-13 16:09:08 -03:00
|
|
|
printf("\t success: result: %8.4f\n", (double)powres);
|
2012-08-04 19:12:36 -03:00
|
|
|
|
2012-08-13 17:10:03 -03:00
|
|
|
sprintf(sbuf, "%8.4f", 0.553415);
|
|
|
|
|
|
|
|
if (sbuf[0] == ' ' && sbuf[1] == ' ' && sbuf[2] == '0' &&
|
|
|
|
sbuf[3] == '.' && sbuf[4] == '5' && sbuf[5] == '5'
|
|
|
|
&& sbuf[6] == '3' && sbuf[7] == '4' && sbuf[8] == '\0') {
|
|
|
|
printf("\t success: printf(\"%%8.4f\", 0.553415) == %8.4f\n", 0.553415);
|
|
|
|
} else {
|
|
|
|
printf("\t FAIL: printf(\"%%8.4f\", 0.553415) != \" 0.5534\", result: %s\n", sbuf);
|
2012-08-26 09:51:52 -03:00
|
|
|
ret = -12;
|
|
|
|
}
|
|
|
|
|
|
|
|
sprintf(sbuf, "%8.4f", -0.553415);
|
|
|
|
|
|
|
|
if (sbuf[0] == ' ' && sbuf[1] == '-' && sbuf[2] == '0' &&
|
|
|
|
sbuf[3] == '.' && sbuf[4] == '5' && sbuf[5] == '5'
|
|
|
|
&& sbuf[6] == '3' && sbuf[7] == '4' && sbuf[8] == '\0') {
|
|
|
|
printf("\t success: printf(\"%%8.4f\", -0.553415) == %8.4f\n", -0.553415);
|
|
|
|
} else {
|
|
|
|
printf("\t FAIL: printf(\"%%8.4f\", -0.553415) != \" -0.5534\", result: %s\n", sbuf);
|
|
|
|
ret = -13;
|
2012-08-13 17:10:03 -03:00
|
|
|
}
|
|
|
|
|
2012-08-04 19:12:36 -03:00
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
printf("\n SUCCESS: All float and double tests passed.\n");
|
|
|
|
|
|
|
|
} else {
|
|
|
|
printf("\n FAIL: One or more tests failed.\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|