OpenVDB 12.0.0
Loading...
Searching...
No Matches
Half.h File Reference
#include <openvdb/Platform.h>
#include <openvdb/version.h>
#include <iostream>
#include <stdint.h>
#include <stdio.h>
#include <limits>

Go to the source code of this file.

Classes

union  imath_half_uif
 a type for both C-only programs and C++ to use the same utilities More...
 
class  half
 
class  numeric_limits< openvdb::math::internal::half >
 

Namespaces

namespace  std
 

Macros

#define IMATH_HALF_NO_LOOKUP_TABLE
 
#define VDBB_HALF_DENORM_MIN   5.96046448e-08
 
#define VDB_HALF_NRM_MIN   6.10351562e-05
 
#define VDB_HALF_MIN   6.10351562e-05f
 
#define VDB_HALF_MAX   65504.0
 
#define VDB_HALF_EPSILON   0.00097656
 
#define VDB_HALF_MANT_DIG   11
 
#define VDB_HALF_DIG   3
 
#define VDB_HALF_DECIMAL_DIG   5
 
#define VDB_HALF_RADIX   2
 
#define VDBB_HALF_DENORM_MIN_EXP   -13
 
#define VDB_HALF_MAX_EXP   16
 
#define VDBB_HALF_DENORM_MIN_10_EXP   -4
 
#define VDB_HALF_MAX_10_EXP   4
 

Typedefs

typedef union imath_half_uif imath_half_uif_t
 a type for both C-only programs and C++ to use the same utilities
 
typedef uint16_t imath_half_bits_t
 a type for both C-only programs and C++ to use the same utilities
 
typedef imath_half_bits_t half
 if we're in a C-only context, alias the half bits type to half
 

Functions

static float imath_half_to_float (imath_half_bits_t h)
 
static imath_half_bits_t imath_float_to_half (float f)
 
OPENVDB_API void printBits (std::ostream &os, half h)
 
OPENVDB_API void printBits (std::ostream &os, float f)
 
OPENVDB_API void printBits (char c[19], half h)
 
OPENVDB_API void printBits (char c[35], float f)
 
OPENVDB_API std::ostream & operator<< (std::ostream &os, half h)
 Output h to os, formatted as a float.
 
OPENVDB_API std::istream & operator>> (std::istream &is, half &h)
 Input h from is.
 

Detailed Description

The half type is a 16-bit floating number, compatible with the IEEE 754-2008 binary16 type.

Representation of a 32-bit float:

We assume that a float, f, is an IEEE 754 single-precision floating point number, whose bits are arranged as follows:

31 (msb)
|
| 30     23
| |      |
| |      | 22                    0 (lsb)
| |      | |                     |
X XXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX

s e        m

S is the sign-bit, e is the exponent and m is the significand.

If e is between 1 and 254, f is a normalized number:

        s    e-127
f = (-1)  * 2      * 1.m

If e is 0, and m is not zero, f is a denormalized number:

        s    -126
f = (-1)  * 2      * 0.m

If e and m are both zero, f is zero:

f = 0.0

If e is 255, f is an "infinity" or "not a number" (NAN), depending on whether m is zero or not.

Examples:

0 00000000 00000000000000000000000 = 0.0
0 01111110 00000000000000000000000 = 0.5
0 01111111 00000000000000000000000 = 1.0
0 10000000 00000000000000000000000 = 2.0
0 10000000 10000000000000000000000 = 3.0
1 10000101 11110000010000000000000 = -124.0625
0 11111111 00000000000000000000000 = +infinity
1 11111111 00000000000000000000000 = -infinity
0 11111111 10000000000000000000000 = NAN
1 11111111 11111111111111111111111 = NAN

Representation of a 16-bit half:

Here is the bit-layout for a half number, h:

15 (msb)
|
| 14  10
| |   |
| |   | 9        0 (lsb)
| |   | |        |
X XXXXX XXXXXXXXXX

s e     m

S is the sign-bit, e is the exponent and m is the significand.

If e is between 1 and 30, h is a normalized number:

        s    e-15
h = (-1)  * 2     * 1.m

If e is 0, and m is not zero, h is a denormalized number:

        S    -14
h = (-1)  * 2     * 0.m

If e and m are both zero, h is zero:

h = 0.0

If e is 31, h is an "infinity" or "not a number" (NAN), depending on whether m is zero or not.

Examples:

0 00000 0000000000 = 0.0
0 01110 0000000000 = 0.5
0 01111 0000000000 = 1.0
0 10000 0000000000 = 2.0
0 10000 1000000000 = 3.0
1 10101 1111000001 = -124.0625
0 11111 0000000000 = +infinity
1 11111 0000000000 = -infinity
0 11111 1000000000 = NAN
1 11111 1111111111 = NAN

Conversion via Lookup Table:

Converting from half to float is performed by default using a lookup table. There are only 65,536 different half numbers; each of these numbers has been converted and stored in a table pointed to by the imath_half_to_float_table pointer. / / Prior to Imath v3.1, conversion from float to half was / accomplished with the help of an exponent look table, but this is / now replaced with explicit bit shifting. / / Conversion via Hardware: / / For Imath v3.1, the conversion routines have been extended to use / F16C SSE instructions whenever present and enabled by compiler / flags. / / Conversion via Bit-Shifting / / If F16C SSE instructions are not available, conversion can be / accomplished by a bit-shifting algorithm. For half-to-float / conversion, this is generally slower than the lookup table, but it / may be preferable when memory limits preclude storing of the / 65,536-entry lookup table. / / The lookup table symbol is included in the compilation even if / IMATH_HALF_USE_LOOKUP_TABLE is false, because application code / using the exported half.h may choose to enable the use of the table. / / An implementation can eliminate the table from compilation by / defining the IMATH_HALF_NO_LOOKUP_TABLE preprocessor symbol. / Simply add: / / #define IMATH_HALF_NO_LOOKUP_TABLE / / before including half.h, or define the symbol on the compile / command line. / / Furthermore, an implementation wishing to receive FE_OVERFLOW / and FE_UNDERFLOW floating point exceptions when converting / float to half by the bit-shift algorithm can define the / preprocessor symbol IMATH_HALF_ENABLE_FP_EXCEPTIONS prior to / including half.h: / / #define IMATH_HALF_ENABLE_FP_EXCEPTIONS / / Conversion Performance Comparison: / / Testing on a Core i9, the timings are approximately: / / half to float / - table: 0.71 ns / call / - no table: 1.06 ns / call / - f16c: 0.45 ns / call / / float-to-half: / - original: 5.2 ns / call / - no exp table + opt: 1.27 ns / call / - f16c: 0.45 ns / call / / Note: the timing above depends on the distribution of the / floats in question. /

OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN

namespace openvdb { OPENVDB_USE_VERSION_NAMESPACE namespace v12_0 { namespace math { namespace internal {

Use of lookup table is explicitly suppressed and the generation of a lookup table is suppressed. This is required because we namespace our type, but the lookup table is extern "C" and lacks a namespace. Thus any attempt to link two versions of OpenVDB with different namespaces will clash due to redefinition with a new type. The default was not to use a lookup table.

#define IMATH_HALF_NO_LOOKUP_TABLE


Limits

Visual C++ will complain if VDBB_HALF_DENORM_MIN, VDB_HALF_NRM_MIN etc. are not float constants, but at least one other compiler (gcc 2.96) produces incorrect

results if they are.

/ Smallest positive denormalized half #define VDBB_HALF_DENORM_MIN
/ Smallest positive normalized half #define VDB_HALF_NRM_MIN
/ Smallest positive normalized half #define VDB_HALF_MIN
/ Largest positive half #define VDB_HALF_MAX
/ Smallest positive e for which half(1.0 + e) != half(1.0) #define VDB_HALF_EPSILON

/ Number of digits in mantissa (significand + hidden leading 1) #define VDB_HALF_MANT_DIG
/ Number of base 10 digits that can be represented without change: / / floor( (HALF_MANT_DIG - 1) * log10(2) ) => 3.01... -> 3 #define VDB_HALF_DIG
/ Number of base-10 digits that are necessary to uniquely represent / all distinct values: / / ceil(HALF_MANT_DIG * log10(2) + 1) => 4.31... -> 5 #define VDB_HALF_DECIMAL_DIG
/ Base of the exponent #define VDB_HALF_RADIX
/ Minimum negative integer such that HALF_RADIX raised to the power / of one less than that integer is a normalized half #define VDBB_HALF_DENORM_MIN_EXP
/ Maximum positive integer such that HALF_RADIX raised to the power of one less than that integer is a normalized half

Macro Definition Documentation

◆ IMATH_HALF_NO_LOOKUP_TABLE

#define IMATH_HALF_NO_LOOKUP_TABLE

◆ VDB_HALF_DECIMAL_DIG

#define VDB_HALF_DECIMAL_DIG   5

◆ VDB_HALF_DIG

#define VDB_HALF_DIG   3

◆ VDB_HALF_EPSILON

#define VDB_HALF_EPSILON   0.00097656

◆ VDB_HALF_MANT_DIG

#define VDB_HALF_MANT_DIG   11

◆ VDB_HALF_MAX

#define VDB_HALF_MAX   65504.0

◆ VDB_HALF_MAX_10_EXP

#define VDB_HALF_MAX_10_EXP   4

Maximum positive integer such that 10 raised to that power is a normalized half

◆ VDB_HALF_MAX_EXP

#define VDB_HALF_MAX_EXP   16

◆ VDB_HALF_MIN

#define VDB_HALF_MIN   6.10351562e-05f

◆ VDB_HALF_NRM_MIN

#define VDB_HALF_NRM_MIN   6.10351562e-05

◆ VDB_HALF_RADIX

#define VDB_HALF_RADIX   2

◆ VDBB_HALF_DENORM_MIN

#define VDBB_HALF_DENORM_MIN   5.96046448e-08

◆ VDBB_HALF_DENORM_MIN_10_EXP

#define VDBB_HALF_DENORM_MIN_10_EXP   -4

Minimum positive integer such that 10 raised to that power is a normalized half

◆ VDBB_HALF_DENORM_MIN_EXP

#define VDBB_HALF_DENORM_MIN_EXP   -13

Typedef Documentation

◆ half

typedef imath_half_bits_t half

if we're in a C-only context, alias the half bits type to half

◆ imath_half_bits_t

typedef uint16_t imath_half_bits_t

a type for both C-only programs and C++ to use the same utilities

◆ imath_half_uif_t

a type for both C-only programs and C++ to use the same utilities

Function Documentation

◆ imath_float_to_half()

static imath_half_bits_t imath_float_to_half ( float f)
inlinestatic

Convert half to float

Note: This only supports the "round to even" rounding mode, which was the only mode supported by the original OpenEXR library

◆ imath_half_to_float()

static float imath_half_to_float ( imath_half_bits_t h)
inlinestatic

Convert half to float

◆ operator<<()

OPENVDB_API std::ostream & operator<< ( std::ostream & os,
half h )

Output h to os, formatted as a float.

◆ operator>>()

OPENVDB_API std::istream & operator>> ( std::istream & is,
half & h )

Input h from is.

◆ printBits() [1/4]

OPENVDB_API void printBits ( char c[19],
half h )

◆ printBits() [2/4]

OPENVDB_API void printBits ( char c[35],
float f )

◆ printBits() [3/4]

OPENVDB_API void printBits ( std::ostream & os,
float f )

◆ printBits() [4/4]

OPENVDB_API void printBits ( std::ostream & os,
half h )