stdlib: add a test for strtold

This commit is contained in:
Lephenixnoir 2021-05-21 22:48:45 +02:00
parent ec7626d789
commit f7be1f758f
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
4 changed files with 136 additions and 0 deletions

View File

@ -29,6 +29,7 @@ set(SOURCES
src/inttypes/sizes.c
# stdlib
src/stdlib/arith.c
src/stdlib/fpconv.c
src/stdlib/intconv.c
src/stdlib/sizes.c
# string

View File

@ -20,6 +20,7 @@ extern ft_test ft_stdlib_arith;
extern ft_test ft_stdlib_sizes;
extern ft_test ft_stdlib_llconv;
extern ft_test ft_stdlib_lconv;
extern ft_test ft_stdlib_fpconv;
/* string */
extern ft_test ft_string_memset;

View File

@ -1,5 +1,6 @@
#include <gint/display.h>
#include <gint/keyboard.h>
#include <gint/kprint.h>
#include <ft/widgets/gscreen.h>
#include <ft/widgets/fbrowser.h>
@ -36,6 +37,7 @@ ft_list headers_libc[] = {
&ft_stdlib_sizes,
&ft_stdlib_llconv,
&ft_stdlib_lconv,
&ft_stdlib_fpconv,
NULL,
}},
{ "<string.h>", (ft_test*[]){
@ -59,6 +61,8 @@ ft_list headers_posix[] = {
int main(void)
{
kprint_enable_fp();
// Initialize test results
for(int i = 0; headers_libc[i].name; i++)
ft_list_init(&headers_libc[i]);

130
src/stdlib/fpconv.c Normal file
View File

@ -0,0 +1,130 @@
#include <stdlib.h>
#include <float.h>
#include <errno.h>
#include <math.h>
#include <ft/test.h>
#include <ft/all-tests.h>
/* All these macros have free variables "func" and "format". */
/* Assert that converting (string) gives (result) with (errno == 0). This check
will skip the test if there is a relative error of 1e-12 or less. */
#define assert_conv(string, expected) { \
errno = 0; \
__auto_type _result = func(string, NULL); \
ft_assert(t, errno == 0); \
if(_result == expected) { \
ft_assert(t, 1); \
ft_log(t, string " = " #expected "\n"); \
} \
else if(fabs(1e12 * (_result - expected)) < expected) { \
ft_skip(t, 1); \
ft_log(t, string " = %" format "f [skipped from " #expected \
", difference is %" format "e]\n", \
_result, expected - _result); \
} \
else { \
ft_assert(t, 0); \
ft_log(t, string " = %" format "f [wanted " #expected \
", difference is %" format "e]\n", \
_result, expected - _result); \
} \
}
/* Assert that converting (string) gives (errno == error). */
#define assert_errno(string, error) { \
errno = 0; \
ft_log(t, string " should be errno " #error "\n"); \
func(string, NULL); \
ft_assert(t, errno == error); \
}
/* Assert that converting (string) sets (endptr == string + distance). */
#define assert_end(string, distance) { \
char const *_str = string; \
char *_end; \
ft_log(t, string " should read " #distance "\n"); \
func(_str, &_end); \
ft_assert(t, _end - _str == distance); \
}
static void _ft_stdlib_fpconv(ft_test *t)
{
#define func strtold
#define format "L"
ft_log(t, "--- strtold ---\n");
ft_log(t, "\nSimple test cases:\n");
assert_conv("73", 73.0);
assert_conv("-12", -12.0);
assert_conv("12.125", 12.125);
ft_log(t, "\nOmitting digits:\n");
assert_conv("73.", 73.0);
assert_conv("+0.375", 0.375);
assert_conv(".625", 0.625);
ft_log(t, "\nBasic exponents:\n");
assert_conv("0.3e2", 30.0);
assert_conv("-0.777e+3", -777.0);
assert_conv("6250E-5", 0.0625);
ft_log(t, "\nEnd pointer for valid cases:\n");
assert_end("73b", 2);
assert_end("-73.f", 4);
assert_end("-73.5.2", 5);
assert_end("73.e2f", 5);
assert_end(" 73E+2+1", 7);
assert_end(" -1e5", 6);
assert_end("", 0);
ft_log(t, "\nInfinity and NaN:\n");
assert_conv("inf", __builtin_infl());
assert_conv("-inFiNiTY", -__builtin_infl());
ft_assert(t, isnan(strtold("+NAN", NULL)));
ft_assert(t, isnan(strtold("-nan", NULL)));
ft_assert(t, isnan(strtold("NaN(57)", NULL)));
ft_log(t, "\nOverflows (with denormalization):\n");
assert_errno("-1e309", ERANGE);
assert_errno("-1e308", 0);
assert_errno("-1e-308", 0);
assert_errno("-1e-324", 0);
/* Implementation is not required to detect underflows */
assert_errno("-1e-325", 0);
assert_errno("0", 0);
assert_errno("1e-325", 0);
assert_errno("1e-324", 0);
assert_errno("1e-308", 0);
assert_errno("1e308", 0);
assert_errno("1e309", ERANGE);
assert_errno("+inf", 0);
assert_errno("-infinity", 0);
ft_log(t, "\nEnd pointer for invalid cases:\n");
assert_end(" b", 0);
assert_end("73e++", 2);
assert_end(" -E5", 0);
assert_end(" +1ex", 3);
ft_log(t, "\nLarge numbers of decimal digits:\n");
assert_conv("18446744073709551616", 1.8446744073709552e+19);
assert_conv("1844674407370955.2e4", 1.8446744073709552e+19);
ft_log(t, "\nHexadecimal notation:\n");
assert_conv("0xa47b.3f85p12", 0xa47b.3f85p12);
// ft_log(t, "\nConversion to double:\n");
// ft_log(t, "\nConversion to float:\n");
}
ft_test ft_stdlib_fpconv = {
.name = "Floating-point conversion",
.function = _ft_stdlib_fpconv,
};