forked from Lephenixnoir/FxLibcTest
stdlib: add a test for strtold
This commit is contained in:
parent
ec7626d789
commit
f7be1f758f
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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,
|
||||
};
|
Loading…
Reference in New Issue