ubjson / universal-binary-json

Community workspace for the Universal Binary JSON Specification.
115 stars 12 forks source link

Define a Float16 type for small floating point values #44

Closed ghost closed 10 years ago

ghost commented 10 years ago

Inspired by #43 (ref: http://en.wikipedia.org/wiki/Half-precision_floating-point_format)

Half-precision floating point numbers would take 3 bytes instead of 5 bytes (40% reduction in size).

The only challenge would be representing it with a marker that makes sense - since 'H' is (high precision), I almost humorously want to make 'h' for half-precision.

d/D are already used for float32/64.

Don't know if supporting this in many platforms would be a problem, if it is, that alone would cause me to reject this idea, but if it is trivial to support and potentially offers huge space savings in certain use-cases (especially used alongside strongly typed containers) there is potentially a very big win here.

Thoughts?

edgar-bonet commented 10 years ago

Personally, I do not have any use for float16, as float32 seems to hit the sweet spot for me. However, I do not see what kind of “problems” you expect, besides the support requiring some work.

I believe the following C code should be able to “parse” a normal float16 into a regular float, irrespective of the endianness or native word-length of the platform:

#define MASK_SIGN 0x8000
#define MASK_EXPO 0x7c00
#define MASK_MANT 0x03ff
#define FIX_EXPO  0x38000000

float half_to_float(uint16_t x_bits)
{
    if (x_bits == 0) return 0;
    uint32_t y_bits = 0;
    y_bits |=  (x_bits & MASK_SIGN) << 16;
    y_bits |= ((x_bits & MASK_EXPO) << 13) + FIX_EXPO;
    y_bits |=  (x_bits & MASK_MANT) << 13;
    return *(float*)&y_bits;
}

Supporting denormals, infinities and NaNs would require more work though.

Regards.

AnyCPU commented 10 years ago

Hello,

As it is not supported directly by C++, The D Programming Language at least, I think that Float16 shall not be added to spec. Because it is slower than built-in float and double types and several libraries are available to work with this data type already. Complexity to implementations and maintaining will be added.

In custom case it is can be packed as needed at library level, not spec.

meisme commented 10 years ago

This seems like an optimization aimed at a very specific use-case and I don't think it belongs in a general data exchange format like UBJSON. Virtually no hardware exists that manipulates half precision floats, so all implementations would just have to parse it into regular floats anyhow. Since it would take extra computing time to check if floats were small enough fit in a float16 and convert them prior to writing out a file, and since storage space and bandwidth is steadily becoming cheaper, I think they would just end up as a dead part of the spec.

ghost commented 10 years ago

@AnyCPU this is exactly the insight I was looking for - if it's more work to support this in (most) other platforms negating the space win, then I'll close this out. I just didn't have enough context to make the call myself.

@meisme You are correct, it was a very specific use case.