Ruby
3.4.0dev (2024-11-22 revision 37a72b0150ec36b4ea27175039afc28c62207b0c)
|
Public APIs related to so-called rb_cBignum. More...
#include "ruby/internal/config.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/backward/2/long_long.h"
Go to the source code of this file.
Macros | |
#define | rb_big2int(x) rb_big2long(x) |
Just another name of rb_big2long. More... | |
#define | rb_big2uint(x) rb_big2ulong(x) |
Just another name of rb_big2long. More... | |
Flags for rb_integer_pack()/rb_integer_unpack() | |
#define | INTEGER_PACK_MSWORD_FIRST 0x01 |
Stores/interprets the most significant word as the first word. More... | |
#define | INTEGER_PACK_LSWORD_FIRST 0x02 |
Stores/interprets the least significant word as the first word. More... | |
#define | INTEGER_PACK_MSBYTE_FIRST 0x10 |
Stores/interprets the most significant byte in a word as the first byte in the word. More... | |
#define | INTEGER_PACK_LSBYTE_FIRST 0x20 |
Stores/interprets the least significant byte in a word as the first byte in the word. More... | |
#define | INTEGER_PACK_NATIVE_BYTE_ORDER 0x40 |
Means either INTEGER_PACK_MSBYTE_FIRST or INTEGER_PACK_LSBYTE_FIRST, depending on the host processor's endian. More... | |
#define | INTEGER_PACK_2COMP 0x80 |
Uses 2's complement representation. More... | |
#define | INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION 0x400 |
Uses "generic" implementation (handy on test). More... | |
#define | INTEGER_PACK_FORCE_BIGNUM 0x100 |
Always generates a bignum object even if the integer can be representable using fixnum scheme (unpack only) More... | |
#define | INTEGER_PACK_NEGATIVE 0x200 |
Interprets the input as a signed negative number (unpack only). More... | |
#define | INTEGER_PACK_LITTLE_ENDIAN |
Little endian combination. More... | |
#define | INTEGER_PACK_BIG_ENDIAN |
Big endian combination. More... | |
Functions | |
VALUE | rb_big_new (size_t len, int sign) |
Allocates a bignum object. More... | |
int | rb_bigzero_p (VALUE x) |
Queries if the passed bignum instance is a "bigzero". More... | |
VALUE | rb_big_clone (VALUE num) |
Duplicates the given bignum. More... | |
void | rb_big_2comp (VALUE num) |
Destructively modify the passed bignum into 2's complement representation. More... | |
VALUE | rb_big_norm (VALUE x) |
Normalises the passed bignum. More... | |
void | rb_big_resize (VALUE big, size_t len) |
Destructively resizes the backend storage of the passed bignum. More... | |
VALUE | rb_cstr_to_inum (const char *str, int base, int badcheck) |
Parses C's string to convert into a Ruby's integer. More... | |
VALUE | rb_str_to_inum (VALUE str, int base, int badcheck) |
Identical to rb_cstr2inum(), except it takes Ruby's strings instead of C's. More... | |
VALUE | rb_cstr2inum (const char *str, int base) |
Identical to rb_cstr_to_inum(), except the second argument controls the base and badcheck at once. More... | |
VALUE | rb_str2inum (VALUE str, int base) |
Identical to rb_str_to_inum(), except the second argument controls the base and badcheck at once. More... | |
VALUE | rb_big2str (VALUE x, int base) |
Generates a place-value representation of the passed integer. More... | |
long | rb_big2long (VALUE x) |
Converts a bignum into C's long . More... | |
unsigned long | rb_big2ulong (VALUE x) |
Converts a bignum into C's unsigned long . More... | |
void | rb_big_pack (VALUE val, unsigned long *buf, long num_longs) |
Converts a bignum into a series of its parts. More... | |
VALUE | rb_big_unpack (unsigned long *buf, long num_longs) |
Constructs a (possibly very big) bignum from a series of integers. More... | |
int | rb_uv_to_utf8 (char buf[6], unsigned long uv) |
Encodes a Unicode codepoint into its UTF-8 representation. More... | |
VALUE | rb_dbl2big (double d) |
Converts a C's double into a bignum. More... | |
double | rb_big2dbl (VALUE x) |
Converts a bignum into C's double . More... | |
VALUE | rb_big_cmp (VALUE lhs, VALUE rhs) |
Compares the passed two bignums. More... | |
VALUE | rb_big_eq (VALUE lhs, VALUE rhs) |
Equality, in terms of == . More... | |
VALUE | rb_big_eql (VALUE lhs, VALUE rhs) |
Equality, in terms of eql? . More... | |
VALUE | rb_big_plus (VALUE x, VALUE y) |
Performs addition of the passed two objects. More... | |
VALUE | rb_big_minus (VALUE x, VALUE y) |
Performs subtraction of the passed two objects. More... | |
VALUE | rb_big_mul (VALUE x, VALUE y) |
Performs multiplication of the passed two objects. More... | |
VALUE | rb_big_div (VALUE x, VALUE y) |
Performs division of the passed two objects. More... | |
VALUE | rb_big_idiv (VALUE x, VALUE y) |
Performs "integer division". More... | |
VALUE | rb_big_modulo (VALUE x, VALUE y) |
Performs modulo of the passed two objects. More... | |
VALUE | rb_big_divmod (VALUE x, VALUE y) |
Performs "divmod" operation. More... | |
VALUE | rb_big_pow (VALUE x, VALUE y) |
Raises x to the powerof y . More... | |
VALUE | rb_big_and (VALUE x, VALUE y) |
Performs bitwise and of the passed two objects. More... | |
VALUE | rb_big_or (VALUE x, VALUE y) |
Performs bitwise or of the passed two objects. More... | |
VALUE | rb_big_xor (VALUE x, VALUE y) |
Performs exclusive or of the passed two objects. More... | |
VALUE | rb_big_lshift (VALUE x, VALUE y) |
Performs shift left. More... | |
VALUE | rb_big_rshift (VALUE x, VALUE y) |
Performs shift right. More... | |
int | rb_integer_pack (VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags) |
Exports an integer into a buffer. More... | |
VALUE | rb_integer_unpack (const void *words, size_t numwords, size_t wordsize, size_t nails, int flags) |
Import an integer from a buffer. More... | |
size_t | rb_absint_size (VALUE val, int *nlz_bits_ret) |
Calculates the number of bytes needed to represent the absolute value of the passed integer. More... | |
size_t | rb_absint_numwords (VALUE val, size_t word_numbits, size_t *nlz_bits_ret) |
Calculates the number of words needed represent the absolute value of the passed integer. More... | |
int | rb_absint_singlebit_p (VALUE val) |
Tests abs(val) consists only of a bit or not. More... | |
Public APIs related to so-called rb_cBignum.
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. __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 bignum.h.
#define INTEGER_PACK_2COMP 0x80 |
#define INTEGER_PACK_BIG_ENDIAN |
Big endian combination.
#define INTEGER_PACK_FORCE_BIGNUM 0x100 |
#define INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION 0x400 |
#define INTEGER_PACK_LITTLE_ENDIAN |
Little endian combination.
#define INTEGER_PACK_LSBYTE_FIRST 0x20 |
#define INTEGER_PACK_LSWORD_FIRST 0x02 |
#define INTEGER_PACK_MSBYTE_FIRST 0x10 |
#define INTEGER_PACK_MSWORD_FIRST 0x01 |
#define INTEGER_PACK_NATIVE_BYTE_ORDER 0x40 |
Means either INTEGER_PACK_MSBYTE_FIRST or INTEGER_PACK_LSBYTE_FIRST, depending on the host processor's endian.
#define INTEGER_PACK_NEGATIVE 0x200 |
#define rb_big2int | ( | x | ) | rb_big2long(x) |
Just another name of rb_big2long.
#define rb_big2uint | ( | x | ) | rb_big2ulong(x) |
Just another name of rb_big2long.
size_t rb_absint_numwords | ( | VALUE | val, |
size_t | word_numbits, | ||
size_t * | nlz_bits_ret | ||
) |
Calculates the number of words needed represent the absolute value of the passed integer.
Unlike rb_absint_size() this function can overflow. It returns (size_t)-1
then.
[in] | val | Integer or integer-like object which has #to_int method. |
[in] | word_numbits | Number of bits per word. |
[out] | nlz_bits_ret | Number of leading zero bits in the most significant word is returned if not NULL . |
rb_eTypeError | val doesn't respond to #to_int . |
(size_t)-1 | Overflowed. |
otherwise | ((val_numbits * CHAR_BIT + word_numbits - 1) / word_numbits) , where val_numbits is the number of bits of abs(val) . |
nlz_bits_ret
is not NULL
and there is no overflow, (return_value * word_numbits - val_numbits)
is stored in *nlz_bits_ret
. In this case, 0 <= *nlz_bits_ret < word_numbits.
Definition at line 3424 of file bignum.c.
Referenced by rb_big_pow(), and rb_str_format().
int rb_absint_singlebit_p | ( | VALUE | val | ) |
Tests abs(val)
consists only of a bit or not.
[in] | val | Integer or integer-like object which has #to_int method. |
rb_eTypeError | val doesn't respond to #to_int . |
1 | abs(val) == 1 << n for some n >= 0 . |
0 | Otherwise. |
rb_absint_singlebit_p() can be used to determine required buffer size for rb_integer_pack() used with INTEGER_PACK_2COMP (two's complement).
Following example calculates number of bits required to represent val in two's complement number, without sign bit.
Following example calculates number of bytes required to represent val in two's complement number, with sign bit.
Definition at line 3487 of file bignum.c.
Referenced by rb_str_format().
size_t rb_absint_size | ( | VALUE | val, |
int * | nlz_bits_ret | ||
) |
Calculates the number of bytes needed to represent the absolute value of the passed integer.
[in] | val | Integer or integer-like object which has #to_int method. |
[out] | nlz_bits_ret | Number of leading zero bits in the most significant byte is returned if not NULL . |
rb_eTypeError | val doesn't respond to #to_int . |
((val_numbits * CHAR_BIT + CHAR_BIT - 1) / CHAR_BIT)
, where val_numbits is the number of bits of abs(val)
. nlz_bits_ret
is not NULL
, (return_value * CHAR_BIT - val_numbits)
is stored in *nlz_bits_ret
. In this case, 0 <= *nlz_bits_ret < CHAR_BIT
.This function should not overflow.
Definition at line 3289 of file bignum.c.
Referenced by rb_absint_numwords().
double rb_big2dbl | ( | VALUE | x | ) |
Converts a bignum into C's double
.
[in] | x | A bignum. |
double
. Definition at line 5346 of file bignum.c.
Referenced by rb_big_minus(), rb_big_mul(), rb_big_plus(), and rb_big_pow().
long rb_big2long | ( | VALUE | x | ) |
Converts a bignum into C's long
.
[in] | x | A bignum. |
rb_eRangeError | x is out of range of long . |
long
. Definition at line 5176 of file bignum.c.
Referenced by rb_num2long().
Generates a place-value representation of the passed integer.
[in] | x | An integer to stringify. |
[in] | base | 2 to 36 inclusive for each radix. |
rb_eArgError | base is out of range. |
rb_eRangeError | x is too big, cannot represent in string. |
x
. Definition at line 5127 of file bignum.c.
Referenced by rb_str_format().
unsigned long rb_big2ulong | ( | VALUE | x | ) |
void rb_big_2comp | ( | VALUE | num | ) |
Performs bitwise and of the passed two objects.
[in] | x | A bignum. |
[in] | y | Arbitrary ruby object. |
x & y
evaluates to. Compares the passed two bignums.
[in] | lhs | Comparison LHS. |
[in] | rhs | Comparison RHS. |
-1 | rhs is bigger than lhs . |
0 | They are identical. |
1 | lhs is bigger than rhs . |
Performs division of the passed two objects.
[in] | x | A bignum. |
[in] | y | Arbitrary ruby object. |
x / y
evaluates to. Performs "divmod" operation.
The operation in bignum's context is that it calculates rb_big_idiv() and rb_big_modulo() at once.
[in] | x | A bignum. |
[in] | y | Arbitrary ruby object. |
x.divmod y
evaluates to. Equality, in terms of eql?
.
Unlike rb_big_eq() it does not convert rb_cFloat etc. This function returns RUBY_Qtrue if and only if both parameters are bignums, which represent the identical numerical value.
[in] | lhs | Comparison LHS. |
[in] | rhs | Comparison RHS. |
RUBY_Qtrue | They are identical. |
RUBY_Qfalse | They are distinct. |
Performs "integer division".
This is different from rb_big_div().
[in] | x | A bignum. |
[in] | y | Arbitrary ruby object. |
x.div y
evaluates to. Performs subtraction of the passed two objects.
[in] | x | A bignum. |
[in] | y | Arbitrary ruby object. |
x - y
evaluates to. Performs modulo of the passed two objects.
[in] | x | A bignum. |
[in] | y | Arbitrary ruby object. |
x % y
evaluates to. Performs multiplication of the passed two objects.
[in] | x | A bignum. |
[in] | y | Arbitrary ruby object. |
x * y
evaluates to. VALUE rb_big_new | ( | size_t | len, |
int | sign | ||
) |
Performs bitwise or of the passed two objects.
[in] | x | A bignum. |
[in] | y | Arbitrary ruby object. |
x | y
evaluates to. void rb_big_pack | ( | VALUE | val, |
unsigned long * | buf, | ||
long | num_longs | ||
) |
Converts a bignum into a series of its parts.
[in] | val | An integer. |
[out] | buf | Return buffer. |
[in] | num_longs | Number of words of buf . |
rb_eTypeError | val doesn't respond to #to_int . |
buf
is filled with val
's 2's complement representation, in the host CPU's native byte order, from least significant word towards the most significant one, for num_longs
words. Array#pack
. Performs addition of the passed two objects.
[in] | x | A bignum. |
[in] | y | Arbitrary ruby object. |
x + y
evaluates to. Raises x
to the powerof y
.
[in] | x | A bignum. |
[in] | y | Arbitrary ruby object. |
x ** y
evaluates to. x
and y
are bignums. Or an instance of rb_cRational, when for instance y
is negative. void rb_big_resize | ( | VALUE | big, |
size_t | len | ||
) |
VALUE rb_big_unpack | ( | unsigned long * | buf, |
long | num_longs | ||
) |
Constructs a (possibly very big) bignum from a series of integers.
buf[0]
would be the return value's least significant word; buf[num_longs-1]
would be that of most significant.
[in] | buf | A series of integers. |
[in] | num_longs | Number of words of buf . |
rb_eArgError | Result would be too big. |
String#pack
. Performs exclusive or of the passed two objects.
[in] | x | A bignum. |
[in] | y | Arbitrary ruby object. |
x ^ y
evaluates to. int rb_bigzero_p | ( | VALUE | x | ) |
Queries if the passed bignum instance is a "bigzero".
What is a bigzero? Well, bignums are for very big integers, but can also represent tiny ones like -1, 0, 1. Bigzero are instances of bignums whose values are zero. Knowing if a bignum is bigzero can be handy on occasions, like for instance detecting division by zero situation.
[in] | x | A bignum. |
1 | It is a bigzero. |
0 | Otherwise. |
VALUE rb_cstr2inum | ( | const char * | str, |
int | base | ||
) |
Identical to rb_cstr_to_inum(), except the second argument controls the base and badcheck at once.
It basically doesn't raise for parse errors, unless the base is zero.
This is an older API. New codes might prefer rb_cstr_to_inum().
[in] | str | Stringised representation of the return value. |
[in] | base | Base of conversion. Must be -36..36 inclusive, except 1 . 2..36 means the conversion is done according to it, with unmatched prefix understood as a part of the result. -36..-2 means the conversion honours prefix when present, or use -base when absent. 0 is equivalent to -10 . -1 mandates a prefix. 1 is an error. |
rb_eArgError | Failed to parse (and base is zero). |
str
. VALUE rb_cstr_to_inum | ( | const char * | str, |
int | base, | ||
int | badcheck | ||
) |
Parses C's string to convert into a Ruby's integer.
It understands prefixes (e.g. 0x
) and underscores.
[in] | str | Stringised representation of the return value. |
[in] | base | Base of conversion. Must be -36..36 inclusive, except 1 . 2..36 means the conversion is done according to it, with unmatched prefix understood as a part of the result. -36..-2 means the conversion honours prefix when present, or use -base when absent. 0 is equivalent to -10 . -1 mandates a prefix. 1 is an error. |
[in] | badcheck | Whether to raise rb_eArgError on failure. If 0 is passed here this function can return INT2FIX(0) for parse errors. |
rb_eArgError | Failed to parse (and badcheck is truthy). |
str
. Definition at line 4051 of file bignum.c.
Referenced by rb_cstr2inum().
VALUE rb_dbl2big | ( | double | d | ) |
Converts a C's double
into a bignum.
[in] | d | A value to convert. |
rb_eFloatDomainError | d is Inf/NaN. |
d
. Definition at line 5285 of file bignum.c.
Referenced by rb_str_format().
int rb_integer_pack | ( | VALUE | val, |
void * | words, | ||
size_t | numwords, | ||
size_t | wordsize, | ||
size_t | nails, | ||
int | flags | ||
) |
Exports an integer into a buffer.
This function fills the buffer specified by words
and numwords
as val
in the format specified by wordsize
, nails
and flags
.
[in] | val | Integer or integer-like object which has #to_int method. |
[out] | words | Return buffer. |
[in] | numwords | Number of words of words . |
[in] | wordsize | Number of bytes per word. |
[in] | nails | Number of padding bits in a word. Most significant nails bits of each word are filled by zero. |
[in] | flags | Bitwise or of constants whose name starts "INTEGER_PACK_". |
rb_eTypeError | val doesn't respond to #to_int . |
Possible flags are:
INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_LSBYTE_FIRST
.INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_MSBYTE_FIRST
.This function fills the buffer specified by words
as val
's 2's complement representation if INTEGER_PACK_2COMP is specified in flags
. Otherwise it fills words
as abs(val)
and signedness is returned via the return value.
When INTEGER_PACK_2COMP is not specified:
-2
: Negative overflow. val <= -2**(numwords*(wordsize*CHAR_BIT-nails))
-1
: Negative without overflow. -2**(numwords*(wordsize*CHAR_BIT-nails)) < val < 0
0
: zero. val == 0
1
: Positive without overflow. 0 < val < 2**(numwords*(wordsize*CHAR_BIT-nails))
2
: Positive overflow. 2**(numwords*(wordsize*CHAR_BIT-nails)) <= val
When INTEGER_PACK_2COMP is specified:
-2
: Negative overflow. val < -2**(numwords*(wordsize*CHAR_BIT-nails))
-1
: Negative without overflow. -2**(numwords*(wordsize*CHAR_BIT-nails)) <= val < 0
0
: zero. val == 0
1
: Positive without overflow. 0 < val < 2**(numwords*(wordsize*CHAR_BIT-nails))
2
: Positive overflow. 2**(numwords*(wordsize*CHAR_BIT-nails)) <= val
The value, -2**(numwords*(wordsize*CHAR_BIT-nails))
, is representable in 2's complement representation but not representable in absolute value. So -1
is returned for the value if INTEGER_PACK_2COMP is specified but returns -2
if INTEGER_PACK_2COMP is not specified.
The least significant words are filled in the buffer when overflow occur.
Definition at line 3588 of file bignum.c.
Referenced by rb_big_pack(), and rb_str_format().
VALUE rb_integer_unpack | ( | const void * | words, |
size_t | numwords, | ||
size_t | wordsize, | ||
size_t | nails, | ||
int | flags | ||
) |
Import an integer from a buffer.
[in] | words | Buffer to import. |
[in] | numwords | Number of words of words . |
[in] | wordsize | Number of bytes per word. |
[in] | nails | Number of padding bits in a word. Most significant nails bits of each word are ignored. |
[in] | flags | Bitwise or of constants whose name starts "INTEGER_PACK_". |
rb_eArgError | numwords * wordsize too big. |
Possible flags are:
INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_LSBYTE_FIRST
INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_MSBYTE_FIRST
words
. The range of the result value depends on INTEGER_PACK_2COMP and INTEGER_PACK_NEGATIVE.When INTEGER_PACK_2COMP is not set:
0 <= val < 2**(numwords*(wordsize*CHAR_BIT-nails))
if !INTEGER_PACK_NEGATIVE
-2**(numwords*(wordsize*CHAR_BIT-nails)) < val <= 0
if INTEGER_PACK_NEGATIVE
When INTEGER_PACK_2COMP is set:
-2**(numwords*(wordsize*CHAR_BIT-nails)-1)
<= val <=
2**(numwords*(wordsize*CHAR_BIT-nails)-1)-1
if !INTEGER_PACK_NEGATIVE
-2**(numwords*(wordsize*CHAR_BIT-nails)) <= val <= -1
if INTEGER_PACK_NEGATIVE
Passing INTEGER_PACK_2COMP without INTEGER_PACK_NEGATIVE means sign extension. INTEGER_PACK_2COMP with INTEGER_PACK_NEGATIVE means assuming the higher bits are 1
.
Note that this function returns 0 when numwords
is zero and INTEGER_PACK_2COMP is set but INTEGER_PACK_NEGATIVE is not set.
Definition at line 3674 of file bignum.c.
Referenced by rb_big_unpack().
Identical to rb_str_to_inum(), except the second argument controls the base and badcheck at once.
It can also be seen as a routine identical to rb_cstr2inum(), except it takes Ruby's strings instead of C's.
This is an older API. New codes might prefer rb_cstr_to_inum().
[in] | str | Stringised representation of the return value. |
[in] | base | Base of conversion. Must be -36..36 inclusive, except 1 . 2..36 means the conversion is done according to it, with unmatched prefix understood as a part of the result. -36..-2 means the conversion honours prefix when present, or use -base when absent. 0 is equivalent to -10 . -1 mandates a prefix. 1 is an error. |
rb_eArgError | Failed to parse (and base is zero). |
rb_eTypeError | str is not a string. |
rb_eEncCompatError | str is not ASCII compatible. |
str
. Identical to rb_cstr2inum(), except it takes Ruby's strings instead of C's.
[in] | str | Stringised representation of the return value. |
[in] | base | Base of conversion. Must be -36..36 inclusive, except 1 . 2..36 means the conversion is done according to it, with unmatched prefix understood as a part of the result. -36..-2 means the conversion honours prefix when present, or use -base when absent. 0 is equivalent to -10 . -1 mandates a prefix. 1 is an error. |
[in] | badcheck | Whether to raise rb_eArgError on failure. If 0 is passed here this function can return INT2FIX(0) for parse errors. |
rb_eArgError | Failed to parse (and badcheck is truthy). |
rb_eTypeError | str is not a string. |
rb_eEncCompatError | str is not ASCII compatible. |
str
. Definition at line 4308 of file bignum.c.
Referenced by rb_str2inum(), and rb_str_format().
int rb_uv_to_utf8 | ( | char | buf[6], |
unsigned long | uv | ||
) |
Encodes a Unicode codepoint into its UTF-8 representation.
[out] | buf | Return buffer, must at least be 6 bytes width. |
[in] | uv | An Unicode codepoint. |
rb_eRangeError | uv is out of Unicode. |
buf
buf
holds a UTF-8 representation of uv
.