Disabled external gits

This commit is contained in:
2022-04-07 18:46:57 +02:00
parent 88cb3426ad
commit 15e7120d6d
5316 changed files with 4563444 additions and 6 deletions

View File

@ -0,0 +1,16 @@
Makefile
Makefile.in
config.h.in
config.h
config.log
config.status
configure
libtool
stamp-h
aclocal.m4
OpenEXR.pc
autom4te.cache
ltmain.sh
stamp-h.in
depcomp
.deps

View File

@ -0,0 +1,16 @@
# yue.nicholas@gmail.com
ADD_EXECUTABLE ( HalfTest
main.cpp
testArithmetic.cpp
testBitPatterns.cpp
testClassification.cpp
testError.cpp
testFunction.cpp
testLimits.cpp
testSize.cpp
)
TARGET_LINK_LIBRARIES ( HalfTest Half )
ADD_TEST ( TestHalf HalfTest )

View File

@ -0,0 +1,19 @@
## Process this file with automake to produce Makefile.in
check_PROGRAMS = HalfTest
HalfTest_SOURCES = main.cpp testArithmetic.cpp testArithmetic.h \
testBitPatterns.cpp testBitPatterns.h \
testClassification.cpp testClassification.h \
testError.cpp testError.h testFunction.cpp \
testFunction.h testLimits.cpp testLimits.h testSize.cpp \
testSize.h
INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Half -I$(top_srcdir)/config
LDADD = -L$(top_builddir)/Half -lHalf
TESTS = HalfTest
EXTRA_DIST = CMakeLists.txt

View File

@ -0,0 +1,32 @@
#include <testSize.h>
#include <testArithmetic.h>
#include <testError.h>
#include <testBitPatterns.h>
#include <testClassification.h>
#include <testLimits.h>
#include <testFunction.h>
#include <iostream>
#include <string.h>
#define TEST(x) if (argc < 2 || !strcmp (argv[1], #x)) x();
int
main (int argc, char *argv[])
{
std::cout << "\ntesting type half:\n\n" << std::flush;
TEST (testSize);
TEST (testArithmetic);
TEST (testNormalizedConversionError);
TEST (testDenormalizedConversionError);
TEST (testRoundingError);
TEST (testBitPatterns);
TEST (testClassification);
TEST (testLimits);
TEST (testFunction);
return 0;
}

View File

@ -0,0 +1,55 @@
#include <testArithmetic.h>
#include "half.h"
#include <iostream>
#include <assert.h>
using namespace std;
void
testArithmetic ()
{
cout << "basic arithmetic operations:\n";
float f1 (1);
float f2 (2);
half h1 (3);
half h2 (4);
cout << "f1 = " << f1 << ", "
"f2 = " << f2 << ", "
"h1 = " << h1 << ", "
"h2 = " << h2 << endl;
h1 = f1 + f2;
assert (h1 == 3);
cout << "h1 = f1 + f2: " << h1 << endl;
h2 += f1;
assert (h2 == 5);
cout << "h2 += f1: " << h2 << endl;
h2 = h1 + h2;
assert (h2 == 8);
cout << "h2 = h1 + h2: " << h2 << endl;
h2 += h1;
assert (h2 == 11);
cout << "h2 += h1: " << h2 << endl;
h1 = h2;
assert (h1 == 11);
cout << "h1 = h2: " << h1 << endl;
h2 = -h1;
assert (h2 == -11);
cout << "h2 = -h1: " << h2 << endl;
cout << "ok\n\n" << flush;
}

View File

@ -0,0 +1,3 @@
void testArithmetic ();

View File

@ -0,0 +1,484 @@
#include <testBitPatterns.h>
#include "half.h"
#include <float.h>
#include <iostream>
#include <string.h>
#include <assert.h>
using namespace std;
namespace {
bool
equalBitPatterns (const char *b1, const char *b2)
{
//
// Returns true if the characters in zero-terminated string b1
// are the same as the charaters in string b2, except for places
// where b1 or b2 contains an 'X'. For example:
//
// equalBitPatterns ("100", "100") returns true
// equalBitPatterns ("100", "101") returns false
// equalBitPatterns ("10X", "101") returns true
// equalBitPatterns ("10X", "100") returns true
//
while (*b1 && *b2)
{
if (*b1 != *b2 && *b1 != 'X' && *b2 != 'X')
return false;
++b1;
++b2;
}
return !(*b1 || *b2);
}
void
testBits (float f, const char bh[19], const char bg[35])
{
half h (f);
float g (h);
cout.width (15);
cout.precision (8);
cout << f << " ";
printBits (cout, f);
cout << " ";
printBits (cout, h);
cout << '\n';
cout.width (15);
cout << g << " ";
printBits (cout, g);
cout << "\n\n";
if (bh || bg)
{
char ch[19], cg[35];
printBits (ch, h);
printBits (cg, g);
if (!equalBitPatterns (ch, bh))
{
cout << "error: expected " << bh << ", got " << ch << endl;
assert (false);
}
if (!equalBitPatterns (cg, bg))
{
cout << "error: expected " << bg << ", got " << cg << endl;
assert (false);
}
}
}
float
floatPosInfinity ()
{
half::uif x;
x.i = 0x7f800000;
return x.f;
}
float
floatNegInfinity ()
{
half::uif x;
x.i = 0xff800000;
return x.f;
}
float
floatPosQNan1 ()
{
half::uif x;
x.i = 0x7fffffff;
return x.f;
}
float
floatNegQNan1 ()
{
half::uif x;
x.i = 0xffffffff;
return x.f;
}
float
floatPosQNan2 ()
{
half::uif x;
x.i = 0x7fd55555;
return x.f;
}
float
floatNegQNan2 ()
{
half::uif x;
x.i = 0xffd55555;
return x.f;
}
} // namespace
void
testBitPatterns()
{
cout << "specific bit patterns\n\n";
//
// Numbers close to 1.0
//
testBits (1.0f,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0f + HALF_EPSILON,
"0 01111 0000000001",
"0 01111111 00000000010000000000000");
testBits (1.0f + HALF_EPSILON * 0.5f,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0f+ HALF_EPSILON * 0.4999f,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0f + HALF_EPSILON * 0.5001f,
"0 01111 0000000001",
"0 01111111 00000000010000000000000");
testBits (1.0f + HALF_EPSILON + HALF_EPSILON,
"0 01111 0000000010",
"0 01111111 00000000100000000000000");
testBits (1.0f + HALF_EPSILON + HALF_EPSILON * 0.5f,
"0 01111 0000000010",
"0 01111111 00000000100000000000000");
testBits (1.0f + HALF_EPSILON + HALF_EPSILON * 0.4999f,
"0 01111 0000000001",
"0 01111111 00000000010000000000000");
testBits (1.0f + HALF_EPSILON + HALF_EPSILON * 0.5001f,
"0 01111 0000000010",
"0 01111111 00000000100000000000000");
testBits (1.0f - HALF_EPSILON * 0.5f,
"0 01110 1111111111",
"0 01111110 11111111110000000000000");
testBits (1.0f - HALF_EPSILON * 0.5f * 0.5f,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0f - HALF_EPSILON * 0.5f * 0.4999f,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0f - HALF_EPSILON * 0.5f * 0.5001f,
"0 01110 1111111111",
"0 01111110 11111111110000000000000");
//
// Numbers close to HALF_MIN
//
testBits (HALF_MIN,
"0 00000 0000000001",
"0 01100111 00000000000000000000000");
testBits (HALF_MIN + HALF_MIN,
"0 00000 0000000010",
"0 01101000 00000000000000000000000");
testBits (HALF_MIN + HALF_MIN * 0.5f,
"0 00000 0000000010",
"0 01101000 00000000000000000000000");
testBits (HALF_MIN + HALF_MIN * 0.4999f,
"0 00000 0000000001",
"0 01100111 00000000000000000000000");
testBits (HALF_MIN + HALF_MIN * 0.5001f,
"0 00000 0000000010",
"0 01101000 00000000000000000000000");
testBits (HALF_MIN - HALF_MIN,
"0 00000 0000000000",
"0 00000000 00000000000000000000000");
testBits (HALF_MIN - HALF_MIN * 0.5f,
"0 00000 0000000000",
"0 00000000 00000000000000000000000");
testBits (HALF_MIN - HALF_MIN * 0.4999f,
"0 00000 0000000001",
"0 01100111 00000000000000000000000");
testBits (HALF_MIN - HALF_MIN * 0.5001f,
"0 00000 0000000000",
"0 00000000 00000000000000000000000");
//
// Numbers close to HALF_NRM_MIN
//
testBits (HALF_NRM_MIN,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN + HALF_MIN,
"0 00001 0000000001",
"0 01110001 00000000010000000000000");
testBits (HALF_NRM_MIN + HALF_MIN * 0.5f,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN + HALF_MIN * 0.4999f,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN + HALF_MIN * 0.5001f,
"0 00001 0000000001",
"0 01110001 00000000010000000000000");
testBits (HALF_NRM_MIN - HALF_MIN,
"0 00000 1111111111",
"0 01110000 11111111100000000000000");
testBits (HALF_NRM_MIN - HALF_MIN * 0.5f,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN - HALF_MIN * 0.49995f,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN - HALF_MIN * 0.50005f,
"0 00000 1111111111",
"0 01110000 11111111100000000000000");
//
// Small positive integers and simple decimal fractions
//
testBits (2,
"0 10000 0000000000",
"0 10000000 00000000000000000000000");
testBits (3,
"0 10000 1000000000",
"0 10000000 10000000000000000000000");
testBits (10,
"0 10010 0100000000",
"0 10000010 01000000000000000000000");
testBits (0.1f,
"0 01011 1001100110",
"0 01111011 10011001100000000000000");
testBits (0.2f,
"0 01100 1001100110",
"0 01111100 10011001100000000000000");
testBits (0.3f,
"0 01101 0011001101",
"0 01111101 00110011010000000000000");
//
// Numbers close to HALF_MAX
//
testBits (HALF_MAX,
"0 11110 1111111111",
"0 10001110 11111111110000000000000");
testBits ((1 << HALF_MAX_EXP) * 1.0,
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits ((1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.25f),
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits ((1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.25005f),
"0 11110 1111111111",
"0 10001110 11111111110000000000000");
testBits ((1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.24995f),
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
//
// Large positive numbers, positive infinity and NANs
//
testBits (HALF_MAX * HALF_MAX,
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits (FLT_MAX,
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits (floatPosInfinity(),
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits (floatPosQNan1(),
"0 11111 1111111111", // nan
"0 11111111 11111111110000000000000"); // nan
testBits (floatPosQNan2(),
"0 11111 1010101010", // nan
"0 11111111 10101010100000000000000"); // nan
//
// Numbers close to -1.0
//
testBits (-1.0,
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0f + HALF_EPSILON),
"1 01111 0000000001",
"1 01111111 00000000010000000000000");
testBits (-(1.0f + HALF_EPSILON * 0.5f),
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0f + HALF_EPSILON * 0.4999f),
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0f + HALF_EPSILON * 0.5001f),
"1 01111 0000000001",
"1 01111111 00000000010000000000000");
testBits (-(1.0f + HALF_EPSILON + HALF_EPSILON),
"1 01111 0000000010",
"1 01111111 00000000100000000000000");
testBits (-(1.0f + HALF_EPSILON + HALF_EPSILON * 0.5f),
"1 01111 0000000010",
"1 01111111 00000000100000000000000");
testBits (-(1.0f + HALF_EPSILON + HALF_EPSILON * 0.4999f),
"1 01111 0000000001",
"1 01111111 00000000010000000000000");
testBits (-(1.0f + HALF_EPSILON + HALF_EPSILON * 0.5001f),
"1 01111 0000000010",
"1 01111111 00000000100000000000000");
testBits (-(1.0f - HALF_EPSILON * 0.5f),
"1 01110 1111111111",
"1 01111110 11111111110000000000000");
testBits (-(1.0f - HALF_EPSILON * 0.5f * 0.5f),
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0f - HALF_EPSILON * 0.5f * 0.4999f),
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0f - HALF_EPSILON * 0.5f * 0.5001f),
"1 01110 1111111111",
"1 01111110 11111111110000000000000");
//
// Numbers close to -HALF_MIN
//
testBits (-HALF_MIN,
"1 00000 0000000001",
"1 01100111 00000000000000000000000");
testBits (-(HALF_MIN + HALF_MIN),
"1 00000 0000000010",
"1 01101000 00000000000000000000000");
testBits (-(HALF_MIN + HALF_MIN * 0.5f),
"1 00000 0000000010",
"1 01101000 00000000000000000000000");
testBits (-(HALF_MIN + HALF_MIN * 0.4999f),
"1 00000 0000000001",
"1 01100111 00000000000000000000000");
testBits (-(HALF_MIN + HALF_MIN * 0.5001f),
"1 00000 0000000010",
"1 01101000 00000000000000000000000");
testBits (-(HALF_MIN - HALF_MIN),
"X 00000 0000000000",
"X 00000000 00000000000000000000000");
testBits (-(HALF_MIN - HALF_MIN * 0.5f),
"1 00000 0000000000",
"1 00000000 00000000000000000000000");
testBits (-(HALF_MIN - HALF_MIN * 0.4999f),
"1 00000 0000000001",
"1 01100111 00000000000000000000000");
testBits (-(HALF_MIN - HALF_MIN * 0.5001f),
"1 00000 0000000000",
"1 00000000 00000000000000000000000");
//
// Numbers close to -HALF_NRM_MIN
//
testBits (-HALF_NRM_MIN,
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN + HALF_MIN),
"1 00001 0000000001",
"1 01110001 00000000010000000000000");
testBits (-(HALF_NRM_MIN + HALF_MIN * 0.5f),
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN + HALF_MIN * 0.4999f),
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN + HALF_MIN * 0.5001f),
"1 00001 0000000001",
"1 01110001 00000000010000000000000");
testBits (-(HALF_NRM_MIN - HALF_MIN),
"1 00000 1111111111",
"1 01110000 11111111100000000000000");
testBits (-(HALF_NRM_MIN - HALF_MIN * 0.5f),
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN - HALF_MIN * 0.49995f),
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN - HALF_MIN * 0.50005f),
"1 00000 1111111111",
"1 01110000 11111111100000000000000");
//
// Small negative integers and simple decimal fractions
//
testBits (-2,
"1 10000 0000000000",
"1 10000000 00000000000000000000000");
testBits (-3,
"1 10000 1000000000",
"1 10000000 10000000000000000000000");
testBits (-10,
"1 10010 0100000000",
"1 10000010 01000000000000000000000");
testBits (-0.1f,
"1 01011 1001100110",
"1 01111011 10011001100000000000000");
testBits (-0.2f,
"1 01100 1001100110",
"1 01111100 10011001100000000000000");
testBits (-0.3f,
"1 01101 0011001101",
"1 01111101 00110011010000000000000");
//
// Numbers close to -HALF_MAX
//
testBits (-HALF_MAX,
"1 11110 1111111111",
"1 10001110 11111111110000000000000");
testBits (-(1 << HALF_MAX_EXP) * 1.0f,
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (-(1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.25f),
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (-(1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.25005f),
"1 11110 1111111111",
"1 10001110 11111111110000000000000");
testBits (-(1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.24995f),
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
//
// Large negative numbers, negative infinity and NANs
//
testBits (-HALF_MAX * HALF_MAX,
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (-FLT_MAX,
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (floatNegInfinity(),
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (floatNegQNan1(),
"1 11111 1111111111", // nan
"1 11111111 11111111110000000000000"); // nan
testBits (floatNegQNan2(),
"1 11111 1010101010", // nan
"1 11111111 10101010100000000000000"); // nan
cout << "ok\n\n" << flush;
}

View File

@ -0,0 +1,3 @@
void testBitPatterns ();

View File

@ -0,0 +1,170 @@
#include <testClassification.h>
#include "half.h"
#include <iostream>
#include <assert.h>
using namespace std;
namespace {
void
testClass (half h,
bool finite,
bool normalized,
bool denormalized,
bool zero,
bool nan,
bool infinity,
bool negative)
{
cout.width (15);
cout.precision (8);
cout << h << " ";
printBits (cout, h);
cout << " ";
if (h.isFinite())
cout << "finite ";
if (h.isNormalized())
cout << "normalized ";
if (h.isDenormalized())
cout << "denormalized ";
if (h.isZero())
cout << "zero ";
if (h.isNan())
cout << "nan ";
if (h.isInfinity())
cout << "infinity ";
if (h.isNegative())
cout << "negative ";
cout << endl;
assert (h.isFinite() == finite);
assert (h.isNormalized() == normalized);
assert (h.isDenormalized() == denormalized);
assert (h.isZero() == zero);
assert (h.isNan() == nan);
assert (h.isInfinity() == infinity);
assert (h.isNegative() == negative);
}
float
floatPosInfinity ()
{
half::uif x;
x.i = 0x7f800000;
return x.f;
}
float
floatNegInfinity ()
{
half::uif x;
x.i = 0xff800000;
return x.f;
}
float
floatPosQNan1 ()
{
half::uif x;
x.i = 0x7fffffff;
return x.f;
}
float
floatNegQNan1 ()
{
half::uif x;
x.i = 0xffffffff;
return x.f;
}
float
floatPosQNan2 ()
{
half::uif x;
x.i = 0x7fd55555;
return x.f;
}
float
floatNegQNan2 ()
{
half::uif x;
x.i = 0xffd55555;
return x.f;
}
} // namespace
void
testClassification()
{
cout << "classification of bit patterns\n\n";
//
// fini norm deno zero nan inf neg
//
testClass (0.0, 1, 0, 0, 1, 0, 0, 0);
testClass (1.0, 1, 1, 0, 0, 0, 0, 0);
testClass (1.0f + HALF_EPSILON, 1, 1, 0, 0, 0, 0, 0);
testClass (HALF_MIN, 1, 0, 1, 0, 0, 0, 0);
testClass (HALF_MIN + HALF_MIN, 1, 0, 1, 0, 0, 0, 0);
testClass (HALF_NRM_MIN, 1, 1, 0, 0, 0, 0, 0);
testClass (HALF_NRM_MIN + HALF_MIN, 1, 1, 0, 0, 0, 0, 0);
testClass (HALF_NRM_MIN - HALF_MIN, 1, 0, 1, 0, 0, 0, 0);
testClass (2.0f, 1, 1, 0, 0, 0, 0, 0);
testClass (3.0f, 1, 1, 0, 0, 0, 0, 0);
testClass (0.1f, 1, 1, 0, 0, 0, 0, 0);
testClass (0.2f, 1, 1, 0, 0, 0, 0, 0);
testClass (0.3f, 1, 1, 0, 0, 0, 0, 0);
testClass (HALF_MAX, 1, 1, 0, 0, 0, 0, 0);
testClass (floatPosInfinity(), 0, 0, 0, 0, 0, 1, 0);
testClass (floatPosQNan1(), 0, 0, 0, 0, 1, 0, 0);
testClass (floatPosQNan2(), 0, 0, 0, 0, 1, 0, 0);
testClass (-1.0f, 1, 1, 0, 0, 0, 0, 1);
testClass (-1.0f - HALF_EPSILON, 1, 1, 0, 0, 0, 0, 1);
testClass (-HALF_MIN, 1, 0, 1, 0, 0, 0, 1);
testClass (-HALF_MIN - HALF_MIN, 1, 0, 1, 0, 0, 0, 1);
testClass (-HALF_NRM_MIN, 1, 1, 0, 0, 0, 0, 1);
testClass (-HALF_NRM_MIN - HALF_MIN,1, 1, 0, 0, 0, 0, 1);
testClass (-HALF_NRM_MIN + HALF_MIN,1, 0, 1, 0, 0, 0, 1);
testClass (-2.0f, 1, 1, 0, 0, 0, 0, 1);
testClass (-3.0f, 1, 1, 0, 0, 0, 0, 1);
testClass (-0.1f, 1, 1, 0, 0, 0, 0, 1);
testClass (-0.2f, 1, 1, 0, 0, 0, 0, 1);
testClass (-0.3f, 1, 1, 0, 0, 0, 0, 1);
testClass (-HALF_MAX, 1, 1, 0, 0, 0, 0, 1);
testClass (floatNegInfinity(), 0, 0, 0, 0, 0, 1, 1);
testClass (floatNegQNan1(), 0, 0, 0, 0, 1, 0, 1);
testClass (floatNegQNan2(), 0, 0, 0, 0, 1, 0, 1);
cout << "\n";
testClass (half::posInf(), 0, 0, 0, 0, 0, 1, 0);
testClass (half::negInf(), 0, 0, 0, 0, 0, 1, 1);
testClass (half::qNan(), 0, 0, 0, 0, 1, 0, 0);
testClass (half::sNan(), 0, 0, 0, 0, 1, 0, 0);
cout << "ok\n\n" << flush;
}

View File

@ -0,0 +1,3 @@
void testClassification ();

View File

@ -0,0 +1,212 @@
#include <testError.h>
#include "half.h"
#include <iostream>
#include <stdlib.h>
#include <assert.h>
using namespace std;
namespace {
float
drand()
{
return static_cast<float> (rand()/(RAND_MAX+1.0f));
}
} // namespace
void
testNormalizedConversionError()
{
cout << "float-to-half conversion error for normalized half numbers\n";
float eMax = 0;
for (int i = 0; i < 20000000; i++)
{
float f (drand() * HALF_MAX);
if (f < HALF_NRM_MIN)
continue;
if (i & 1)
f = -f;
half h (f);
float e = 1.0f - h/f;
if (e < 0)
e = -e;
if (e > HALF_EPSILON * 0.5)
{
cout << "float = " << f <<
", half = " << h <<
", error = " << e << endl;
assert (false);
}
if (e > eMax)
eMax = e;
}
cout << "max error = " << eMax << endl;
cout << "max expected error = " << HALF_EPSILON * 0.5 << endl;
cout << "ok\n\n" << flush;
}
void
testDenormalizedConversionError()
{
cout << "float-to-half conversion error for denormalized half numbers\n";
float eMax = 0;
for (int i = 0; i < 20000000; i++)
{
float f (drand() * (HALF_NRM_MIN - HALF_MIN));
if (i & 1)
f = -f;
half h (f);
float e = h - f;
if (e < 0)
e = -e;
if (e > HALF_MIN * 0.5)
{
cout << "float = " << f <<
", half = " << h <<
", error = " << e << endl;
assert (false);
}
if (e > eMax)
eMax = e;
}
cout << "max error = " << eMax << endl;
cout << "max expected error = " << HALF_MIN * 0.5 << endl;
cout << "ok\n\n" << flush;
}
namespace {
void
testNormalizedRounding (int n)
{
cout << "rounding normalized numbers to " << n << "-bit precision\n";
float eExpected = (n < 10)? HALF_EPSILON * 0.5f * (1 << (10 - n)): 0;
float eMax = 0;
for (int i = 0; i < 200000; i++)
{
half h (drand() * HALF_MAX);
if (h < HALF_NRM_MIN)
continue;
if (i & 1)
h = -h;
half r (h.round(n));
float e = 1.0f - r/h;
if (e < 0)
e = -e;
if (e > eExpected)
{
cout << "half = " << h <<
", rounded = " << r <<
", error = " << e <<
", expected error = " << eExpected << endl;
printBits (cout, h);
cout << endl;
printBits (cout, r);
cout << endl;
assert (false);
}
if (e > eMax)
eMax = e;
}
cout << "max error = " << eMax << endl;
cout << "max expected error = " << eExpected << endl;
cout << "ok\n\n" << flush;
}
void
testDenormalizedRounding (int n)
{
cout << "rounding denormalized numbers to " << n << "-bit precision\n";
float eExpected = (n < 10)? HALF_MIN * 0.5f * (1 << (10 - n)): 0;
float eMax = 0;
for (int i = 0; i < 200000; i++)
{
half h (drand() * (HALF_NRM_MIN - HALF_MIN));
if (i & 1)
h = -h;
half r (h.round(n));
float e = r - h;
if (e < 0)
e = -e;
if (e > eExpected)
{
cout << "half = " << h <<
", rounded = " << r <<
", error = " << e <<
", expected error = " << eExpected << endl;
printBits (cout, h);
cout << endl;
printBits (cout, r);
cout << endl;
assert (false);
}
if (e > eMax)
eMax = e;
}
cout << "max error = " << eMax << endl;
cout << "max expected error = " << eExpected << endl;
cout << "ok\n\n" << flush;
}
} // namespace
void
testRoundingError ()
{
testNormalizedRounding (10);
testDenormalizedRounding (10);
testNormalizedRounding (9);
testDenormalizedRounding (9);
testNormalizedRounding (1);
testDenormalizedRounding (1);
testNormalizedRounding (0);
testDenormalizedRounding (0);
}

View File

@ -0,0 +1,5 @@
void testNormalizedConversionError ();
void testDenormalizedConversionError ();
void testRoundingError ();

View File

@ -0,0 +1,68 @@
#include <testFunction.h>
#include "halfFunction.h"
#include <iostream>
#include <assert.h>
using namespace std;
namespace {
float
divideByTwo (float x)
{
return x / 2;
}
struct timesN
{
timesN (float n): n (n) {}
float operator () (float x) {return x * n;}
float n;
};
} // namespace
void
testFunction ()
{
cout << "halfFunction<T>\n";
halfFunction <float> d2 (divideByTwo);
assert (d2 (0) == 0);
assert (d2 (2) == 1);
assert (d2 (-2) == -1);
assert (d2 (HALF_MAX) == HALF_MAX / 2);
assert (d2 (-HALF_MAX) == -HALF_MAX / 2);
assert (d2 (half::posInf()) == 0);
assert (d2 (half::negInf()) == 0);
assert (d2 (half::qNan()) == 0);
halfFunction <half> t5 (timesN (5), // function
0, HALF_MAX / 8, // domain
-1, // default value
half::posInf(), // posInfValue
half::negInf(), // negInfValue
half::qNan()); // nanValue
assert (t5 (0) == 0);
assert (t5 (2) == 10);
assert (t5 (-2) == -1);
assert (t5 (HALF_MAX) == -1);
assert (t5 (-HALF_MAX) == -1);
assert ( t5(half::posInf()).isInfinity());
assert (!t5(half::posInf()).isNegative());
assert (t5(half::negInf()).isInfinity());
assert (t5(half::negInf()).isNegative());
assert (t5(half::qNan()).isNan());
cout << "ok\n\n" << flush;
}

View File

@ -0,0 +1,3 @@
void testFunction ();

View File

@ -0,0 +1,94 @@
#include <testLimits.h>
#include "halfLimits.h"
#include <iostream>
#include <assert.h>
using namespace std;
namespace {
float
mypow (int x, int y)
{
bool negative = false;
if (y < 0)
{
negative = true;
y = -y;
}
float z = 1;
while (y > 0)
{
z *= x;
y -= 1;
}
if (negative)
z = 1 / z;
return z;
}
} // namespace
void
testLimits()
{
cout << "values in std::numeric_limits<half>\n";
cout << "min_exponent\n";
{
half h (mypow (2, numeric_limits<half>::min_exponent - 1));
assert (h.isNormalized());
}
{
half h (mypow (2, numeric_limits<half>::min_exponent - 2));
assert (h.isDenormalized());
}
cout << "max_exponent\n";
{
half h (mypow (2, numeric_limits<half>::max_exponent - 1));
assert (h.isNormalized());
}
{
half h (mypow (2, numeric_limits<half>::max_exponent));
assert (h.isInfinity());
}
cout << "min_exponent10\n";
{
half h (mypow (10, numeric_limits<half>::min_exponent10));
assert (h.isNormalized());
}
{
half h (mypow (10, numeric_limits<half>::min_exponent10 - 1));
assert (h.isDenormalized());
}
cout << "max_exponent10\n";
{
half h (mypow (10, numeric_limits<half>::max_exponent10));
assert (h.isNormalized());
}
{
half h (mypow (10, numeric_limits<half>::max_exponent10 + 1));
assert (h.isInfinity());
}
cout << "ok\n\n" << flush;
}

View File

@ -0,0 +1,3 @@
void testLimits ();

View File

@ -0,0 +1,27 @@
#include <testSize.h>
#include "half.h"
#include <iostream>
#include <assert.h>
#include <stddef.h>
using namespace std;
void
testSize ()
{
cout << "size and alignment\n";
half h[2];
int size = sizeof (half);
ptrdiff_t algn = (char *)&h[1] - (char *)&h[0];
cout << "sizeof (half) = " << size << endl;
cout << "alignof (half) = " << (int) algn << endl;
assert (size == 2 && algn == 2);
cout << "ok\n\n" << flush;
}

View File

@ -0,0 +1,3 @@
void testSize ();