Ruby: internal/bignum.h Source File

Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)

bignum.h
Go to the documentation of this file.
1#ifndef INTERNAL_BIGNUM_H /*-*-C-*-vi:se ft=c:*/
2#define INTERNAL_BIGNUM_H
12#include "ruby/internal/config.h" /* for HAVE_LIBGMP */
13#include <stddef.h> /* for size_t */
14
15#ifdef HAVE_SYS_TYPES_H
16# include <sys/types.h> /* for ssize_t (note: on Windows ssize_t is */
17#endif /* `#define`d in ruby/config.h) */
18
19#include "ruby/internal/stdbool.h" /* for bool */
20#include "ruby/ruby.h" /* for struct RBasic */
21
22#ifndef BDIGIT
23# if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
24# define BDIGIT unsigned int
25# define SIZEOF_BDIGIT SIZEOF_INT
26# define BDIGIT_DBL unsigned LONG_LONG
27# define BDIGIT_DBL_SIGNED LONG_LONG
28# define PRI_BDIGIT_PREFIX ""
29# define PRI_BDIGIT_DBL_PREFIX PRI_LL_PREFIX
30# elif SIZEOF_INT*2 <= SIZEOF_LONG
31# define BDIGIT unsigned int
32# define SIZEOF_BDIGIT SIZEOF_INT
33# define BDIGIT_DBL unsigned long
34# define BDIGIT_DBL_SIGNED long
35# define PRI_BDIGIT_PREFIX ""
36# define PRI_BDIGIT_DBL_PREFIX "l"
37# elif SIZEOF_SHORT*2 <= SIZEOF_LONG
38# define BDIGIT unsigned short
39# define SIZEOF_BDIGIT SIZEOF_SHORT
40# define BDIGIT_DBL unsigned long
41# define BDIGIT_DBL_SIGNED long
42# define PRI_BDIGIT_PREFIX "h"
43# define PRI_BDIGIT_DBL_PREFIX "l"
44# else
45# define BDIGIT unsigned short
46# define SIZEOF_BDIGIT (SIZEOF_LONG/2)
47# define SIZEOF_ACTUAL_BDIGIT SIZEOF_LONG
48# define BDIGIT_DBL unsigned long
49# define BDIGIT_DBL_SIGNED long
50# define PRI_BDIGIT_PREFIX "h"
51# define PRI_BDIGIT_DBL_PREFIX "l"
52# endif
53#endif
54
55#ifndef SIZEOF_ACTUAL_BDIGIT
56# define SIZEOF_ACTUAL_BDIGIT SIZEOF_BDIGIT
57#endif
58
59#ifdef PRI_BDIGIT_PREFIX
60# define PRIdBDIGIT PRI_BDIGIT_PREFIX"d"
61# define PRIiBDIGIT PRI_BDIGIT_PREFIX"i"
62# define PRIoBDIGIT PRI_BDIGIT_PREFIX"o"
63# define PRIuBDIGIT PRI_BDIGIT_PREFIX"u"
64# define PRIxBDIGIT PRI_BDIGIT_PREFIX"x"
65# define PRIXBDIGIT PRI_BDIGIT_PREFIX"X"
66#endif
67
68#ifdef PRI_BDIGIT_DBL_PREFIX
69# define PRIdBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"d"
70# define PRIiBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"i"
71# define PRIoBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"o"
72# define PRIuBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"u"
73# define PRIxBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"x"
74# define PRIXBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"X"
75#endif
76
77#define RBIGNUM(obj) ((struct RBignum *)(obj))
78#define BIGNUM_SIGN_BIT FL_USER1
79#define BIGNUM_EMBED_FLAG ((VALUE)FL_USER2)
80#define BIGNUM_EMBED_LEN_NUMBITS 3
81#define BIGNUM_EMBED_LEN_MASK \
82 (~(~(VALUE)0U << BIGNUM_EMBED_LEN_NUMBITS) << BIGNUM_EMBED_LEN_SHIFT)
83#define BIGNUM_EMBED_LEN_SHIFT \
84 (FL_USHIFT+3) /* bit offset of BIGNUM_EMBED_LEN_MASK */
85#ifndef BIGNUM_EMBED_LEN_MAX
86# if (SIZEOF_VALUE*RVALUE_EMBED_LEN_MAX/SIZEOF_ACTUAL_BDIGIT) < (1 << BIGNUM_EMBED_LEN_NUMBITS)-1
87# define BIGNUM_EMBED_LEN_MAX (SIZEOF_VALUE*RVALUE_EMBED_LEN_MAX/SIZEOF_ACTUAL_BDIGIT)
88# else
89# define BIGNUM_EMBED_LEN_MAX ((1 << BIGNUM_EMBED_LEN_NUMBITS)-1)
90# endif
91#endif
92
93 enum rb_int_parse_flags {
94 RB_INT_PARSE_SIGN = 0x01,
95 RB_INT_PARSE_UNDERSCORE = 0x02,
96 RB_INT_PARSE_PREFIX = 0x04,
97 RB_INT_PARSE_ALL = 0x07,
98 RB_INT_PARSE_DEFAULT = 0x07,
99};
100
101 struct RBignum {
102 struct RBasic basic;
103 union {
104 struct {
105 size_t len;
106 BDIGIT *digits;
107 } heap;
108 BDIGIT ary[BIGNUM_EMBED_LEN_MAX];
109 } as;
110};
111
112/* bignum.c */
113extern const char ruby_digitmap[];
114double rb_big_fdiv_double(VALUE x, VALUE y);
115 VALUE rb_big_uminus(VALUE x);
116 VALUE rb_big_hash(VALUE);
117 VALUE rb_big_odd_p(VALUE);
118 VALUE rb_big_even_p(VALUE);
119size_t rb_big_size(VALUE);
120 VALUE rb_integer_float_cmp(VALUE x, VALUE y);
121 VALUE rb_integer_float_eq(VALUE x, VALUE y);
122 VALUE rb_str_convert_to_inum(VALUE str, int base, int badcheck, int raise_exception);
123 VALUE rb_big_comp(VALUE x);
124 VALUE rb_big_aref(VALUE x, VALUE y);
125 VALUE rb_big_abs(VALUE x);
126 VALUE rb_big_size_m(VALUE big);
127 VALUE rb_big_bit_length(VALUE big);
128 VALUE rb_big_remainder(VALUE x, VALUE y);
129 VALUE rb_big_gt(VALUE x, VALUE y);
130 VALUE rb_big_ge(VALUE x, VALUE y);
131 VALUE rb_big_lt(VALUE x, VALUE y);
132 VALUE rb_big_le(VALUE x, VALUE y);
133 VALUE rb_int_powm(int const argc, VALUE * const argv, VALUE const num);
134static inline bool BIGNUM_SIGN(VALUE b);
135static inline bool BIGNUM_POSITIVE_P(VALUE b);
136static inline bool BIGNUM_NEGATIVE_P(VALUE b);
137static inline void BIGNUM_SET_SIGN(VALUE b, bool sign);
138static inline void BIGNUM_NEGATE(VALUE b);
139static inline size_t BIGNUM_LEN(VALUE b);
140static inline BDIGIT *BIGNUM_DIGITS(VALUE b);
141static inline int BIGNUM_LENINT(VALUE b);
142static inline bool BIGNUM_EMBED_P(VALUE b);
143
144RUBY_SYMBOL_EXPORT_BEGIN
145/* bignum.c (export) */
146 VALUE rb_big_mul_normal(VALUE x, VALUE y);
147 VALUE rb_big_mul_balance(VALUE x, VALUE y);
148 VALUE rb_big_mul_karatsuba(VALUE x, VALUE y);
149 VALUE rb_big_mul_toom3(VALUE x, VALUE y);
150 VALUE rb_big_sq_fast(VALUE x);
151 VALUE rb_big_divrem_normal(VALUE x, VALUE y);
152 VALUE rb_big2str_poweroftwo(VALUE x, int base);
153 VALUE rb_big2str_generic(VALUE x, int base);
154 VALUE rb_str2big_poweroftwo(VALUE arg, int base, int badcheck);
155 VALUE rb_str2big_normal(VALUE arg, int base, int badcheck);
156 VALUE rb_str2big_karatsuba(VALUE arg, int base, int badcheck);
157#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
158 VALUE rb_big_mul_gmp(VALUE x, VALUE y);
159 VALUE rb_big_divrem_gmp(VALUE x, VALUE y);
160 VALUE rb_big2str_gmp(VALUE x, int base);
161 VALUE rb_str2big_gmp(VALUE arg, int base, int badcheck);
162#endif
163 VALUE rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits, int base, int flags);
164RUBY_SYMBOL_EXPORT_END
165
166 MJIT_SYMBOL_EXPORT_BEGIN
167#if defined(HAVE_INT128_T)
168 VALUE rb_int128t2big(int128_t n);
169#endif
170 MJIT_SYMBOL_EXPORT_END
171
172/* sign: positive:1, negative:0 */
173static inline bool
174BIGNUM_SIGN(VALUE b)
175{
176 return FL_TEST_RAW(b, BIGNUM_SIGN_BIT);
177}
178
179static inline bool
180BIGNUM_POSITIVE_P(VALUE b)
181{
182 return BIGNUM_SIGN(b);
183}
184
185static inline bool
186BIGNUM_NEGATIVE_P(VALUE b)
187{
188 return ! BIGNUM_POSITIVE_P(b);
189}
190
191static inline void
192BIGNUM_SET_SIGN(VALUE b, bool sign)
193{
194 if (sign) {
195 FL_SET_RAW(b, BIGNUM_SIGN_BIT);
196 }
197 else {
198 FL_UNSET_RAW(b, BIGNUM_SIGN_BIT);
199 }
200}
201
202static inline void
203BIGNUM_NEGATE(VALUE b)
204{
205 FL_REVERSE_RAW(b, BIGNUM_SIGN_BIT);
206}
207
208static inline size_t
209BIGNUM_LEN(VALUE b)
210{
211 if (! BIGNUM_EMBED_P(b)) {
212 return RBIGNUM(b)->as.heap.len;
213 }
214 else {
215 size_t ret = RBASIC(b)->flags;
216 ret &= BIGNUM_EMBED_LEN_MASK;
217 ret >>= BIGNUM_EMBED_LEN_SHIFT;
218 return ret;
219 }
220}
221
222static inline int
223BIGNUM_LENINT(VALUE b)
224{
225 return rb_long2int(BIGNUM_LEN(b));
226}
227
228/* LSB:BIGNUM_DIGITS(b)[0], MSB:BIGNUM_DIGITS(b)[BIGNUM_LEN(b)-1] */
229static inline BDIGIT *
230BIGNUM_DIGITS(VALUE b)
231{
232 if (BIGNUM_EMBED_P(b)) {
233 return RBIGNUM(b)->as.ary;
234 }
235 else {
236 return RBIGNUM(b)->as.heap.digits;
237 }
238}
239
240static inline bool
241BIGNUM_EMBED_P(VALUE b)
242{
243 return FL_TEST_RAW(b, BIGNUM_EMBED_FLAG);
244}
245
246#endif /* INTERNAL_BIGNUM_H */
BDIGIT
#define BDIGIT
Definition: bigdecimal.h:48
MJIT_SYMBOL_EXPORT_END
#define MJIT_SYMBOL_EXPORT_END
Definition: dllexport.h:63
MJIT_SYMBOL_EXPORT_BEGIN
#define MJIT_SYMBOL_EXPORT_BEGIN
Definition: dllexport.h:62
num
big_t * num
Definition: enough.c:232
len
uint8_t len
Definition: escape.c:17
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
FL_UNSET_RAW
#define FL_UNSET_RAW
Definition: fl_type.h:133
FL_REVERSE_RAW
#define FL_REVERSE_RAW
Definition: fl_type.h:127
FL_TEST_RAW
#define FL_TEST_RAW
Definition: fl_type.h:131
FL_SET_RAW
#define FL_SET_RAW
Definition: fl_type.h:129
config.h
Thin wrapper to ruby/config.h.
rb_big_even_p
VALUE rb_big_even_p(VALUE)
Definition: bignum.c:6837
rb_big_size
size_t rb_big_size(VALUE)
Definition: bignum.c:6775
rb_integer_float_eq
VALUE rb_integer_float_eq(VALUE x, VALUE y)
Definition: bignum.c:5383
rb_big_hash
VALUE rb_big_hash(VALUE)
Definition: bignum.c:6723
rb_big_fdiv_double
double rb_big_fdiv_double(VALUE x, VALUE y)
Definition: bignum.c:6206
rb_big2str_generic
VALUE rb_big2str_generic(VALUE x, int base)
Definition: bignum.c:5004
rb_big_mul_toom3
VALUE rb_big_mul_toom3(VALUE x, VALUE y)
Definition: bignum.c:2277
rb_big_comp
VALUE rb_big_comp(VALUE x)
Definition: bignum.c:5561
BIGNUM_EMBED_LEN_MAX
#define BIGNUM_EMBED_LEN_MAX
Definition: bignum.h:89
rb_big_sq_fast
VALUE rb_big_sq_fast(VALUE x)
Definition: bignum.c:1640
rb_big2str_poweroftwo
VALUE rb_big2str_poweroftwo(VALUE x, int base)
Definition: bignum.c:4921
rb_int_parse_flags
rb_int_parse_flags
Definition: bignum.h:93
RB_INT_PARSE_ALL
@ RB_INT_PARSE_ALL
Definition: bignum.h:97
RB_INT_PARSE_UNDERSCORE
@ RB_INT_PARSE_UNDERSCORE
Definition: bignum.h:95
RB_INT_PARSE_PREFIX
@ RB_INT_PARSE_PREFIX
Definition: bignum.h:96
RB_INT_PARSE_DEFAULT
@ RB_INT_PARSE_DEFAULT
Definition: bignum.h:98
RB_INT_PARSE_SIGN
@ RB_INT_PARSE_SIGN
Definition: bignum.h:94
rb_big_gt
VALUE rb_big_gt(VALUE x, VALUE y)
Definition: bignum.c:5486
rb_big_ge
VALUE rb_big_ge(VALUE x, VALUE y)
Definition: bignum.c:5492
rb_big_aref
VALUE rb_big_aref(VALUE x, VALUE y)
Definition: bignum.c:6678
rb_big_bit_length
VALUE rb_big_bit_length(VALUE big)
Definition: bignum.c:6787
BIGNUM_EMBED_LEN_MASK
#define BIGNUM_EMBED_LEN_MASK
Definition: bignum.h:81
rb_str2big_karatsuba
VALUE rb_str2big_karatsuba(VALUE arg, int base, int badcheck)
Definition: bignum.c:4358
rb_big_lt
VALUE rb_big_lt(VALUE x, VALUE y)
Definition: bignum.c:5498
rb_big_remainder
VALUE rb_big_remainder(VALUE x, VALUE y)
Definition: bignum.c:6116
rb_big_size_m
VALUE rb_big_size_m(VALUE big)
Definition: bignum.c:6781
ruby_digitmap
const char ruby_digitmap[]
Definition: bignum.c:48
rb_int_powm
VALUE rb_int_powm(int const argc, VALUE *const argv, VALUE const num)
Definition: bignum.c:7108
rb_str2big_normal
VALUE rb_str2big_normal(VALUE arg, int base, int badcheck)
Definition: bignum.c:4316
BIGNUM_EMBED_FLAG
#define BIGNUM_EMBED_FLAG
Definition: bignum.h:79
rb_big_mul_karatsuba
VALUE rb_big_mul_karatsuba(VALUE x, VALUE y)
Definition: bignum.c:1880
rb_integer_float_cmp
VALUE rb_integer_float_cmp(VALUE x, VALUE y)
Definition: bignum.c:5324
BDIGIT
#define BDIGIT
Definition: bignum.h:24
BIGNUM_SIGN_BIT
#define BIGNUM_SIGN_BIT
Definition: bignum.h:78
rb_big_divrem_normal
VALUE rb_big_divrem_normal(VALUE x, VALUE y)
Definition: bignum.c:2741
rb_str_convert_to_inum
VALUE rb_str_convert_to_inum(VALUE str, int base, int badcheck, int raise_exception)
Definition: bignum.c:4252
rb_big_uminus
VALUE rb_big_uminus(VALUE x)
Definition: bignum.c:5551
rb_big_odd_p
VALUE rb_big_odd_p(VALUE)
Definition: bignum.c:6828
rb_big_mul_balance
VALUE rb_big_mul_balance(VALUE x, VALUE y)
Definition: bignum.c:1699
BIGNUM_EMBED_LEN_SHIFT
#define BIGNUM_EMBED_LEN_SHIFT
Definition: bignum.h:83
rb_big_abs
VALUE rb_big_abs(VALUE x)
Definition: bignum.c:6759
rb_int_parse_cstr
VALUE rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits, int base, int flags)
Definition: bignum.c:4045
rb_big_mul_normal
VALUE rb_big_mul_normal(VALUE x, VALUE y)
Definition: bignum.c:1571
RBIGNUM
#define RBIGNUM(obj)
Definition: bignum.h:77
rb_str2big_poweroftwo
VALUE rb_str2big_poweroftwo(VALUE arg, int base, int badcheck)
Definition: bignum.c:4280
rb_big_le
VALUE rb_big_le(VALUE x, VALUE y)
Definition: bignum.c:5504
rb_long2int
#define rb_long2int
Definition: long.h:62
RBASIC
#define RBASIC(obj)
Definition: rbasic.h:34
ruby.h
argc
int argc
Definition: ruby.c:240
argv
char ** argv
Definition: ruby.c:241
stdbool.h
C99 shim for <stdbool.h>
RBasic
Definition: rbasic.h:47
RBignum
Definition: bignum.h:101
RBignum::digits
BDIGIT * digits
Definition: bignum.h:106
RBignum::as
union RBignum::@107 as
RBignum::basic
struct RBasic basic
Definition: bignum.h:102
RBignum::len
size_t len
Definition: bignum.h:105
VALUE
unsigned long VALUE
Definition: value.h:38