I want to create a 16-bit float datatype, allocating memory to exponential and mantissa part at my own discretion. How can I do that?

Dani AI

Generated

For : when a 16‑bit float with exact control of every bit is required, first choose the layout (the standard IEEE‑754 binary16 is 1 sign / 5 exponent / 10 mantissa; any custom split must define bias, subnormals and special values). Two practical, robust routes are common: 1) keep a single portable 16‑bit container and implement pack/unpack and conversions to/from 32‑bit float for arithmetic, or 2) use a tested half‑precision library if available. Implementing full 16‑bit FP arithmetic from scratch is considerably more work.

A portability word about earlier suggestions: ’s bitfield struct is compact but bitfield ordering, alignment and signedness are implementation‑defined; results can change across compilers and endianness. ’s byte‑array idea is closer to portable, but the clearest, most testable representation is a single std::uint16_t combined with explicit masks and shifts.

Example packing/unpacking for IEEE binary16 (portable, deterministic layout):

#include <cstdint>

// pack 1 sign, 5 exponent, 10 mantissa into a uint16_t
static inline std::uint16_t pack16(std::uint32_t sign, std::uint32_t exp, std::uint32_t mant) {
    return std::uint16_t(((sign & 1u) << 15) | ((exp & 0x1Fu) << 10) | (mant & 0x3FFu));
}

static inline void unpack16(std::uint16_t v, std::uint32_t &sign, std::uint32_t &exp, std::uint32_t &mant) {
    sign = (v >> 15) & 1u;
    exp  = (v >> 10) & 0x1Fu;
    mant = v & 0x3FFu;
}

Conversion notes (high‑level): map exponent bias (bias16 = 15, bias32 = 127), shift mantissa bits to the 23‑bit float position, and handle three classes explicitly: zero/subnormal (exp==0), normal (0<exp<max), and inf/NaN (exp==max). Converting back requires a rounding step (round‑to‑nearest‑even), clamping to infinity on overflow, and producing subnormals or zero on underflow. Add unit tests for +/-0, subnormals, large magnitudes, infinities and NaNs, and define endianness for any serialization. For production use, prefer a well‑tested half implementation (OpenEXR’s half or a small header‑only half library) instead of ad hoc FP arithmetic.

Recommended Answers

All 4 Replies

Why do you want to do that?
you can use structures
say

struct myFloat{
    short int sign:1;
    short int expo:6;
    short int mant:11;

    float toFloat(){
        // conversion 
    }

    // overloaded arithmetic operations

    // constructors and initializations
}

hope this helps:)

I want to create a 16-bit float datatype, allocating memory to exponential and mantissa part at my own discretion. How can I do that?

Do you want a portable solution?
No: use short int (if it occupies exactly 16 bits on the target platform)...
Yes: use class TinyFloat {... unsigned char rep[2]; ...}; ...
Both cases: use bitwise operators <<, >>, &, | to pack and unpack bit fields.

Can u plz explain in a lil more detail.... I m new to bit-fields and such stuff.

Do you want a portable solution?
No: use short int (if it occupies exactly 16 bits on the target platform)...
Yes: use class TinyFloat {... unsigned char rep[2]; ...}; ...
Both cases: use bitwise operators <<, >>, &, | to pack and unpack bit fields.

Of course, you are new in bit fields and other stuff (see OP ;))
http://www.cprogramming.com/tutorial/bitwise_operators.html
http://www.learncpp.com/cpp-tutorial/38-bitwise-operators/
For example, let rep[0] is a mantissa and rep[1] represents:

bits 0..5 - binary exponent
bit6 - exponent sign
bit7 - number sign
(rep[1]&0x3F) // get exponent
(rep[1]&040)  // get exponent sign
(rep[1]&0x80) // get number sign
(negative?rep[1]|0x80:rep[1]&~0x80) // set negative
rep[1] &= ~0F0 // abs(x)

and so on.
See also operator overloading in C++.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.