Ruby  3.4.0dev (2024-11-22 revision 0989400a925cd201defdca9eb28eb87200b30785)
bignum.h
1 #ifndef INTERNAL_BIGNUM_H /*-*-C-*-vi:se ft=c:*/
2 #define INTERNAL_BIGNUM_H
11 #include "ruby/internal/config.h" /* for HAVE_LIBGMP */
12 #include <stddef.h> /* for size_t */
13 
14 #ifdef HAVE_SYS_TYPES_H
15 # include <sys/types.h> /* for ssize_t (note: on Windows ssize_t is */
16 #endif /* `#define`d in ruby/config.h) */
17 
18 #include "ruby/internal/stdbool.h" /* for bool */
19 #include "ruby/ruby.h" /* for struct RBasic */
20 
21 #ifndef BDIGIT
22 # if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
23 # define BDIGIT unsigned int
24 # define SIZEOF_BDIGIT SIZEOF_INT
25 # define BDIGIT_DBL unsigned LONG_LONG
26 # define BDIGIT_DBL_SIGNED LONG_LONG
27 # define PRI_BDIGIT_PREFIX ""
28 # define PRI_BDIGIT_DBL_PREFIX PRI_LL_PREFIX
29 # elif SIZEOF_INT*2 <= SIZEOF_LONG
30 # define BDIGIT unsigned int
31 # define SIZEOF_BDIGIT SIZEOF_INT
32 # define BDIGIT_DBL unsigned long
33 # define BDIGIT_DBL_SIGNED long
34 # define PRI_BDIGIT_PREFIX ""
35 # define PRI_BDIGIT_DBL_PREFIX "l"
36 # elif SIZEOF_SHORT*2 <= SIZEOF_LONG
37 # define BDIGIT unsigned short
38 # define SIZEOF_BDIGIT SIZEOF_SHORT
39 # define BDIGIT_DBL unsigned long
40 # define BDIGIT_DBL_SIGNED long
41 # define PRI_BDIGIT_PREFIX "h"
42 # define PRI_BDIGIT_DBL_PREFIX "l"
43 # else
44 # define BDIGIT unsigned short
45 # define SIZEOF_BDIGIT (SIZEOF_LONG/2)
46 # define SIZEOF_ACTUAL_BDIGIT SIZEOF_LONG
47 # define BDIGIT_DBL unsigned long
48 # define BDIGIT_DBL_SIGNED long
49 # define PRI_BDIGIT_PREFIX "h"
50 # define PRI_BDIGIT_DBL_PREFIX "l"
51 # endif
52 #endif
53 
54 #ifndef SIZEOF_ACTUAL_BDIGIT
55 # define SIZEOF_ACTUAL_BDIGIT SIZEOF_BDIGIT
56 #endif
57 
58 #ifdef PRI_BDIGIT_PREFIX
59 # define PRIdBDIGIT PRI_BDIGIT_PREFIX"d"
60 # define PRIiBDIGIT PRI_BDIGIT_PREFIX"i"
61 # define PRIoBDIGIT PRI_BDIGIT_PREFIX"o"
62 # define PRIuBDIGIT PRI_BDIGIT_PREFIX"u"
63 # define PRIxBDIGIT PRI_BDIGIT_PREFIX"x"
64 # define PRIXBDIGIT PRI_BDIGIT_PREFIX"X"
65 #endif
66 
67 #ifdef PRI_BDIGIT_DBL_PREFIX
68 # define PRIdBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"d"
69 # define PRIiBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"i"
70 # define PRIoBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"o"
71 # define PRIuBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"u"
72 # define PRIxBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"x"
73 # define PRIXBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"X"
74 #endif
75 
76 #define RBIGNUM(obj) ((struct RBignum *)(obj))
77 #define BIGNUM_SIGN_BIT FL_USER1
78 #define BIGNUM_EMBED_FLAG ((VALUE)FL_USER2)
79 #define BIGNUM_EMBED_LEN_NUMBITS 3
80 #define BIGNUM_EMBED_LEN_MASK \
81  (~(~(VALUE)0U << BIGNUM_EMBED_LEN_NUMBITS) << BIGNUM_EMBED_LEN_SHIFT)
82 #define BIGNUM_EMBED_LEN_SHIFT \
83  (FL_USHIFT+3) /* bit offset of BIGNUM_EMBED_LEN_MASK */
84 #ifndef BIGNUM_EMBED_LEN_MAX
85 # if (SIZEOF_VALUE*RBIMPL_RVALUE_EMBED_LEN_MAX/SIZEOF_ACTUAL_BDIGIT) < (1 << BIGNUM_EMBED_LEN_NUMBITS)-1
86 # define BIGNUM_EMBED_LEN_MAX (SIZEOF_VALUE*RBIMPL_RVALUE_EMBED_LEN_MAX/SIZEOF_ACTUAL_BDIGIT)
87 # else
88 # define BIGNUM_EMBED_LEN_MAX ((1 << BIGNUM_EMBED_LEN_NUMBITS)-1)
89 # endif
90 #endif
91 
92 enum rb_int_parse_flags {
93  RB_INT_PARSE_SIGN = 0x01,
94  RB_INT_PARSE_UNDERSCORE = 0x02,
95  RB_INT_PARSE_PREFIX = 0x04,
96  RB_INT_PARSE_ALL = 0x07,
97  RB_INT_PARSE_DEFAULT = 0x07,
98 };
99 
100 struct RBignum {
101  struct RBasic basic;
102  union {
103  struct {
104  size_t len;
105  BDIGIT *digits;
106  } heap;
107  BDIGIT ary[BIGNUM_EMBED_LEN_MAX];
108  } as;
109 };
110 
111 /* bignum.c */
112 extern const char ruby_digitmap[];
113 double rb_big_fdiv_double(VALUE x, VALUE y);
114 VALUE rb_big_uminus(VALUE x);
115 VALUE rb_big_hash(VALUE);
116 VALUE rb_big_odd_p(VALUE);
117 VALUE rb_big_even_p(VALUE);
118 size_t rb_big_size(VALUE);
119 VALUE rb_integer_float_cmp(VALUE x, VALUE y);
120 VALUE rb_integer_float_eq(VALUE x, VALUE y);
121 VALUE rb_str_convert_to_inum(VALUE str, int base, int badcheck, int raise_exception);
122 VALUE rb_big_comp(VALUE x);
123 VALUE rb_big_aref(VALUE x, VALUE y);
124 VALUE rb_big_abs(VALUE x);
125 VALUE rb_big_size_m(VALUE big);
126 VALUE rb_big_bit_length(VALUE big);
127 VALUE rb_big_remainder(VALUE x, VALUE y);
128 VALUE rb_big_gt(VALUE x, VALUE y);
129 VALUE rb_big_ge(VALUE x, VALUE y);
130 VALUE rb_big_lt(VALUE x, VALUE y);
131 VALUE rb_big_le(VALUE x, VALUE y);
132 VALUE rb_int_powm(int const argc, VALUE * const argv, VALUE const num);
133 VALUE rb_big_isqrt(VALUE n);
134 static inline bool BIGNUM_SIGN(VALUE b);
135 static inline bool BIGNUM_POSITIVE_P(VALUE b);
136 static inline bool BIGNUM_NEGATIVE_P(VALUE b);
137 static inline void BIGNUM_SET_SIGN(VALUE b, bool sign);
138 static inline void BIGNUM_NEGATE(VALUE b);
139 static inline size_t BIGNUM_LEN(VALUE b);
140 static inline BDIGIT *BIGNUM_DIGITS(VALUE b);
141 static inline int BIGNUM_LENINT(VALUE b);
142 static inline bool BIGNUM_EMBED_P(VALUE b);
143 
144 RUBY_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);
164 RUBY_SYMBOL_EXPORT_END
165 
166 #if defined(HAVE_INT128_T)
167 VALUE rb_int128t2big(int128_t n);
168 #endif
169 
170 /* sign: positive:1, negative:0 */
171 static inline bool
172 BIGNUM_SIGN(VALUE b)
173 {
174  return FL_TEST_RAW(b, BIGNUM_SIGN_BIT);
175 }
176 
177 static inline bool
178 BIGNUM_POSITIVE_P(VALUE b)
179 {
180  return BIGNUM_SIGN(b);
181 }
182 
183 static inline bool
184 BIGNUM_NEGATIVE_P(VALUE b)
185 {
186  return ! BIGNUM_POSITIVE_P(b);
187 }
188 
189 static inline void
190 BIGNUM_SET_SIGN(VALUE b, bool sign)
191 {
192  if (sign) {
193  FL_SET_RAW(b, BIGNUM_SIGN_BIT);
194  }
195  else {
196  FL_UNSET_RAW(b, BIGNUM_SIGN_BIT);
197  }
198 }
199 
200 static inline void
201 BIGNUM_NEGATE(VALUE b)
202 {
203  FL_REVERSE_RAW(b, BIGNUM_SIGN_BIT);
204 }
205 
206 static inline size_t
207 BIGNUM_LEN(VALUE b)
208 {
209  if (! BIGNUM_EMBED_P(b)) {
210  return RBIGNUM(b)->as.heap.len;
211  }
212  else {
213  size_t ret = RBASIC(b)->flags;
214  ret &= BIGNUM_EMBED_LEN_MASK;
215  ret >>= BIGNUM_EMBED_LEN_SHIFT;
216  return ret;
217  }
218 }
219 
220 static inline int
221 BIGNUM_LENINT(VALUE b)
222 {
223  return rb_long2int(BIGNUM_LEN(b));
224 }
225 
226 /* LSB:BIGNUM_DIGITS(b)[0], MSB:BIGNUM_DIGITS(b)[BIGNUM_LEN(b)-1] */
227 static inline BDIGIT *
228 BIGNUM_DIGITS(VALUE b)
229 {
230  if (BIGNUM_EMBED_P(b)) {
231  return RBIGNUM(b)->as.ary;
232  }
233  else {
234  return RBIGNUM(b)->as.heap.digits;
235  }
236 }
237 
238 static inline bool
239 BIGNUM_EMBED_P(VALUE b)
240 {
241  return FL_TEST_RAW(b, BIGNUM_EMBED_FLAG);
242 }
243 
244 #endif /* INTERNAL_BIGNUM_H */
#define FL_UNSET_RAW
Old name of RB_FL_UNSET_RAW.
Definition: fl_type.h:134
#define FL_REVERSE_RAW
Old name of RB_FL_REVERSE_RAW.
Definition: fl_type.h:128
#define FL_TEST_RAW
Old name of RB_FL_TEST_RAW.
Definition: fl_type.h:132
#define FL_SET_RAW
Old name of RB_FL_SET_RAW.
Definition: fl_type.h:130
int len
Length of the buffer.
Definition: io.h:8
#define rb_long2int
Just another name of rb_long2int_inline.
Definition: long.h:62
#define RBASIC(obj)
Convenient casting macro.
Definition: rbasic.h:40
C99 shim for <stdbool.h>
Ruby object's base components.
Definition: rbasic.h:63
uintptr_t VALUE
Type that represents a Ruby object.
Definition: value.h:40