Ruby  3.4.0dev (2024-12-06 revision 892c46283a5ea4179500d951c9d4866c0051f27b)
Macros | Functions
numeric.h File Reference

(892c46283a5ea4179500d951c9d4866c0051f27b)

Public APIs related to rb_cNumeric. More...

#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
Include dependency graph for numeric.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define RB_NUM_COERCE_FUNCS_NEED_OPID   1
 

Functions

void rb_num_zerodiv (void)
 Just always raises an exception. More...
 
VALUE rb_num2fix (VALUE val)
 Converts a numeric value into a Fixnum. More...
 
VALUE rb_fix2str (VALUE val, int base)
 Generates a place-value representation of the given Fixnum, with given radix. More...
 
VALUE rb_dbl_cmp (double lhs, double rhs)
 Compares two doubles. More...
 
VALUE rb_int_positive_pow (long x, unsigned long y)
 Raises the passed x to the power of y. More...
 
Coercion operators.

What is a coercion? Well Ruby is basically an OOPL but it also has arithmetic operators.

They are implemented in OO manners. For instance a+b is a binary operation +, whose receiver is a, and whose (sole) argument is b.

The problem is, you often want a+b == b+a to hold. That is easy if both a and b belongs to the same class... Ensuring 1 + 2 == 2 + 1 is kind of intuitive. But if you want 1.0 + 2 == 2 + 1.0, things start getting complicated. 1.0+2 is Float#+, while 2+1.0 is Integer#+. In order to achieve the equality Float's and Integer's methods must agree with their behaviours.

Now. Floats versus Integers situation is still controllable because they are both built-in. But in Ruby you can define your own numeric classes. BigDecimal, which is a rubygems gem distributed along with the interpreter, is one of such examples. Rational was another such example before. In short you cannot create list of all possible combination of the classes that could be the operand of + operator. Then how do we achieve the commutativity?

Here comes the concept of coercion. If a definition of an operator encounters an object which is unknown to the author, just assumes that the unknown object knows how to handle the situation. So for instance when 1+x has unknown x, it lets the x handle this.

class Foo
def +(x)
if we_know_what_is_x? then
... # handle here
else
y, z = x.coerce self
return y + z
end
end
end

The x.coerce method returns a 2-element array which are "casted" versions of x and self.

VALUE rb_num_coerce_bin (VALUE lhs, VALUE rhs, ID op)
 Coerced binary operation. More...
 
VALUE rb_num_coerce_cmp (VALUE lhs, VALUE rhs, ID op)
 Identical to rb_num_coerce_bin(), except for return values. More...
 
VALUE rb_num_coerce_relop (VALUE lhs, VALUE rhs, ID op)
 Identical to rb_num_coerce_cmp(), except for return values. More...
 
VALUE rb_num_coerce_bit (VALUE lhs, VALUE rhs, ID op)
 This one is optimised for bitwise operations, but the API is identical to rb_num_coerce_bin(). More...
 

Detailed Description

Public APIs related to rb_cNumeric.

Author
Ruby developers ruby-.nosp@m.core.nosp@m.@ruby.nosp@m.-lan.nosp@m.g.org
Warning
Symbols prefixed with either RBIMPL or rbimpl are implementation details. Don't take them as canon. They could rapidly appear then vanish. The name (path) of this header file is also an implementation detail. Do not expect it to persist at the place it is now. Developers are free to move it anywhere anytime at will.
Note
To ruby-core: remember that this header can be possibly recursively included from extension libraries written in C++. Do not expect for instance __VA_ARGS__ is always available. We assume C99 for ruby itself but we don't assume languages of extension libraries. They could be written in C++98.

Definition in file numeric.h.

Macro Definition Documentation

◆ RB_NUM_COERCE_FUNCS_NEED_OPID

#define RB_NUM_COERCE_FUNCS_NEED_OPID   1
Deprecated:
This macro once was a thing in the old days, but makes no sense any longer today.

Exists here for backwards compatibility only. You can safely forget about it.

Definition at line 35 of file numeric.h.

Function Documentation

◆ rb_dbl_cmp()

VALUE rb_dbl_cmp ( double  lhs,
double  rhs 
)

Compares two doubles.

Handy when implementing a spaceship operator.

Parameters
[in]lhsA value.
[in]rhsAnother value.
Return values
RB_INT2FIX(-1)lhs is "bigger than" rhs.
RB_INT2FIX(1)rhs is "bigger than" lhs.
RB_INT2FIX(0)They are equal.
RUBY_QnilNot comparable, e.g. NaN.

Definition at line 1633 of file numeric.c.

◆ rb_fix2str()

VALUE rb_fix2str ( VALUE  val,
int  base 
)

Generates a place-value representation of the given Fixnum, with given radix.

Parameters
[in]valA fixnum to stringify.
[in]base2 to 36 inclusive for each radix.
Exceptions
rb_eArgErrorbase is out of range.
Returns
An instance of rb_cString representing val.
Precondition
val must be a Fixnum (no checks performed).

Definition at line 3909 of file numeric.c.

◆ rb_int_positive_pow()

VALUE rb_int_positive_pow ( long  x,
unsigned long  y 
)

Raises the passed x to the power of y.

Note
The return value can be really big.
Also the return value can be really small, in case x is a negative number.
Parameters
[in]xA number.
[in]yAnother number.
Return values
InfCannot express the result.
1Either y is 0 or x is 1.
otherwiseAn instance of rb_cInteger whose value is x ** y.

Definition at line 4559 of file numeric.c.

Referenced by rb_flt_rationalize(), and rb_str_format().

◆ rb_num2fix()

VALUE rb_num2fix ( VALUE  val)

Converts a numeric value into a Fixnum.

This is not a preserving conversion; for instance 1.5 would be converted into 1.

Parameters
[in]valA numeric object.
Exceptions
rb_eTypeErrorNo conversion from val to Integer.
rb_eRangeErrorval out of range.
Returns
A fixnum converted from val.

Definition at line 3442 of file numeric.c.

◆ rb_num_coerce_bin()

VALUE rb_num_coerce_bin ( VALUE  lhs,
VALUE  rhs,
ID  op 
)

Coerced binary operation.

This function first coerces the two objects, then applies the operation.

Parameters
[in]lhsLHS operand.
[in]rhsRHS operand.
[in]opOperator method name.
Exceptions
rb_eTypeErrorCoercion failed for some reason.
Returns
lhs op rhs, in a coerced way.

Definition at line 477 of file numeric.c.

Referenced by rb_big_divmod(), rb_big_minus(), rb_big_modulo(), rb_big_mul(), rb_big_plus(), rb_big_pow(), rb_complex_minus(), rb_complex_mul(), rb_complex_plus(), and rb_complex_pow().

◆ rb_num_coerce_bit()

VALUE rb_num_coerce_bit ( VALUE  lhs,
VALUE  rhs,
ID  op 
)

This one is optimised for bitwise operations, but the API is identical to rb_num_coerce_bin().

Parameters
[in]lhsLHS operand.
[in]rhsRHS operand.
[in]opOperator method name.
Exceptions
rb_eArgErrorCoercion failed for some reason.
Returns
lhs op rhs, in a coerced way.

Definition at line 4987 of file numeric.c.

Referenced by rb_big_and(), rb_big_or(), and rb_big_xor().

◆ rb_num_coerce_cmp()

VALUE rb_num_coerce_cmp ( VALUE  lhs,
VALUE  rhs,
ID  op 
)

Identical to rb_num_coerce_bin(), except for return values.

This function best suits for comparison operators e.g. <=>.

Parameters
[in]lhsLHS operand.
[in]rhsRHS operand.
[in]opOperator method name.
Return values
RUBY_QnilCoercion failed for some reason.
otherwiselhs op rhs, in a coerced way.

Definition at line 484 of file numeric.c.

Referenced by rb_big_cmp().

◆ rb_num_coerce_relop()

VALUE rb_num_coerce_relop ( VALUE  lhs,
VALUE  rhs,
ID  op 
)

Identical to rb_num_coerce_cmp(), except for return values.

This function best suits for relationship operators e.g. <=.

Parameters
[in]lhsLHS operand.
[in]rhsRHS operand.
[in]opOperator method name.
Exceptions
rb_eArgErrorCoercion failed for some reason.
Returns
lhs op rhs, in a coerced way.

Definition at line 499 of file numeric.c.

◆ rb_num_zerodiv()

void rb_num_zerodiv ( void  )

Just always raises an exception.

Exceptions
rb_eZeroDivErrorDivision by zero error.

Definition at line 206 of file numeric.c.