Discussion about this post

User's avatar
Jeremiah's avatar

Huge thanks for writing this series!

But looks like sm7_from_offset128 contains a mistake. Excerpt from "Table of conversions from 8-bit offset-128": (Edit: sorry, looks like substack doesn't support code snippet formatting)

| hex | bin | value | u-128 | int8 | sm7 |

|------|----------|-------|---------|------|------|

| 0x81 | 10000001 | 1 | 127-128 | 0x01 | 0x81 |

This seems to suggest that 1 in offset-128 (0x81) is also represented as 0x81 in sm7. But of course the sign-magnitude representation for 1 is 0x01, as I confirmed using the "Table of 8-bit sign-magnitude values" (Oh, and looks like the u value is also wrong in the excerpt above)

| hex | bin | s | m | value |

|------|----------|---|-----|-------|

| 0x01 | 00000001 | 0 | 1 | 1 |

Looks like the implementation was intended to flip the sign bit to convert to two's-complement, then use the same conversion strategy as sm7_from_int8. But on the second reference to offset128, it was used it directly instead of the bit-flipped value. The corrected version should be

uint8_t

sm7_from_offset128( uint8_t offset128 )

{

int8_t s = (int8_t)(offset128^0x80) >> 7;

uint8_t m = ((offset128^0x80) ^ s)-s;

return (s & 0x80)|m;

}

which is just the expansion of

uint8_t

sm7_from_offset128( uint8_t offset128 )

{

return sm7_from_int8(int8_from_offset128(offset128));

}

Plugging that into the table generator, the problematic row is corrected

| hex | bin | value | u-128 | int8 | sm7 |

|------|----------|-------|---------|------|------|

| 0x81 | 10000001 | 1 | 127-128 | 0x01 | 0x01 |

Expand full comment

No posts