From: "nobu (Nobuyoshi Nakada)" Date: 2021-10-19T11:12:48+00:00 Subject: [ruby-core:105679] [Ruby master Bug#18187] Float#clamp() returns ArgumentError (comparison of Float with 1 failed) Issue #18187 has been updated by nobu (Nobuyoshi Nakada). What about `Float#clamp`? ```diff diff --git i/numeric.c w/numeric.c index db2b2eb2793..12edb0f6006 100644 --- i/numeric.c +++ w/numeric.c @@ -2844,6 +2844,13 @@ num_step(int argc, VALUE *argv, VALUE from) return from; } +static VALUE +flo_clamp(int argc, VALUE *argv, VALUE x) +{ + if (isnan(RFLOAT_VALUE(x))) return x; + return rb_call_super(argc, argv); +} + static char * out_of_range_float(char (*pbuf)[24], VALUE val) { @@ -5789,6 +5796,7 @@ Init_Numeric(void) rb_define_method(rb_cFloat, "finite?", rb_flo_is_finite_p, 0); rb_define_method(rb_cFloat, "next_float", flo_next_float, 0); rb_define_method(rb_cFloat, "prev_float", flo_prev_float, 0); + rb_define_method(rb_cFloat, "clamp", flo_clamp, -1); } #undef rb_float_value ``` ---------------------------------------- Bug #18187: Float#clamp() returns ArgumentError (comparison of Float with 1 failed) https://bugs.ruby-lang.org/issues/18187#change-94179 * Author: SouravGoswami (Sourav Goswami) * Status: Open * Priority: Normal * ruby -v: ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux] * Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN ---------------------------------------- When I have a Float::NAN as a number, I expect all the method to work properly. For example, `Float::NAN - 1` gives NAN. But Float::NAN.to_i raises FloatDomainError. But in case of clamp(), Float::NAN.clamp(0, 100) returns `ArgumentError (comparison of Float with 1 failed)` This error doesn't explain what's actually wrong. I didn't write the comparison to compare Float with 1. I didn't pass any invalid argument either. This error is a reflection of what's going on in the C level, which shouldn't appear to the user. If I write a vanilla clamp() in ruby: ``` Float.define_method(:clamp2) { |min, max| self < min ? min : self > max ? max : self } ``` In this case, I can call it like this: ``` > 8.0.clamp2(10, 100) => 10 > 80.0.clamp2(10, 100) => 80.0 > 800.0.clamp2(10, 100) => 100 > Float::NAN.clamp2(10, 100) => NaN ``` As you can see, it just returns NAN. But in case of the built-in clamp, it raises the ArgumentError, even though my arguments are just correct. So this should handle this clamp() correctly, either returning the min value or `Float::NAN`. -- https://bugs.ruby-lang.org/ Unsubscribe: