mirror of https://gitee.com/openkylin/ilmbase.git
489 lines
14 KiB
C++
489 lines
14 KiB
C++
#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
|
|
#ifndef __mc68000__
|
|
testBits (floatPosQNan2(),
|
|
"0 11111 1010101010", // nan
|
|
"0 11111111 10101010100000000000000"); // nan
|
|
#endif
|
|
|
|
//
|
|
// 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
|
|
#ifndef __mc68000__
|
|
testBits (floatNegQNan1(),
|
|
"1 11111 1111111111", // nan
|
|
"1 11111111 11111111110000000000000"); // nan
|
|
testBits (floatNegQNan2(),
|
|
"1 11111 1010101010", // nan
|
|
"1 11111111 10101010100000000000000"); // nan
|
|
#endif
|
|
|
|
cout << "ok\n\n" << flush;
|
|
}
|