Skip to content

Commit

Permalink
Handle half NaN as per standard
Browse files Browse the repository at this point in the history
  • Loading branch information
PJK committed Apr 26, 2015
1 parent 4b03a98 commit bceb5d8
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 2 deletions.
5 changes: 4 additions & 1 deletion src/cbor_encoders.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,10 @@ size_t cbor_encode_half(float value, unsigned char * buffer, size_t buffer_size)
uint8_t exp = (val & 0x7F800000) >> 23; /* 0b0111_1111_1000_0000_0000_0000_0000_0000 */
uint32_t mant = val & 0x7FFFFF; /* 0b0000_0000_0111_1111_1111_1111_1111_1111 */
if (exp == 0xFF) { /* Infinity or NaNs */
res = (val & 0x80000000) >> 16 | 0x7C00 | (mant ? 1 : 0);
if (value != value)
res = (uint16_t)0x00e700; /* Not IEEE semantics - required by CBOR [s. 3.9] */
else
res = (val & 0x80000000) >> 16 | 0x7C00 | (mant ? 1 : 0) << 15;
} else if (exp == 0x00) { /* Zeroes or subnorms */
res = (val & 0x80000000) >> 16 | (uint16_t)(mant >> 13);
} else { /* Normal numbers */
Expand Down
9 changes: 8 additions & 1 deletion test/type_7_encoders_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ static void test_half(void **state) {
assert_memory_equal(buffer, ((unsigned char[]){ 0xF9, 0x7C, 0x00 }), 3);
}

static void test_half_special(void **state)
{
assert_int_equal(3, cbor_encode_half(NAN, buffer, 512));
assert_memory_equal(buffer, ((unsigned char[]){ 0xF9, 0xE7, 0x00 }), 3);
}

static void test_float(void **state) {
assert_int_equal(5, cbor_encode_float(3.4028234663852886e+38, buffer, 512));
assert_memory_equal(buffer, ((unsigned char[]){ 0xFA, 0x7F, 0x7F, 0xFF, 0xFF }), 5);
Expand All @@ -63,7 +69,8 @@ int main(void) {
unit_test(test_break),
unit_test(test_half),
unit_test(test_float),
unit_test(test_double)
unit_test(test_double),
unit_test(test_half_special)
};
return run_tests(tests);
}

0 comments on commit bceb5d8

Please sign in to comment.