зеркало из https://github.com/github/ruby.git
include/ruby/internal/intern/numeric.h: add doxygen
Must not be a bad idea to improve documents. [ci skip]
This commit is contained in:
Родитель
d43accae15
Коммит
14e6e122e7
|
@ -20,22 +20,187 @@
|
|||
* extension libraries. They could be written in C++98.
|
||||
* @brief Public APIs related to ::rb_cNumeric.
|
||||
*/
|
||||
#include "ruby/internal/attr/cold.h"
|
||||
#include "ruby/internal/attr/noreturn.h"
|
||||
#include "ruby/internal/dllexport.h"
|
||||
#include "ruby/internal/value.h"
|
||||
#include "ruby/backward/2/attributes.h"
|
||||
|
||||
/**
|
||||
* @private
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
#define RB_NUM_COERCE_FUNCS_NEED_OPID 1
|
||||
|
||||
RBIMPL_SYMBOL_EXPORT_BEGIN()
|
||||
|
||||
/* numeric.c */
|
||||
NORETURN(void rb_num_zerodiv(void));
|
||||
#define RB_NUM_COERCE_FUNCS_NEED_OPID 1
|
||||
VALUE rb_num_coerce_bin(VALUE, VALUE, ID);
|
||||
VALUE rb_num_coerce_cmp(VALUE, VALUE, ID);
|
||||
VALUE rb_num_coerce_relop(VALUE, VALUE, ID);
|
||||
VALUE rb_num_coerce_bit(VALUE, VALUE, ID);
|
||||
VALUE rb_num2fix(VALUE);
|
||||
VALUE rb_fix2str(VALUE, int);
|
||||
CONSTFUNC(VALUE rb_dbl_cmp(double, double));
|
||||
|
||||
RBIMPL_ATTR_NORETURN()
|
||||
RBIMPL_ATTR_COLD()
|
||||
/**
|
||||
* Just always raises an exception.
|
||||
*
|
||||
* @exception rb_eZeroDivError Division by zero error.
|
||||
*/
|
||||
void rb_num_zerodiv(void);
|
||||
|
||||
/**
|
||||
* @name 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.
|
||||
*
|
||||
* ```ruby
|
||||
* 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`.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Coerced binary operation. This function first coerces the two objects, then
|
||||
* applies the operation.
|
||||
*
|
||||
* @param[in] lhs LHS operand.
|
||||
* @param[in] rhs RHS operand.
|
||||
* @param[in] op Operator method name.
|
||||
* @exception rb_eTypeError Coercion failed for some reason.
|
||||
* @return `lhs op rhs`, in a coerced way.
|
||||
*/
|
||||
VALUE rb_num_coerce_bin(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. `<=>`.
|
||||
*
|
||||
* @param[in] lhs LHS operand.
|
||||
* @param[in] rhs RHS operand.
|
||||
* @param[in] op Operator method name.
|
||||
* @retval RUBY_Qnil Coercion failed for some reason.
|
||||
* @retval otherwise `lhs op rhs`, in a coerced way.
|
||||
*/
|
||||
VALUE rb_num_coerce_cmp(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. `<=`.
|
||||
*
|
||||
* @param[in] lhs LHS operand.
|
||||
* @param[in] rhs RHS operand.
|
||||
* @param[in] op Operator method name.
|
||||
* @exception rb_eArgError Coercion failed for some reason.
|
||||
* @return `lhs op rhs`, in a coerced way.
|
||||
*/
|
||||
VALUE rb_num_coerce_relop(VALUE lhs, VALUE rhs, ID op);
|
||||
|
||||
/**
|
||||
* This one is optimised for bitwise operations, but the API is identical to
|
||||
* rb_num_coerce_bin().
|
||||
*
|
||||
* @param[in] lhs LHS operand.
|
||||
* @param[in] rhs RHS operand.
|
||||
* @param[in] op Operator method name.
|
||||
* @exception rb_eArgError Coercion failed for some reason.
|
||||
* @return `lhs op rhs`, in a coerced way.
|
||||
*/
|
||||
VALUE rb_num_coerce_bit(VALUE lhs, VALUE rhs, ID op);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Converts a numeric value into a Fixnum. This is not a preserving
|
||||
* conversion; for instance 1.5 would be converted into 1.
|
||||
*
|
||||
* @param[in] val A numeric object.
|
||||
* @exception rb_eTypeError No conversion from `val` to Integer.
|
||||
* @exception rb_eRangeError `val` out of range.
|
||||
* @return A fixnum converted from `val`.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* This seems used from nowhere?
|
||||
*/
|
||||
VALUE rb_num2fix(VALUE val);
|
||||
|
||||
/**
|
||||
* Generates a place-value representation of the given Fixnum, with given
|
||||
* radix.
|
||||
*
|
||||
* @param[in] val A fixnum to stringify.
|
||||
* @param[in] base `2` to `36` inclusive for each radix.
|
||||
* @exception rb_eArgError `base` is out of range.
|
||||
* @return An instance of ::rb_cString representing `val`.
|
||||
* @pre `val` must be a Fixnum (no checks performed).
|
||||
*/
|
||||
VALUE rb_fix2str(VALUE val, int base);
|
||||
|
||||
RBIMPL_ATTR_CONST()
|
||||
/**
|
||||
* Compares two `double`s. Handy when implementing a spaceship operator.
|
||||
*
|
||||
* @param[in] lhs A value.
|
||||
* @param[in] rhs Another value.
|
||||
* @retval RB_INT2FIX(-1) `lhs` is "bigger than" `rhs`.
|
||||
* @retval RB_INT2FIX(1) `rhs` is "bigger than" `lhs`.
|
||||
* @retval RB_INT2FIX(0) They are equal.
|
||||
* @retval RUBY_Qnil Not comparable, e.g. NaN.
|
||||
*/
|
||||
VALUE rb_dbl_cmp(double lhs, double rhs);
|
||||
|
||||
/**
|
||||
* Raises the passed `x` to the power of `y`.
|
||||
*
|
||||
* @note The return value can be really big.
|
||||
* @note Also the return value can be really small, in case `x` is a
|
||||
* negative number.
|
||||
* @param[in] x A number.
|
||||
* @param[in] y Another number.
|
||||
* @retval Inf Cannot express the result.
|
||||
* @retval 1 Either `y` is 0 or `x` is 1.
|
||||
* @retval otherwise An instance of ::rb_cInteger whose value is `x ** y`.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* This function returns Infinity when `y` is big enough not to fit into a
|
||||
* Fixnum. Warning is issued then.
|
||||
*/
|
||||
RUBY_EXTERN VALUE rb_int_positive_pow(long x, unsigned long y);
|
||||
|
||||
RBIMPL_SYMBOL_EXPORT_END()
|
||||
|
|
Загрузка…
Ссылка в новой задаче