diff options
author | S.H <[email protected]> | 2021-01-02 11:39:07 +0900 |
---|---|---|
committer | GitHub <[email protected]> | 2021-01-01 18:39:07 -0800 |
commit | daec5f9edcfbf98b10a4bfc1aa501c9ac2c64841 (patch) | |
tree | 584ce612193fa7b4cfd78e4013ba4de4e66a59ca /numeric.rb | |
parent | ef6ab776d55f2775957b107a3a0d8c45ece119b8 (diff) |
Improve performance some Float methods [Feature #17498] (#4018)
Notes
Notes:
Merged-By: k0kubun <[email protected]>
Diffstat (limited to 'numeric.rb')
-rw-r--r-- | numeric.rb | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/numeric.rb b/numeric.rb new file mode 100644 index 0000000000..b8b3a90d75 --- /dev/null +++ b/numeric.rb @@ -0,0 +1,207 @@ +class Integer + # call-seq: + # -int -> integer + # + # Returns +int+, negated. + def -@ + Primitive.attr! 'inline' + Primitive.cexpr! 'rb_int_uminus(self)' + end + + # call-seq: + # ~int -> integer + # + # One's complement: returns a number where each bit is flipped. + # + # Inverts the bits in an Integer. As integers are conceptually of + # infinite length, the result acts as if it had an infinite number of + # one bits to the left. In hex representations, this is displayed + # as two periods to the left of the digits. + # + # sprintf("%X", ~0x1122334455) #=> "..FEEDDCCBBAA" + def ~ + Primitive.attr! 'inline' + Primitive.cexpr! 'rb_int_comp(self)' + end + + def abs + Primitive.attr! 'inline' + Primitive.cexpr! 'rb_int_abs(self)' + end + + # call-seq: + # int.bit_length -> integer + # + # Returns the number of bits of the value of +int+. + # + # "Number of bits" means the bit position of the highest bit + # which is different from the sign bit + # (where the least significant bit has bit position 1). + # If there is no such bit (zero or minus one), zero is returned. + # + # I.e. this method returns <i>ceil(log2(int < 0 ? -int : int+1))</i>. + # + # (-2**1000-1).bit_length #=> 1001 + # (-2**1000).bit_length #=> 1000 + # (-2**1000+1).bit_length #=> 1000 + # (-2**12-1).bit_length #=> 13 + # (-2**12).bit_length #=> 12 + # (-2**12+1).bit_length #=> 12 + # -0x101.bit_length #=> 9 + # -0x100.bit_length #=> 8 + # -0xff.bit_length #=> 8 + # -2.bit_length #=> 1 + # -1.bit_length #=> 0 + # 0.bit_length #=> 0 + # 1.bit_length #=> 1 + # 0xff.bit_length #=> 8 + # 0x100.bit_length #=> 9 + # (2**12-1).bit_length #=> 12 + # (2**12).bit_length #=> 13 + # (2**12+1).bit_length #=> 13 + # (2**1000-1).bit_length #=> 1000 + # (2**1000).bit_length #=> 1001 + # (2**1000+1).bit_length #=> 1001 + # + # This method can be used to detect overflow in Array#pack as follows: + # + # if n.bit_length < 32 + # [n].pack("l") # no overflow + # else + # raise "overflow" + # end + def bit_length + Primitive.attr! 'inline' + Primitive.cexpr! 'rb_int_bit_length(self)' + end + + # call-seq: + # int.even? -> true or false + # + # Returns +true+ if +int+ is an even number. + def even? + Primitive.attr! 'inline' + Primitive.cexpr! 'rb_int_even_p(self)' + end + + # call-seq: + # int.integer? -> true + # + # Since +int+ is already an Integer, this always returns +true+. + def integer? + return true + end + + def magnitude + Primitive.attr! 'inline' + Primitive.cexpr! 'rb_int_abs(self)' + end + + # call-seq: + # int.odd? -> true or false + # + # Returns +true+ if +int+ is an odd number. + def odd? + Primitive.attr! 'inline' + Primitive.cexpr! 'rb_int_odd_p(self)' + end + + # call-seq: + # int.ord -> self + # + # Returns the +int+ itself. + # + # 97.ord #=> 97 + # + # This method is intended for compatibility to character literals + # in Ruby 1.9. + # + # For example, <code>?a.ord</code> returns 97 both in 1.8 and 1.9. + def ord + return self + end + + # call-seq: + # int.to_i -> integer + # + # Since +int+ is already an Integer, returns +self+. + # + # #to_int is an alias for #to_i. + def to_i + return self + end + + # call-seq: + # int.to_int -> integer + # + # Since +int+ is already an Integer, returns +self+. + def to_int + return self + end + + # call-seq: + # int.zero? -> true or false + # + # Returns +true+ if +int+ has a zero value. + def zero? + Primitive.attr! 'inline' + Primitive.cexpr! 'rb_int_zero_p(self)' + end +end + +class Float + # + # call-seq: + # float.to_f -> self + # + # Since +float+ is already a Float, returns +self+. + # + def to_f + return self + end + + # + # call-seq: + # float.abs -> float + # float.magnitude -> float + # + # Returns the absolute value of +float+. + # + # (-34.56).abs #=> 34.56 + # -34.56.abs #=> 34.56 + # 34.56.abs #=> 34.56 + # + # Float#magnitude is an alias for Float#abs. + # + def abs + Primitive.attr! 'inline' + Primitive.cexpr! 'rb_float_abs(self)' + end + + def magnitude + Primitive.attr! 'inline' + Primitive.cexpr! 'rb_float_abs(self)' + end + + # + # call-seq: + # -float -> float + # + # Returns +float+, negated. + # + def -@ + Primitive.attr! 'inline' + Primitive.cexpr! 'rb_float_uminus(self)' + end + + # + # call-seq: + # float.zero? -> true or false + # + # Returns +true+ if +float+ is 0.0. + # + def zero? + Primitive.attr! 'inline' + Primitive.cexpr! 'flo_iszero(self) ? Qtrue : Qfalse' + end +end |