Collect value statistics for formats

This notebook presents various statistics for a variety of float formats. Some of these are present on the FormatInfo class, and are presented for all formats. Others are obtained by enumerating all values (only for the =16 bit formats).

Statistics obtained from FormatInfo

  • name: Format

  • B: Bits in the format

  • P: Precision in bits

  • E: Exponent field width in bits

  • T: Trailing significand field width in bits

  • max: Largest finite value

  • min: Most negative value (typically the same, unless twos complement)

  • smallest: Smallest positive value

  • smallest_normal: Smallest positive normal value, NaN if all finite values are subnormal

%run utils.py
D = pandas_render  # from utils
import pandas
from functools import partial
from gfloat import *
from gfloat.formats import *

import numpy as np


# Special rendering for float values -
# if they don't round-trip in 8.5g, prepend with "≈", or render as rational
def render_float(approx: bool, v):
    if not isinstance(v, float):
        return str(v)

    if np.isnan(v):
        return "n/a"

    s = f"{v:8.5g}"
    if float(s) == v:
        return s

    if approx:
        return "≈" + s
    else:
        return float_pow2str(v)


def collect_stats(fi: FormatInfo):
    return dict(
        name=fi.name,
        B=fi.bits,
        P=fi.precision,
        E=fi.expBits,
        smallest=fi.smallest,
        smallest_normal=fi.smallest_normal if not fi.is_all_subnormal else np.nan,
        max=fi.max,
        num_nans=float(fi.num_nans),
        infs=fi.num_infs,
    )


stats = [collect_stats(fi) for fi in sample_formats]
df = pandas.DataFrame(stats)
D(df, format=partial(render_float, True))
name B P E smallest smallest_normal max num_nans infs
p3109_k3p2sf 3 2 1 0.5 1 1.5 1 0
ocp_e2m1 4 2 2 0.5 1 6 0 0
p3109_k4p2sf 4 2 2 0.25 0.5 3 1 0
ocp_e2m3 6 4 2 0.125 1 7.5 0 0
ocp_e3m2 6 3 3 0.0625 0.25 28 0 0
p3109_k6p3sf 6 3 3 0.03125 0.125 14 1 0
p3109_k6p4sf 6 4 2 0.0625 0.5 3.75 1 0
ocp_e4m3 8 4 4 ≈0.0019531 0.015625 448 2 0
ocp_e5m2 8 3 5 ≈1.5259e-05 ≈6.1035e-05 57344 6 2
p3109_k8p1se 8 1 7 ≈1.0842e-19 ≈1.0842e-19 ≈4.6117e+18 1 2
p3109_k8p1ue 8 1 8 ≈5.8775e-39 ≈5.8775e-39 ≈4.2535e+37 1 1
p3109_k8p3se 8 3 5 ≈7.6294e-06 ≈3.0518e-05 49152 1 2
p3109_k8p3sf 8 3 5 ≈7.6294e-06 ≈3.0518e-05 57344 1 0
p3109_k8p3ue 8 3 6 ≈1.1642e-10 ≈4.6566e-10 ≈2.6844e+09 1 1
p3109_k8p3uf 8 3 6 ≈1.1642e-10 ≈4.6566e-10 ≈3.2212e+09 1 0
p3109_k8p4se 8 4 4 ≈0.00097656 0.0078125 224 1 2
p3109_k8p4sf 8 4 4 ≈0.00097656 0.0078125 240 1 0
p3109_k8p4ue 8 4 5 ≈3.8147e-06 ≈3.0518e-05 53248 1 1
p3109_k8p4uf 8 4 5 ≈3.8147e-06 ≈3.0518e-05 57344 1 0
p3109_k8p7sf 8 7 1 0.015625 1 ≈ 1.9844 1 0
p3109_k8p8uf 8 8 1 0.0078125 1 ≈ 1.9844 1 0
binary16 16 11 5 ≈5.9605e-08 ≈6.1035e-05 65504 2046 2
bfloat16 16 8 8 ≈9.1835e-41 ≈1.1755e-38 ≈3.3895e+38 254 2
binary32 32 24 8 ≈1.4013e-45 ≈1.1755e-38 ≈3.4028e+38 ≈1.6777e+07 2
binary64 64 53 11 4.9407e-324 ≈2.2251e-308 ≈1.7977e+308 ≈9.0072e+15 2
ocp_e8m0 8 1 8 ≈5.8775e-39 ≈5.8775e-39 ≈1.7014e+38 1 0
ocp_int8 8 8 0 0.015625 n/a ≈ 1.9844 0 0

Statistics computed by exhaustive inspection

  • lt1: Number of values x such that 0 < x < 1

  • gt1: Number of values x such that 1 < x < Inf

  • rt16: True if all values are exactly representable in IEEE binary16

  • min/maxSubnormal: Smallest/largest subnormal value, “n/a” if no values are subnormal

  • min/maxNormal: Smallest/largest normal value, “n/a” if no values are normal

def compute_stats(fi: FormatInfo):
    # Generate all values
    values = [decode_float(fi, i) for i in range(2**fi.bits)]
    df = pandas.DataFrame(values)

    # Compute statistics: lt1,gt1
    fval = df["fval"]
    total_01 = fval.between(0, 1, inclusive="neither").sum()
    total_1Inf = fval.between(1, np.inf, inclusive="neither").sum()

    # Compute statistics: maxFinite,minFinite
    finite_vals = fval[np.isfinite(fval)]
    maxFinite = finite_vals.loc[finite_vals.idxmax()]
    minFinite = finite_vals.loc[finite_vals.idxmin()]
    assert maxFinite == fi.max
    assert minFinite == fi.min
    fi.emax

    # Compute statistics: maxNormal,minNormal
    normal_vals = fval[(df["fclass"] == FloatClass.NORMAL) & (fval > 0)]
    maxNormal = normal_vals.loc[normal_vals.idxmax()] if normal_vals.any() else np.nan
    minNormal = normal_vals.loc[normal_vals.idxmin()] if normal_vals.any() else np.nan
    assert np.isnan(maxNormal) or maxNormal == fi.max
    assert np.isnan(minNormal) or minNormal == fi.smallest_normal

    # Compute statistics: minSubnormal
    pos_subnormal = fval[(df["fclass"] == FloatClass.SUBNORMAL) & (fval > 0)]
    maxSubnormal = (
        pos_subnormal.loc[pos_subnormal.idxmax()] if pos_subnormal.any() else np.nan
    )
    minSubnormal = (
        pos_subnormal.loc[pos_subnormal.idxmin()] if pos_subnormal.any() else np.nan
    )
    assert np.isnan(minSubnormal) or minSubnormal == fi.smallest_subnormal
    assert np.isnan(minNormal) or minNormal == fi.smallest_normal

    assert np.nanmin([minSubnormal, minNormal]) == fi.smallest

    # Compute roundtrips: rt16, rt32
    with np.errstate(over="ignore"):
        rt16 = (np.float64(np.float16(fval)) == np.float64(fval)) | ~np.isfinite(fval)
        rt32 = (np.float64(np.float32(fval)) == np.float64(fval)) | ~np.isfinite(fval)

    rt16 = rt16.all()
    rt32 = rt32.all()
    # assert rt32  # If not, we should include rt32 in the table

    # Assemble tuple
    return dict(
        name=fi.name,
        B=fi.bits,
        P=fi.precision,
        E=fi.expBits,
        lt1=total_01,
        gt1=total_1Inf,
        minSubnormal=minSubnormal,
        maxSubnormal=maxSubnormal,
        minNormal=minNormal,
        maxNormal=maxNormal,
        rt16=rt16,
        rt32=rt32,
    )


stats = [compute_stats(fi) for fi in sample_formats if fi.bits <= 16]
df2 = pandas.DataFrame(stats)
D(df2, format=partial(render_float, True))
name B P E lt1 gt1 minSubnormal maxSubnormal minNormal maxNormal rt16 rt32
p3109_k3p2sf 3 2 1 1 1 0.5 0.5 1 1.5 True True
ocp_e2m1 4 2 2 1 5 0.5 0.5 1 6 True True
p3109_k4p2sf 4 2 2 3 3 0.25 0.25 0.5 3 True True
ocp_e2m3 6 4 2 7 23 0.125 0.875 1 7.5 True True
ocp_e3m2 6 3 3 11 19 0.0625 0.1875 0.25 28 True True
p3109_k6p3sf 6 3 3 15 15 0.03125 0.09375 0.125 14 True True
p3109_k6p4sf 6 4 2 15 15 0.0625 0.4375 0.5 3.75 True True
ocp_e4m3 8 4 4 55 70 ≈0.0019531 ≈0.013672 0.015625 448 True True
ocp_e5m2 8 3 5 59 63 ≈1.5259e-05 ≈4.5776e-05 ≈6.1035e-05 57344 True True
p3109_k8p1se 8 1 7 63 62 n/a n/a ≈1.0842e-19 ≈4.6117e+18 False True
p3109_k8p1ue 8 1 8 127 125 n/a n/a ≈5.8775e-39 ≈4.2535e+37 False True
p3109_k8p3se 8 3 5 63 62 ≈7.6294e-06 ≈2.2888e-05 ≈3.0518e-05 49152 True True
p3109_k8p3sf 8 3 5 63 63 ≈7.6294e-06 ≈2.2888e-05 ≈3.0518e-05 57344 True True
p3109_k8p3ue 8 3 6 127 125 ≈1.1642e-10 ≈3.4925e-10 ≈4.6566e-10 ≈2.6844e+09 False True
p3109_k8p3uf 8 3 6 127 126 ≈1.1642e-10 ≈3.4925e-10 ≈4.6566e-10 ≈3.2212e+09 False True
p3109_k8p4se 8 4 4 63 62 ≈0.00097656 ≈0.0068359 0.0078125 224 True True
p3109_k8p4sf 8 4 4 63 63 ≈0.00097656 ≈0.0068359 0.0078125 240 True True
p3109_k8p4ue 8 4 5 127 125 ≈3.8147e-06 ≈2.6703e-05 ≈3.0518e-05 53248 True True
p3109_k8p4uf 8 4 5 127 126 ≈3.8147e-06 ≈2.6703e-05 ≈3.0518e-05 57344 True True
p3109_k8p7sf 8 7 1 63 63 0.015625 ≈ 0.98438 1 ≈ 1.9844 True True
p3109_k8p8uf 8 8 1 127 126 0.0078125 ≈ 0.99219 1 ≈ 1.9844 True True
binary16 16 11 5 15359 16383 ≈5.9605e-08 ≈6.0976e-05 ≈6.1035e-05 65504 True True
bfloat16 16 8 8 16255 16383 ≈9.1835e-41 ≈1.1663e-38 ≈1.1755e-38 ≈3.3895e+38 False True
ocp_e8m0 8 1 8 127 127 n/a n/a ≈5.8775e-39 ≈1.7014e+38 False True
ocp_int8 8 8 0 63 63 0.015625 ≈ 1.9844 n/a n/a True True

Emit the same table, but with exact values

In this table, float values are printed as decimals, unless the decimals are not an exact representation of the value, in which case, they are printed as rationals (between 1 and 2) times 2^E.

D(df2, format=partial(render_float, False))
name B P E lt1 gt1 minSubnormal maxSubnormal minNormal maxNormal rt16 rt32
p3109_k3p2sf 3 2 1 1 1 0.5 0.5 1 1.5 True True
ocp_e2m1 4 2 2 1 5 0.5 0.5 1 6 True True
p3109_k4p2sf 4 2 2 3 3 0.25 0.25 0.5 3 True True
ocp_e2m3 6 4 2 7 23 0.125 0.875 1 7.5 True True
ocp_e3m2 6 3 3 11 19 0.0625 0.1875 0.25 28 True True
p3109_k6p3sf 6 3 3 15 15 0.03125 0.09375 0.125 14 True True
p3109_k6p4sf 6 4 2 15 15 0.0625 0.4375 0.5 3.75 True True
ocp_e4m3 8 4 4 55 70 2^-9 7/4*2^-7 0.015625 448 True True
ocp_e5m2 8 3 5 59 63 2^-16 3/2*2^-15 2^-14 57344 True True
p3109_k8p1se 8 1 7 63 62 n/a n/a 2^-63 2^62 False True
p3109_k8p1ue 8 1 8 127 125 n/a n/a 2^-127 2^125 False True
p3109_k8p3se 8 3 5 63 62 2^-17 3/2*2^-16 2^-15 49152 True True
p3109_k8p3sf 8 3 5 63 63 2^-17 3/2*2^-16 2^-15 57344 True True
p3109_k8p3ue 8 3 6 127 125 2^-33 3/2*2^-32 2^-31 5/4*2^31 False True
p3109_k8p3uf 8 3 6 127 126 2^-33 3/2*2^-32 2^-31 3/2*2^31 False True
p3109_k8p4se 8 4 4 63 62 2^-10 7/4*2^-8 0.0078125 224 True True
p3109_k8p4sf 8 4 4 63 63 2^-10 7/4*2^-8 0.0078125 240 True True
p3109_k8p4ue 8 4 5 127 125 2^-18 7/4*2^-16 2^-15 53248 True True
p3109_k8p4uf 8 4 5 127 126 2^-18 7/4*2^-16 2^-15 57344 True True
p3109_k8p7sf 8 7 1 63 63 0.015625 63/32*2^-1 1 127/64*2^0 True True
p3109_k8p8uf 8 8 1 127 126 0.0078125 127/64*2^-1 1 127/64*2^0 True True
binary16 16 11 5 15359 16383 2^-24 1023/512*2^-15 2^-14 65504 True True
bfloat16 16 8 8 16255 16383 2^-133 127/64*2^-127 2^-126 255/128*2^127 False True
ocp_e8m0 8 1 8 127 127 n/a n/a 2^-127 2^127 False True
ocp_int8 8 8 0 63 63 0.015625 127/64*2^0 n/a n/a True True
count_p3109_formats = len(
    [
        1
        for signedness in (True, False)
        for domain in (Domain.Extended, Domain.Finite)
        for k in range(2, 16)
        for p in range(1, k if signedness else k + 1)
    ]
)
count_p3109_formats, count_p3109_formats == format_info_ocp_e4m3.max
(448, True)
all_p3109 = [
    format_info_p3109(k, p, signedness, domain)
    for signedness in (Signedness.Signed, Signedness.Unsigned)
    for domain in (Domain.Extended, Domain.Finite)
    for k in range(3, 8)
    for p in range(1, k if signedness == Signedness.Signed else k + 1)
]

stats = [compute_stats(fi) for fi in all_p3109]
df3 = pandas.DataFrame(stats)
df3["rt32"].all()
# D(df3, format=partial(render_float, True))
np.True_

Tables in RST/Markdown

These are used to generate gfloat documentation, but may be of use in other contexts so left here.

from tabulate import tabulate

dfstr = df.map(lambda x: render_float(True, x))
print(
    tabulate(dfstr, df.columns, tablefmt="rst", showindex=False).replace(" nan", " n/a")
)
============  ===  ===  ===  ===========  =================  ============  ===========  ======
name            B    P    E  smallest     smallest_normal    max           num_nans       infs
============  ===  ===  ===  ===========  =================  ============  ===========  ======
p3109_k3p2sf    3    2    1  0.5          1                  1.5           1                 0
ocp_e2m1        4    2    2  0.5          1                  6             0                 0
p3109_k4p2sf    4    2    2  0.25         0.5                3             1                 0
ocp_e2m3        6    4    2  0.125        1                  7.5           0                 0
ocp_e3m2        6    3    3  0.0625       0.25               28            0                 0
p3109_k6p3sf    6    3    3  0.03125      0.125              14            1                 0
p3109_k6p4sf    6    4    2  0.0625       0.5                3.75          1                 0
ocp_e4m3        8    4    4  ≈0.0019531   0.015625           448           2                 0
ocp_e5m2        8    3    5  ≈1.5259e-05  ≈6.1035e-05        57344         6                 2
p3109_k8p1se    8    1    7  ≈1.0842e-19  ≈1.0842e-19        ≈4.6117e+18   1                 2
p3109_k8p1ue    8    1    8  ≈5.8775e-39  ≈5.8775e-39        ≈4.2535e+37   1                 1
p3109_k8p3se    8    3    5  ≈7.6294e-06  ≈3.0518e-05        49152         1                 2
p3109_k8p3sf    8    3    5  ≈7.6294e-06  ≈3.0518e-05        57344         1                 0
p3109_k8p3ue    8    3    6  ≈1.1642e-10  ≈4.6566e-10        ≈2.6844e+09   1                 1
p3109_k8p3uf    8    3    6  ≈1.1642e-10  ≈4.6566e-10        ≈3.2212e+09   1                 0
p3109_k8p4se    8    4    4  ≈0.00097656  0.0078125          224           1                 2
p3109_k8p4sf    8    4    4  ≈0.00097656  0.0078125          240           1                 0
p3109_k8p4ue    8    4    5  ≈3.8147e-06  ≈3.0518e-05        53248         1                 1
p3109_k8p4uf    8    4    5  ≈3.8147e-06  ≈3.0518e-05        57344         1                 0
p3109_k8p7sf    8    7    1  0.015625     1                  ≈  1.9844     1                 0
p3109_k8p8uf    8    8    1  0.0078125    1                  ≈  1.9844     1                 0
binary16       16   11    5  ≈5.9605e-08  ≈6.1035e-05        65504         2046              2
bfloat16       16    8    8  ≈9.1835e-41  ≈1.1755e-38        ≈3.3895e+38   254               2
binary32       32   24    8  ≈1.4013e-45  ≈1.1755e-38        ≈3.4028e+38   ≈1.6777e+07       2
binary64       64   53   11  4.9407e-324  ≈2.2251e-308       ≈1.7977e+308  ≈9.0072e+15       2
ocp_e8m0        8    1    8  ≈5.8775e-39  ≈5.8775e-39        ≈1.7014e+38   1                 0
ocp_int8        8    8    0  0.015625     n/a                ≈  1.9844     0                 0
============  ===  ===  ===  ===========  =================  ============  ===========  ======
from tabulate import tabulate

dfstr = df.map(lambda x: render_float(False, x))
print(tabulate(dfstr, df.columns, tablefmt="rst", showindex=False))
============  ===  ===  ===  ===========  =================  ========================================  ======================================  ======
name            B    P    E  smallest     smallest_normal    max                                       num_nans                                  infs
============  ===  ===  ===  ===========  =================  ========================================  ======================================  ======
p3109_k3p2sf    3    2    1  0.5          1                  1.5                                       1                                            0
ocp_e2m1        4    2    2  0.5          1                  6                                         0                                            0
p3109_k4p2sf    4    2    2  0.25         0.5                3                                         1                                            0
ocp_e2m3        6    4    2  0.125        1                  7.5                                       0                                            0
ocp_e3m2        6    3    3  0.0625       0.25               28                                        0                                            0
p3109_k6p3sf    6    3    3  0.03125      0.125              14                                        1                                            0
p3109_k6p4sf    6    4    2  0.0625       0.5                3.75                                      1                                            0
ocp_e4m3        8    4    4  2^-9         0.015625           448                                       2                                            0
ocp_e5m2        8    3    5  2^-16        2^-14              57344                                     6                                            2
p3109_k8p1se    8    1    7  2^-63        2^-63              2^62                                      1                                            2
p3109_k8p1ue    8    1    8  2^-127       2^-127             2^125                                     1                                            1
p3109_k8p3se    8    3    5  2^-17        2^-15              49152                                     1                                            2
p3109_k8p3sf    8    3    5  2^-17        2^-15              57344                                     1                                            0
p3109_k8p3ue    8    3    6  2^-33        2^-31              5/4*2^31                                  1                                            1
p3109_k8p3uf    8    3    6  2^-33        2^-31              3/2*2^31                                  1                                            0
p3109_k8p4se    8    4    4  2^-10        0.0078125          224                                       1                                            2
p3109_k8p4sf    8    4    4  2^-10        0.0078125          240                                       1                                            0
p3109_k8p4ue    8    4    5  2^-18        2^-15              53248                                     1                                            1
p3109_k8p4uf    8    4    5  2^-18        2^-15              57344                                     1                                            0
p3109_k8p7sf    8    7    1  0.015625     1                  127/64*2^0                                1                                            0
p3109_k8p8uf    8    8    1  0.0078125    1                  127/64*2^0                                1                                            0
binary16       16   11    5  2^-24        2^-14              65504                                     2046                                         2
bfloat16       16    8    8  2^-133       2^-126             255/128*2^127                             254                                          2
binary32       32   24    8  2^-149       2^-126             16777215/8388608*2^127                    8388607/4194304*2^23                         2
binary64       64   53   11  4.9407e-324  2^-1022            9007199254740991/9007199254740992*2^1024  4503599627370495/4503599627370496*2^53       2
ocp_e8m0        8    1    8  2^-127       2^-127             2^127                                     1                                            0
ocp_int8        8    8    0  0.015625     n/a                127/64*2^0                                0                                            0
============  ===  ===  ===  ===========  =================  ========================================  ======================================  ======
dfstr = df2.map(lambda x: render_float(False, x))
print(
    tabulate(dfstr, df2.columns, tablefmt="github", showindex=False).replace(
        " nan", " n/a"
    )
)
| name         |   B |   P |   E |   lt1 |   gt1 | minSubnormal   | maxSubnormal   | minNormal   | maxNormal     | rt16   | rt32   |
|--------------|-----|-----|-----|-------|-------|----------------|----------------|-------------|---------------|--------|--------|
| p3109_k3p2sf |   3 |   2 |   1 |     1 |     1 | 0.5            | 0.5            | 1           | 1.5           | True   | True   |
| ocp_e2m1     |   4 |   2 |   2 |     1 |     5 | 0.5            | 0.5            | 1           | 6             | True   | True   |
| p3109_k4p2sf |   4 |   2 |   2 |     3 |     3 | 0.25           | 0.25           | 0.5         | 3             | True   | True   |
| ocp_e2m3     |   6 |   4 |   2 |     7 |    23 | 0.125          | 0.875          | 1           | 7.5           | True   | True   |
| ocp_e3m2     |   6 |   3 |   3 |    11 |    19 | 0.0625         | 0.1875         | 0.25        | 28            | True   | True   |
| p3109_k6p3sf |   6 |   3 |   3 |    15 |    15 | 0.03125        | 0.09375        | 0.125       | 14            | True   | True   |
| p3109_k6p4sf |   6 |   4 |   2 |    15 |    15 | 0.0625         | 0.4375         | 0.5         | 3.75          | True   | True   |
| ocp_e4m3     |   8 |   4 |   4 |    55 |    70 | 2^-9           | 7/4*2^-7       | 0.015625    | 448           | True   | True   |
| ocp_e5m2     |   8 |   3 |   5 |    59 |    63 | 2^-16          | 3/2*2^-15      | 2^-14       | 57344         | True   | True   |
| p3109_k8p1se |   8 |   1 |   7 |    63 |    62 | n/a            | n/a            | 2^-63       | 2^62          | False  | True   |
| p3109_k8p1ue |   8 |   1 |   8 |   127 |   125 | n/a            | n/a            | 2^-127      | 2^125         | False  | True   |
| p3109_k8p3se |   8 |   3 |   5 |    63 |    62 | 2^-17          | 3/2*2^-16      | 2^-15       | 49152         | True   | True   |
| p3109_k8p3sf |   8 |   3 |   5 |    63 |    63 | 2^-17          | 3/2*2^-16      | 2^-15       | 57344         | True   | True   |
| p3109_k8p3ue |   8 |   3 |   6 |   127 |   125 | 2^-33          | 3/2*2^-32      | 2^-31       | 5/4*2^31      | False  | True   |
| p3109_k8p3uf |   8 |   3 |   6 |   127 |   126 | 2^-33          | 3/2*2^-32      | 2^-31       | 3/2*2^31      | False  | True   |
| p3109_k8p4se |   8 |   4 |   4 |    63 |    62 | 2^-10          | 7/4*2^-8       | 0.0078125   | 224           | True   | True   |
| p3109_k8p4sf |   8 |   4 |   4 |    63 |    63 | 2^-10          | 7/4*2^-8       | 0.0078125   | 240           | True   | True   |
| p3109_k8p4ue |   8 |   4 |   5 |   127 |   125 | 2^-18          | 7/4*2^-16      | 2^-15       | 53248         | True   | True   |
| p3109_k8p4uf |   8 |   4 |   5 |   127 |   126 | 2^-18          | 7/4*2^-16      | 2^-15       | 57344         | True   | True   |
| p3109_k8p7sf |   8 |   7 |   1 |    63 |    63 | 0.015625       | 63/32*2^-1     | 1           | 127/64*2^0    | True   | True   |
| p3109_k8p8uf |   8 |   8 |   1 |   127 |   126 | 0.0078125      | 127/64*2^-1    | 1           | 127/64*2^0    | True   | True   |
| binary16     |  16 |  11 |   5 | 15359 | 16383 | 2^-24          | 1023/512*2^-15 | 2^-14       | 65504         | True   | True   |
| bfloat16     |  16 |   8 |   8 | 16255 | 16383 | 2^-133         | 127/64*2^-127  | 2^-126      | 255/128*2^127 | False  | True   |
| ocp_e8m0     |   8 |   1 |   8 |   127 |   127 | n/a            | n/a            | 2^-127      | 2^127         | False  | True   |
| ocp_int8     |   8 |   8 |   0 |    63 |    63 | 0.015625       | 127/64*2^0     | n/a         | n/a           | True   | True   |