Skip to content

Commit 2922e2e

Browse files
committed
AP_HAL: add test for snprintf and thus ftoa_engine behavior
Ensures subnormals aren't formatted grossly wrong nor cause hangs. Reveals two additional bugs: * The requested number of digits is not always produced. * The precision isn't enough to distinguish every float. Outputs from the (nominally) original assembly implementation running on a real AVR (avr-gcc 7.3.0) are included. That implementation exhibits none of these flaws so it's likely they have been introduced during the C port.
1 parent ebc9be6 commit 2922e2e

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

libraries/AP_HAL/tests/test_vsnprintf.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,53 @@ TEST(vsnprintf_Test, Basic)
6262
}
6363
}
6464

65+
static const char* do_subnormal_format(uint32_t val_hex) {
66+
// format float represented as a hex number long enough to see all digits
67+
68+
// note that something else is wrong here and all the strings should be the
69+
// same width of 99 chars (or whatever the format string means)! when that
70+
// is fixed, update the test and add an assert here.
71+
72+
static char buf[256];
73+
74+
float val = *(float*)&val_hex;
75+
76+
hal.util->snprintf(buf, ARRAY_SIZE(buf), "%.99f", val);
77+
78+
return buf;
79+
}
80+
81+
TEST(vsnprintf_Test, SubnormalFormat)
82+
{
83+
// arbitrary small number (1e-31)
84+
// EXPECT_STREQ("0.000000000000000000000000000000099999998000000000000000000000000000000000000000000000000000000000000",
85+
EXPECT_STREQ("0.0000000000000000000000000000001000000",
86+
do_subnormal_format(0x0C01CEB3));
87+
88+
// smallest normal (1.1754944e-38)
89+
// EXPECT_STREQ("0.000000000000000000000000000000000000011754944000000000000000000000000000000000000000000000000000000",
90+
EXPECT_STREQ("0.00000000000000000000000000000000000001175494",
91+
do_subnormal_format(0x00800000));
92+
93+
// largest subnormal (1.1754942e-38)
94+
// EXPECT_STREQ("0.000000000000000000000000000000000000011754942000000000000000000000000000000000000000000000000000000",
95+
EXPECT_STREQ("0.00000000000000000000000000000000000001175494", // !! same as above
96+
do_subnormal_format(0x007FFFFF));
97+
98+
// moderate subnormal (1.1478e-41)
99+
// EXPECT_STREQ("0.000000000000000000000000000000000000000011478036000000000000000000000000000000000000000000000000000",
100+
EXPECT_STREQ("0.00000000000000000000000000000000000000001147804",
101+
do_subnormal_format(0x00001FFF));
102+
103+
// smallest subnormal (1e-45)
104+
// EXPECT_STREQ("0.000000000000000000000000000000000000000000001401290000000000000000000000000000000000000000000000000",
105+
EXPECT_STREQ("0.00000000000000000000000000000000000000000000140130",
106+
do_subnormal_format(0x00000001));
107+
108+
// zero
109+
EXPECT_STREQ("0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
110+
do_subnormal_format(0x00000000));
111+
}
112+
113+
65114
AP_GTEST_MAIN()

0 commit comments

Comments
 (0)