Skip to content

Ignore bits above a microfloat's width - #36

Merged
AntonOresten merged 1 commit into
mainfrom
raw-bits
Oct 21, 2026
Merged

AntonOresten merged 1 commit into
mainfrom
raw-bits

Conversation

@AntonOresten

Copy link
Copy Markdown
Member

reinterpret(Float4_E2M1FN, 0x13) sets bits above the format's four. Twiddles and table lookups already masked them, but other code read the whole byte:

  • show and cvt_generic indexed the tables generated by @microfloat with the whole byte, so they threw BoundsError.
  • isnan, iszero, issubnormal, abs, nextfloat, == and others treated those bits as part of the value.

Changes

  • Reads: every read of a microfloat's bits goes through an internal raw_bits(x), which masks to bitwidth(T). reinterpret(Unsigned, x) returns the same.
  • Constructions: every construction goes through from_raw_bits(T, bits). These two helpers are the only places a later switch to primitive types declared with their real width (Julia 1.14, core: support odd-bit primitive integers, add Core.bitsizeof JuliaLang/julia#61359) would need to change.
  • CUDA extension: its private lane_bits was the same mask, so it now uses raw_bits.
  • Docs: the Microfloat docstring says the bits above the width are ignored. The exception is ===, which still compares the whole byte.

Behavior change: nextfloat/prevfloat at ±floatmax

On formats without Inf, these stepped past ±floatmax:

  • into bits above the width (Float6_*);
  • onto the sign bit (Float4_E2M1FN, so nextfloat(floatmax) was -0.0);
  • to NaN (the FN formats).

They now stop at ±floatmax, the same way they stop at ±Inf on formats that have it. For the FN formats this changes a valid result (it was NaN, now floatmax), matching Base, where nextfloat never steps from a finite value to NaN.

Testing

  • New test/high_bits.jl covers every sub-byte type in the suite:
    • setting bits above the width changes no result;
    • no operation produces such bits;
    • nextfloat/prevfloat stop at the ends.
  • Against the code before this PR, the new file gives about 1,600 failures and 2,900 errors.
  • Full suite passes locally: 83,470/83,470 on Julia 1.10, 1.13 and 1.14.0-alpha1. That's 50,596 existing tests plus the new ones.
  • Generated code is unchanged for valid values. LLVM for the conversions and checks I compared matches Faster microfloat conversions: generated bit-twiddles and branch-free narrowing #35 instruction for instruction, including the vectorized widening loop.

🤖 Generated with Claude Code

`reinterpret(Float4_E2M1FN, 0x13)` sets bits above the format's four.
Twiddles and lookups masked them, but `show` and `cvt_generic` indexed
their tables with the whole byte (BoundsError), and `isnan`, `iszero`,
`issubnormal`, `abs`, `nextfloat` and others read them as value bits.

Every read now goes through `raw_bits`, which masks to `bitwidth(T)`,
and every construction through `from_raw_bits`, so primitive types
declared with their real width (Julia 1.14) would change only these two.
Generated code is unchanged for valid values.

`nextfloat` and `prevfloat` stepped past ±floatmax on types without
Inf: into bits above the width (Float6_*), onto the sign bit
(Float4_E2M1FN, giving -0.0), or to NaN (the FN types). They now stop
there, as they stop at ±Inf on the others.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.04%. Comparing base (46108af) to head (feb4cd0).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #36      +/-   ##
==========================================
+ Coverage   86.03%   87.04%   +1.00%     
==========================================
  Files          14       14              
  Lines         659      664       +5     
==========================================
+ Hits          567      578      +11     
+ Misses         92       86       -6     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@AntonOresten
AntonOresten merged commit ac5234a into main Oct 21, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant