| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
`mrb_obj_eq()` is the shortcut every equality goes through, and what it asks of two values is whether they hold the same thing. For a Float it asked whether they were equal as numbers instead, which is a different question, and only under `MRB_NO_BOXING`: the boxed builds compare the `mrb_value` itself and so read the representation. The two questions part over -0.0, which holds what 0.0 does not, and over a NaN, which is equal to no number at all, its own operand included: ```ruby z = [0.0][0] (z + 0.0).equal?(z * -1.0) # word/nan boxing false, MRB_NO_BOXING true (z + 0.0) == (z * -1.0) # true everywhere, as it should be nan = z / z nan.equal?(nan) # word/nan boxing true, MRB_NO_BOXING false ``` `equal?` now answers alike whatever the build stores a Float in, which is what a value being the object it is asks of a boxing. What a Float is equal to is untouched: `Float#==` is where that question is asked, 0.0 and -0.0 are still equal, and a NaN is still equal to nothing.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ce1cc99d-4faa-46f7-9c60-43c7a287ceed 📥 CommitsReviewing files that changed from the base of the PR and between 44ab336 and 2e8b461. 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 8 included reviews per hour; 4 remain after this review. 📝 Walkthrough WalkthroughFloat object equality now compares stored float representations. Tests document and verify identity behavior for NaN, positive zero, and negative zero. ChangesFloat identity comparison
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to 2e8b4 The change makes Float#equal? consistently compare stored bits across build modes while leaving numeric equality unchanged, with targeted tests and no actionable merge-blocking risk remaining after normal checks and review. Suggested reviewers: matz 🚥 Pre-merge checks | ✅ 5 ✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. ❤️ ShareComment @coderabbitai help to get the list of available commands. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Summary
mrb_obj_eq() asks whether two values hold the same thing, and equal? is the one caller that asks for exactly that. For a Float it asked whether they were equal as numbers instead, which is a different question, and it asked it only under MRB_NO_BOXING: the boxed builds compare the mrb_value and so read the representation. The same expression answered one way there and the other way here.
Changes
Where the two questions part
A Float holds two kinds of pair that tell the questions apart. 0.0 and -0.0 are equal as numbers and hold different bits; a NaN holds a NaN and is equal to no number at all, its own operand included. Reading them as numbers, MRB_NO_BOXING called 0.0 and -0.0 one object and said a NaN was not the same object as itself, while the boxings that keep a Float in the value read the bits and answered both the other way.
memcmp() over sizeof(mrb_float) asks the question the boxed builds answer, so equal? reads alike whatever the build stores a Float in. Float#== is untouched, and what a Float is equal to does not move with it: 0.0 == -0.0 is still true, and a NaN is still equal to nothing.
Behaviour
pzero and nzero are built at run time as z + 0.0 and z * -1.0, and nan as z / z, from z = [0.0][0], so that nothing folds them into a single literal. Bold marks where a build differs from CRuby today.
The this PR column is what all three boxings answer after the change. Measured against CRuby 4.0.6.
Speed
MRB_NO_BOXING is the only build the change reaches, so the counts below are from a MRB_NO_BOXING build of the full-core gembox:
Instruction counts as callgrind reads them, taken as Ir(2N) - Ir(N) so that startup cancels:
memcmp() over eight bytes is four instructions fewer per comparison than loading the two Floats and comparing them, so the path equal? and the == shortcut take is slightly shorter than it was. The other two rows are the same code either way.
Size
bin/mruby .text for every build in build_config/ci/gcc-clang.rb:
None of the five defines MRB_NO_BOXING, so none of them compiles the edit. The build that does is 96 bytes smaller: object.o .text reads 5,288 against master and 5,192 here, and bin/mruby the same 96 less.
Testing
rake test passes for the default build, for build_config/host-nofloat.rb, for every build in build_config/ci/gcc-clang.rb including the C++ ABI one, and for a MRB_NO_BOXING build of the full-core gembox, with no compiler warnings beyond the one -Wmaybe-uninitialized about eq in hash.c that master already emits in a MRB_NO_BOXING build.
Environment
Machine, toolchain and the compile lines these numbers were taken withThe instruction counts were taken with a full-core gembox build at MRB_NO_BOXING:
gcc -std=gnu99 -g -O3 -Wall -Wundef -Werror-implicit-function-declaration -Wwrite-strings -DMRB_NO_BOXING -DMRB_USE_BIGINT -DMRB_USE_COMPLEX -DHAVE_MRUBY_ENCODING_GEM -DMRB_UTF8_STRING -DHAVE_MRUBY_IO_GEM -DMRB_USE_RATIONAL -DHAVE_MRUBY_REGEXP_GEM -DMRB_USE_SET -DMRB_USE_TASK_SCHEDULERThe ## Size table was taken with build_config/ci/gcc-clang.rb:
cxx_abi compiles mruby as C++ with gcc -x c++ -std=gnu++03; g++ only links. full-debug is the one build at -O0, enable_debug putting -g3 -O0 after the toolchain default of -g -O3.
Summary by CodeRabbit
Bug Fixes
Documentation
Tests