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 v11_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

typedef union imath_half_uif imath_half_uif_t

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

## Function Documentation

## imath_float_to_half()

imath_half_bits_t imath_float_to_half | ( | float | f | ) |

inline static

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()

float imath_half_to_float | ( | imath_half_bits_t | h | ) |

inline static

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 )