123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455 |
- /*! ========================================================================
- ** Extended Template and Library Test Suite
- ** Fixed-Point Math Test
- **
- ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
- ** Copyright (c) 2007 Chris Moore
- **
- ** This package is free software; you can redistribute it and/or
- ** modify it under the terms of the GNU General Public License as
- ** published by the Free Software Foundation; either version 2 of
- ** the License, or (at your option) any later version.
- **
- ** This package is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- ** General Public License for more details.
- **
- ** === N O T E S ===========================================================
- **
- ** ========================================================================= */
- #define ETL_FIXED_BITS 12
- #include <ETL/fixed>
- #include <stdio.h>
- #include <ETL/clock>
- #ifndef PI
- # define PI (3.1415926535897932384626433832795029L)
- #endif
- #define ADD_SUB_TEST 20000000
- #define MUL_TEST 10000000
- #define DIV_TEST 1048573 // at 1048573, fixed point numbers wrap around to zero
- using namespace etl;
- template <class value_type>
- struct speed_test {
- double add_sub_test(void)
- {
- value_type a = 1;
- value_type b = 2;
- value_type c = 3;
- int i;
- etl::clock MyTimer;
- MyTimer.reset();
- for (i = 0; i < ADD_SUB_TEST; i++) {
- a += a;
- a -= b;
- a -= c;
- a += a;
- a += a;
- a -= b;
- a -= c;
- a += a;
- a += a;
- a -= b;
- a -= c;
- a += a;
- a += a;
- a -= b;
- a -= c;
- a += a;
- a += a;
- a -= b;
- a -= c;
- a += a;
- a += a;
- a -= b;
- a -= c;
- a += a;
- a += a;
- a -= b;
- a -= c;
- a += a;
- }
- fprintf(stderr, "[%1d]...", int(int(a) / 1e9) + 5); // so the compiler doesn't optimize everything out
- return MyTimer();
- }
- double mul_test(void)
- {
- value_type a, b, c, d;
- a = value_type(2.25);
- b = value_type(2);
- c = value_type(4.5);
- d = value_type(1);
- const value_type one_and_a_half(static_cast<value_type>(1.5));
- int i;
- etl::clock MyTimer;
- MyTimer.reset();
- for (i = 1; i < MUL_TEST; i++) {
- d *= a;
- d *= b;
- d *= c;
- d *= 3;
- d *= i;
- b *= c;
- b *= d;
- b *= d;
- b *= 3;
- c *= d;
- c *= one_and_a_half;
- c *= a;
- c *= b;
- c *= 3;
- a *= c;
- a *= b;
- a *= 3;
- d *= a;
- d *= b;
- d *= c;
- d *= 3;
- d *= i;
- b *= c;
- b *= d;
- b *= d;
- b *= 3;
- c *= d;
- c *= one_and_a_half;
- c *= a;
- c *= b;
- c *= 3;
- a *= c;
- a *= b;
- a *= 3;
- d *= a;
- d *= b;
- d *= c;
- d *= 3;
- d *= i;
- b *= c;
- b *= d;
- b *= d;
- b *= 3;
- c *= d;
- c *= one_and_a_half;
- c *= a;
- c *= b;
- c *= 3;
- a *= c;
- a *= b;
- a *= 3;
- d *= a;
- d *= b;
- d *= c;
- d *= 3;
- d *= i;
- b *= c;
- b *= d;
- b *= d;
- b *= 3;
- c *= d;
- c *= one_and_a_half;
- c *= a;
- c *= b;
- c *= 3;
- a *= c;
- a *= b;
- a *= 3;
- d *= a;
- d *= b;
- d *= c;
- d *= 3;
- d *= i;
- b *= c;
- b *= d;
- b *= d;
- b *= 3;
- c *= d;
- c *= one_and_a_half;
- c *= a;
- c *= b;
- c *= 3;
- a *= c;
- a *= b;
- a *= 3;
- d *= a;
- d *= b;
- d *= c;
- d *= 3;
- d *= i;
- b *= c;
- b *= d;
- b *= d;
- b *= 3;
- c *= d;
- c *= one_and_a_half;
- c *= a;
- c *= b;
- c *= 3;
- a *= c;
- a *= b;
- a *= 3;
- d *= a;
- d *= b;
- d *= c;
- d *= 3;
- d *= i;
- b *= c;
- b *= d;
- b *= d;
- b *= 3;
- c *= d;
- c *= one_and_a_half;
- c *= a;
- c *= b;
- c *= 3;
- a *= c;
- a *= b;
- a *= 3;
- }
- fprintf(stderr, "[%1d]...", int(int(a) / 1e9) + 5); // so the compiler doesn't optimize everything out
- return MyTimer();
- }
- double div_test(void)
- {
- value_type a(30);
- value_type b(40);
- value_type acc(0);
- int i, j;
- etl::clock MyTimer;
- MyTimer.reset();
- for (j = 0; j < 10; j++)
- for (i = 1; i < DIV_TEST; i++) {
- a = 3 + i;
- b = 40 + i;
- b /= a;
- a /= (i % 20) + 1;
- acc += a;
- a = 3 + i;
- b = 40 + i;
- b /= a;
- a /= (i % 20) + 1;
- acc += a;
- a = 3 + i;
- b = 40 + i;
- b /= a;
- a /= (i % 20) + 1;
- acc += a;
- a = 3 + i;
- b = 40 + i;
- b /= a;
- a /= (i % 20) + 1;
- acc += a;
- a = 3 + i;
- b = 40 + i;
- b /= a;
- a /= (i % 20) + 1;
- acc += a;
- a = 3 + i;
- b = 40 + i;
- b /= a;
- a /= (i % 20) + 1;
- acc += a;
- }
- fprintf(stderr, "[%1d]...", int(int(acc) / 1e9) + 5); // so the compiler doesn't optimize everything out
- return MyTimer();
- }
- };
- int basic_test(void)
- {
- int ret = 0;
- fixed a, b, c;
- double d;
- a = -1;
- a = std::abs(a);
- if (a != fixed(1)) {
- fprintf(stderr, "fixed: abs() failure on line %d in "__FILE__".\n", __LINE__);
- ret++;
- }
- d = (double)(fixed(2.5) * fixed(3.0f) / 7) - (2.5f * 3.0f / 7.0f);
- fprintf(stderr, "fixed: 2.5 * 2 / 7 --- Difference: %f\n", d);
- if (d < 0.0) {
- d = -d;
- }
- if (d > 0.0005) {
- fprintf(stderr, "fixed: Failed test on line %d in "__FILE__".\n", __LINE__);
- ret++;
- }
- a = 1043;
- d = 1043;
- a /= 27;
- d /= 27;
- a += 10.42;
- d += 10.42;
- a /= 6;
- d /= 6;
- a *= PI;
- d *= PI;
- d -= (double)a;
- fprintf(stderr, "fixed: ( 1043 / 27 + 10.42 ) / 6 * PI --- Difference: %f\n", d);
- if (d < 0.0) {
- d = -d;
- }
- #ifdef ROUND_TO_NEAREST_INTEGER
- if (d > 0.0005)
- #else
- if (d > 0.0025)
- #endif
- {
- fprintf(stderr, "fixed: Failed test on line %d in "__FILE__".\n", __LINE__);
- ret++;
- }
- return ret;
- }
- int char_test(void)
- {
- int ret = 0;
- fixed_base<unsigned char, 8> fix;
- double flt;
- if (sizeof(fix) != sizeof(unsigned char)) {
- ret++;
- fprintf(stderr, "fixed: Size of fixed_base<unsigned char,8> is wrong!\n");
- }
- flt = 1.0;
- fix = 1.0;
- fprintf(stderr, "fixed: value=%f, data=%d, shouldbe=%f, error=%f\n", (float)fix, fix.data(), flt, (float)fix - flt);
- flt *= 0.7;
- fix *= 0.7;
- fprintf(stderr, "fixed: value=%f, data=%d, shouldbe=%f, error=%f\n", (float)fix, fix.data(), flt, (float)fix - flt);
- flt *= 0.7;
- fix *= 0.7;
- fprintf(stderr, "fixed: value=%f, data=%d, shouldbe=%f, error=%f\n", (float)fix, fix.data(), flt, (float)fix - flt);
- flt *= 0.7;
- fix *= 0.7;
- fprintf(stderr, "fixed: value=%f, data=%d, shouldbe=%f, error=%f\n", (float)fix, fix.data(), flt, (float)fix - flt);
- flt *= 0.7;
- fix *= 0.7;
- fprintf(stderr, "fixed: value=%f, data=%d, shouldbe=%f, error=%f\n", (float)fix, fix.data(), flt, (float)fix - flt);
- flt *= 0.7;
- fix *= 0.7;
- fprintf(stderr, "fixed: value=%f, data=%d, shouldbe=%f, error=%f\n", (float)fix, fix.data(), flt, (float)fix - flt);
- // fix/=0.7;
- // fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
- flt += 0.3;
- fix += 0.3;
- fprintf(stderr, "fixed: value=%f, data=%d, shouldbe=%f, error=%f\n", (float)fix, fix.data(), flt, (float)fix - flt);
- flt *= 2;
- fix *= 2;
- fprintf(stderr, "fixed: value=%f, data=%d, shouldbe=%f, error=%f\n", (float)fix, fix.data(), flt, (float)fix - flt);
- return ret;
- }
- int main()
- {
- int error = 0;
- error += basic_test();
- error += char_test();
- speed_test<float> float_test;
- speed_test<int> int_test;
- speed_test<fixed> fixed_test;
- {
- double flt, fix, inte;
- fprintf(stderr, "\nAddition/subtraction test...\n");
- fprintf(stderr, " calculating float.....");
- flt = float_test.add_sub_test();
- fprintf(stderr, " float time: %f sec\n", flt);
- fprintf(stderr, " calculating fixed.....");
- fix = fixed_test.add_sub_test();
- fprintf(stderr, " fixed time: %f sec\n", fix);
- fprintf(stderr, " calculating integer...");
- inte = int_test.add_sub_test();
- fprintf(stderr, " integer time: %f sec\n", inte);
- if (flt > fix) {
- fprintf(stderr, "Fixed point wins by %f seconds! (%f%% faster)\n", flt - fix, flt / fix * 100.0f - 100.0f);
- } else {
- fprintf(stderr, "Floating point wins by %f seconds! (%f%% faster)\n", fix - flt, fix / flt * 100.0f - 100.0f);
- }
- }
- {
- double flt, fix, inte;
- fprintf(stderr, "\nProduct test...\n");
- fprintf(stderr, " calculating float.....");
- flt = float_test.mul_test();
- fprintf(stderr, " float time: %f sec\n", flt);
- fprintf(stderr, " calculating fixed.....");
- fix = fixed_test.mul_test();
- fprintf(stderr, " fixed time: %f sec\n", fix);
- fprintf(stderr, " calculating integer...");
- inte = int_test.mul_test();
- fprintf(stderr, " integer time: %f sec\n", inte);
- if (flt > fix) {
- fprintf(stderr, "Fixed point wins by %f seconds! (%f%% faster)\n", flt - fix, flt / fix * 100.0f - 100.0f);
- } else {
- fprintf(stderr, "Floating point wins by %f seconds! (%f%% faster)\n", fix - flt, fix / flt * 100.0f - 100.0f);
- }
- }
- {
- double flt, fix, inte;
- fprintf(stderr, "\nDivision test...\n");
- fprintf(stderr, " calculating float.....");
- flt = float_test.div_test();
- fprintf(stderr, " float time: %f sec\n", flt);
- fprintf(stderr, " calculating fixed.....");
- fix = fixed_test.div_test();
- fprintf(stderr, " fixed time: %f sec\n", fix);
- fprintf(stderr, " calculating integer...");
- inte = int_test.div_test();
- fprintf(stderr, " integer time: %f sec\n", inte);
- if (flt > fix) {
- fprintf(stderr, "Fixed point wins by %f seconds! (%f%% faster)\n", flt - fix, flt / fix * 100.0f - 100.0f);
- } else {
- fprintf(stderr, "Floating point wins by %f seconds! (%f%% faster)\n", fix - flt, fix / flt * 100.0f - 100.0f);
- }
- fprintf(stderr, "\n");
- }
- return error;
- }
|