Zakir032002 commented on PR #3329:
URL: https://github.com/apache/fory/pull/3329#issuecomment-3950638059
hey @asadjan4611, went through `bfloat16.pyx` — two bugs here
**NaN becomes Infinity**
for a signaling NaN like `0x7F800001`:
```
bf16_bits = 0x7F800001 >> 16 → 0x7F80
truncated = 0x7F800001 & 0xFFFF → 0x0001
0x0001 > 0x8000 → false, no rounding fires
returns 0x7F80 → Infinity, not NaN
```
fix — add NaN passthrough at the top (also note: `cdef` inside `if` block is
illegal in Cython, all declarations go at function top):
```cython
cdef inline uint16_t float32_to_bfloat16_bits(float value) nogil:
cdef uint32_t f32_bits
cdef uint16_t bf16_bits
cdef uint16_t truncated
memcpy(&f32_bits, &value, 4)
if (f32_bits & 0x7FFFFFFF) > 0x7F800000:
return (<uint16_t>(f32_bits >> 16)) | 0x0040
bf16_bits = <uint16_t>(f32_bits >> 16)
truncated = <uint16_t>(f32_bits & 0xFFFF)
if truncated > 0x8000:
bf16_bits += 1
elif truncated == 0x8000 and (bf16_bits & 1):
bf16_bits += 1
return bf16_bits
```
**`__hash__` breaks the eq contract for ±0**
`__eq__` returns `True` for `+0 == -0` but `hash(0x0000) != hash(0x8000)` —
python requires equal objects to have equal hashes, so `{bfloat16(0.0),
bfloat16(-0.0)}` silently gives 2 elements instead of 1.
```cython
def __hash__(self):
if (self._bits & 0x7FFF) == 0:
return hash(0)
return hash(self._bits)
```
Happy to discuss if im misreading the flow here
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]