From ea2e7100bdc8bf889226afec97d8df12b299e75d Mon Sep 17 00:00:00 2001 From: Rob Tillaart Date: Sat, 27 Nov 2021 16:05:06 +0100 Subject: [PATCH] Develop (#4) * update unit tests * add example code (tests) * some refactor --- .../float16_test_all/float16_test_all.ino | 133 ++++++++++++++++++ .../float16_test_performance.ino | 61 +++++++- .../performance_0.1.4.txt | 19 +++ .../float16_test_special.ino | 74 ++++++++++ float16.cpp | 8 +- test/unit_test_001.cpp | 23 ++- 6 files changed, 311 insertions(+), 7 deletions(-) create mode 100644 examples/float16_test_all/float16_test_all.ino create mode 100644 examples/float16_test_performance/performance_0.1.4.txt create mode 100644 examples/float16_test_special/float16_test_special.ino diff --git a/examples/float16_test_all/float16_test_all.ino b/examples/float16_test_all/float16_test_all.ino new file mode 100644 index 0000000..db2f9c3 --- /dev/null +++ b/examples/float16_test_all/float16_test_all.ino @@ -0,0 +1,133 @@ +// +// FILE: float16_test_all.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// PURPOSE: test float16 +// DATE: 2021-11-27 +// URL: https://github.com/RobTillaart/float16 +// + +// test all values except the NAN +// test_1 takes ~ 2 minutes on UNO @ 115200baud + +// https://github.com/RobTillaart/float16/issues/2 + + +#include "float16.h" + +float16 f16; + +uint32_t start, stop; +uint32_t errors = 0; +float prev; + + +void setup() +{ + while (!Serial); + Serial.begin(115200); + Serial.println(__FILE__); + Serial.print("FLOAT16_LIB_VERSION: "); + Serial.println(FLOAT16_LIB_VERSION); + Serial.println("\nStart "); + + f16.setDecimals(6); + + test_1(); + test_2(); +} + + +void loop() +{ +} + + +void test_2() +{ + start = millis(); + for (uint32_t x = 0x0001; x < 0x7C01; x++) + { + if (x % 16 == 0) Serial.println(); + f16.setBinary(x); + float16 f17 = f16.toDouble(); + Serial.print(x, HEX); + Serial.print("\t"); + Serial.print(f17.toDouble() - f16.toDouble(), 5); + Serial.println(); + } + stop = millis(); + Serial.println(); + Serial.print(" TIME: "); + Serial.println(stop - start); +} + + +void test_1() +{ + // POSITIVE NUMBERS + prev = 0; + errors = 0; + start = millis(); + for (uint32_t x = 0x0000; x < 0x7C01; x++) + { + if (x % 16 == 0) Serial.println(); + f16.setBinary(x); + Serial.print(x, HEX); + Serial.print('\t'); + float current = f16.toDouble(); + Serial.print(current, 8); + if (prev > current) + { + Serial.print("\t\tERROR"); + errors++; + } + prev = current; + Serial.println(); + } + stop = millis(); + Serial.println(); + Serial.print(" TIME: "); + Serial.println(stop - start); + Serial.print("ERRORS: "); + Serial.println(errors); + Serial.println(); + Serial.println(); + + + // NEGATIVE NUMBERS + prev = 0; + errors = 0; + start = millis(); + for (uint32_t x = 0x8000; x < 0xFC01; x++) + { + if (x % 16 == 0) Serial.println(); + f16.setBinary(x); + Serial.print(x, HEX); + Serial.print('\t'); + float current = f16.toDouble(); + Serial.print(current, 8); + if (prev < current) + { + Serial.print("\t\tERROR"); + errors++; + } + prev = current; + Serial.println(); + } + stop = millis(); + Serial.println(); + Serial.print(" TIME: "); + Serial.println(stop - start); + Serial.print("ERRORS: "); + Serial.println(errors); + Serial.println(); + Serial.println(); + + + Serial.println("\ndone"); +} + + + +// -- END OF FILE -- diff --git a/examples/float16_test_performance/float16_test_performance.ino b/examples/float16_test_performance/float16_test_performance.ino index dc937cd..116353f 100644 --- a/examples/float16_test_performance/float16_test_performance.ino +++ b/examples/float16_test_performance/float16_test_performance.ino @@ -13,7 +13,7 @@ uint32_t start, stop; volatile float f; - +volatile bool b; void setup() { @@ -22,10 +22,11 @@ void setup() Serial.println(__FILE__); Serial.print("FLOAT16_LIB_VERSION: "); Serial.println(FLOAT16_LIB_VERSION); - Serial.println("\nStart "); + Serial.println(); f = random(1000000) * 0.001; + // CONSTRUCTORS start = micros(); float16 f16(f); stop = micros(); @@ -33,12 +34,68 @@ void setup() Serial.println(stop - start); delay(10); + float16 f17(f + 1); + start = micros(); + f16 = f17; + stop = micros(); + Serial.print("a = b: \t"); + Serial.println(stop - start); + delay(10); + + // CONVERSION start = micros(); f = f16.toDouble(); stop = micros(); Serial.print("toDouble(): \t"); Serial.println(stop - start); delay(10); + Serial.println(); + + + // COMPARE + f17 = f16.toDouble() + 1; + + start = micros(); + b = f16 == f17; + stop = micros(); + Serial.print("compare == : \t"); + Serial.println(stop - start); + delay(10); + + start = micros(); + b = f16 != f17; + stop = micros(); + Serial.print("compare != : \t"); + Serial.println(stop - start); + delay(10); + + start = micros(); + b = f16 < f17; + stop = micros(); + Serial.print("compare < : \t"); + Serial.println(stop - start); + delay(10); + + start = micros(); + b = f16 <= f17; + stop = micros(); + Serial.print("compare <= : \t"); + Serial.println(stop - start); + delay(10); + + start = micros(); + b = f16 >= f17; + stop = micros(); + Serial.print("compare >= : \t"); + Serial.println(stop - start); + delay(10); + + start = micros(); + b = f16 > f17; + stop = micros(); + Serial.print("compare > : \t"); + Serial.println(stop - start); + delay(10); Serial.println("\ndone"); } diff --git a/examples/float16_test_performance/performance_0.1.4.txt b/examples/float16_test_performance/performance_0.1.4.txt new file mode 100644 index 0000000..67ab7be --- /dev/null +++ b/examples/float16_test_performance/performance_0.1.4.txt @@ -0,0 +1,19 @@ +// +// test: UNO +// IDE: 1.8.13 +// + +FLOAT16_LIB_VERSION: 0.1.4 + +Constructor: 24 +a = b: 4 +toDouble(): 396 + +compare == : 4 +compare != : 4 +compare < : 784 +compare <= : 784 +compare >= : 784 +compare > : 780 + +done diff --git a/examples/float16_test_special/float16_test_special.ino b/examples/float16_test_special/float16_test_special.ino new file mode 100644 index 0000000..f768fe4 --- /dev/null +++ b/examples/float16_test_special/float16_test_special.ino @@ -0,0 +1,74 @@ +// +// FILE: float16_test_special.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// PURPOSE: test float16 +// DATE: 2021-11-26 +// URL: https://github.com/RobTillaart/float16 +// + +// test special values ... +// https://github.com/RobTillaart/float16/issues/2 + + +#include "float16.h" + +uint16_t value[32] = +{ + 0xFC00, 0xF400, 0xEC00, 0xE400, 0xDC00, 0xD400, 0xCC00, 0xC400, + 0xBC00, 0xB400, 0xAC00, 0xA400, 0x9C00, 0x9400, 0x8C00, 0x8400, + 0x0400, 0x0C00, 0x1400, 0x1C00, 0x2400, 0x2C00, 0x3400, 0x3C00, + 0x4400, 0x4C00, 0x5400, 0x5C00, 0x6400, 0x6C00, 0x7400, 0x7C00 +}; + +float16 f16; + + +void setup() +{ + while (!Serial); + Serial.begin(115200); + Serial.println(__FILE__); + Serial.print("FLOAT16_LIB_VERSION: "); + Serial.println(FLOAT16_LIB_VERSION); + Serial.println("\nStart "); + + f16.setDecimals(6); + + for (int i = 0; i < 32; i++) + { + f16.setBinary(value[i]); + Serial.print(value[i], HEX); + Serial.print("\t"); + Serial.print(f16); + Serial.print("\t"); + Serial.print(f16.toDouble(), 6); + Serial.print("\t"); + Serial.println(); + } + + Serial.println(); + Serial.println(); + + for (uint32_t x = 1; x < 65535; x *= 4) + { + f16 = x; + Serial.print(f16.getBinary(), HEX); + Serial.print("\t"); + Serial.print(f16); + Serial.print("\t"); + Serial.print(f16.toDouble(), 6); + Serial.print("\t"); + Serial.println(); + } + + Serial.println("\ndone"); +} + + +void loop() +{ +} + + +// -- END OF FILE -- diff --git a/float16.cpp b/float16.cpp index a20f777..cf65e98 100644 --- a/float16.cpp +++ b/float16.cpp @@ -154,7 +154,7 @@ float float16::f16tof32(uint16_t n) const #ifdef DEBUG Serial.println("ZERO"); #endif - return sgn?-0:0; + return sgn ? -0 : 0; } // NAN & INF if (exp == 0x001F) @@ -232,7 +232,8 @@ uint16_t float16::f32tof16(float f) const // rounding man++; man >>= 1; - return (sgn ? 0x8000 : 0x0000) | man; + if (sgn) return 0x8000 | man; + return man; } // normal @@ -243,7 +244,8 @@ uint16_t float16::f32tof16(float f) const // Serial.print("SGN: "); Serial.println(sgn, BIN); // Serial.print("EXP: "); Serial.println(exp, BIN); // Serial.print("MAN: "); Serial.println(man, BIN); - return (sgn ? 0x8000 : 0x0000) | exp | man; + if (sgn) return 0x8000 | exp | man; + return exp | man; } diff --git a/test/unit_test_001.cpp b/test/unit_test_001.cpp index 04cebd2..6eeaafa 100644 --- a/test/unit_test_001.cpp +++ b/test/unit_test_001.cpp @@ -69,7 +69,7 @@ unittest(test_constructor) assertEqualFloat(1.000, (-1 / minusOne.toDouble()), 1e-3); // TODO - // NAN constructor how to test + // NAN constructor how to test // float16 nanny(1.0/0.0); // assertNAN(nanny.toDouble()); @@ -82,6 +82,8 @@ unittest(test_constructor) float16 small(1e-30); assertEqualFloat(0.0, small.toDouble(), 1e-3); + float16 smaller(-1e-30); + assertEqualFloat(0.0, smaller.toDouble(), 1e-3); } @@ -92,13 +94,18 @@ unittest(test_compare_equal) float16 a(1); float16 b(1); float16 c(2); + float16 d(-1); assertTrue(a == a); assertTrue(a == b); assertFalse(a == c); + assertFalse(a == d); + + fprintf(stderr, "\n"); assertFalse(a != a); assertFalse(a != b); assertTrue(a != c); + assertTrue(a != d); } @@ -109,16 +116,24 @@ unittest(test_compare_1nequal) float16 a(1); float16 b(1); float16 c(2); + float16 d(-2); assertFalse(a < a); assertTrue(a <= b); assertFalse(a > b); assertTrue(a >= a); + fprintf(stderr, "\n"); assertTrue(a < c); assertTrue(a <= c); assertFalse(a > c); assertFalse(a >= c); + + fprintf(stderr, "\n"); + assertFalse(a < d); + assertFalse(a <= d); + assertTrue(a > d); + assertTrue(a >= d); } @@ -128,8 +143,10 @@ unittest(test_negation) float16 f16(123.456); float16 f17(-f16); + float16 f18 = -f16; assertEqualFloat(-123.456, f17.toDouble(), 1e-1); + assertEqualFloat(-123.456, f18.toDouble(), 1e-1); } @@ -151,6 +168,7 @@ unittest(test_printable) fprintf(stderr, "FLOAT16_LIB_VERSION: %s\n", (char*) FLOAT16_LIB_VERSION); float16 f16(123.456); + // test default value. assertEqual(4, f16.getDecimals()); for (int i = 0; i < 6; i++) { @@ -158,7 +176,8 @@ unittest(test_printable) assertEqual(i, f16.getDecimals()); } - // todo printable? how to test? + // TODO + // printable? how to test? }