quadmath 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +11 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +160 -0
- data/Rakefile +14 -0
- data/ext/quadmath/complex128.c +494 -0
- data/ext/quadmath/extconf.rb +15 -0
- data/ext/quadmath/float128.c +638 -0
- data/ext/quadmath/internal/rb_quadmath.h +77 -0
- data/ext/quadmath/main.c +31 -0
- data/ext/quadmath/missing/cerfcq.c +158 -0
- data/ext/quadmath/missing/cerfq.c +35 -0
- data/ext/quadmath/missing/cl2norm2q.c +43 -0
- data/ext/quadmath/missing/clgammaq.c +61 -0
- data/ext/quadmath/missing/ctgammaq.c +56 -0
- data/ext/quadmath/missing/ool_quad2str.c +738 -0
- data/ext/quadmath/missing/opts_exception_p.c +20 -0
- data/ext/quadmath/numerable.c +2657 -0
- data/ext/quadmath/quadmath.c +2768 -0
- data/ext/quadmath/rb_quadmath.h +75 -0
- data/lib/quadmath/quadmath.so +0 -0
- data/lib/quadmath/version.rb +5 -0
- data/lib/quadmath.rb +8 -0
- data/pkg/quadmath-0.1.0.gem +0 -0
- data/sig/ruby/quadmath.rbs +6 -0
- metadata +70 -0
|
@@ -0,0 +1,2768 @@
|
|
|
1
|
+
/*******************************************************************************
|
|
2
|
+
quadmath.c -- module QuadMath
|
|
3
|
+
|
|
4
|
+
Author: Hironobu Inatsuka
|
|
5
|
+
*******************************************************************************/
|
|
6
|
+
#include <ruby.h>
|
|
7
|
+
#include <quadmath.h>
|
|
8
|
+
#include "rb_quadmath.h"
|
|
9
|
+
#include "internal/rb_quadmath.h"
|
|
10
|
+
|
|
11
|
+
static inline bool
|
|
12
|
+
num_real_p(VALUE self)
|
|
13
|
+
{
|
|
14
|
+
if (!rb_respond_to(self, rb_intern("real?")))
|
|
15
|
+
rb_fatal("method `real?' is undefined");
|
|
16
|
+
else
|
|
17
|
+
return RTEST(rb_funcall(self, rb_intern("real?"), 0));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static inline __float128
|
|
21
|
+
fixnum_to_cf128(VALUE self)
|
|
22
|
+
{
|
|
23
|
+
long x = FIX2LONG(self);
|
|
24
|
+
|
|
25
|
+
return (__float128)x;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
static inline __float128
|
|
29
|
+
bignum_to_cf128(VALUE self)
|
|
30
|
+
{
|
|
31
|
+
VALUE inum = rb_big2str(self, 10);
|
|
32
|
+
__float128 x = strtoflt128(StringValuePtr(inum), NULL);
|
|
33
|
+
|
|
34
|
+
return x;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static inline __float128
|
|
38
|
+
integer_to_cf128(VALUE self)
|
|
39
|
+
{
|
|
40
|
+
__float128 x = 0.0Q;
|
|
41
|
+
switch (TYPE(self)) {
|
|
42
|
+
case T_FIXNUM:
|
|
43
|
+
x = fixnum_to_cf128(self);
|
|
44
|
+
break;
|
|
45
|
+
case T_BIGNUM:
|
|
46
|
+
x = bignum_to_cf128(self);
|
|
47
|
+
break;
|
|
48
|
+
default:
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
return x;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static inline __float128
|
|
55
|
+
rational_to_cf128(VALUE self)
|
|
56
|
+
{
|
|
57
|
+
VALUE numer = rb_rational_num(self),
|
|
58
|
+
denom = rb_rational_den(self);
|
|
59
|
+
__float128 x = integer_to_cf128(numer) / integer_to_cf128(denom);
|
|
60
|
+
|
|
61
|
+
return x;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static inline __float128
|
|
65
|
+
float_to_cf128(VALUE self)
|
|
66
|
+
{
|
|
67
|
+
double x = NUM2DBL(self);
|
|
68
|
+
|
|
69
|
+
return (__float128)x;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
static inline __float128
|
|
75
|
+
primitive_real_to_cf128(VALUE self)
|
|
76
|
+
{
|
|
77
|
+
__float128 x;
|
|
78
|
+
switch (TYPE(self)) {
|
|
79
|
+
case T_FIXNUM:
|
|
80
|
+
x = fixnum_to_cf128(self);
|
|
81
|
+
break;
|
|
82
|
+
case T_BIGNUM:
|
|
83
|
+
x = bignum_to_cf128(self);
|
|
84
|
+
break;
|
|
85
|
+
case T_RATIONAL:
|
|
86
|
+
x = rational_to_cf128(self);
|
|
87
|
+
break;
|
|
88
|
+
case T_FLOAT:
|
|
89
|
+
x = float_to_cf128(self);
|
|
90
|
+
break;
|
|
91
|
+
default:
|
|
92
|
+
self = rb_funcall(self, rb_intern("to_f128"), 0);
|
|
93
|
+
x = GetF128(self);
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
return x;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static inline __complex128
|
|
100
|
+
nucomp_to_cc128(VALUE self)
|
|
101
|
+
{
|
|
102
|
+
VALUE real = rb_complex_real(self);
|
|
103
|
+
VALUE imag = rb_complex_imag(self);
|
|
104
|
+
__complex128 z = 0+0i;
|
|
105
|
+
|
|
106
|
+
__real__ z = primitive_real_to_cf128(real);
|
|
107
|
+
__imag__ z = primitive_real_to_cf128(imag);
|
|
108
|
+
|
|
109
|
+
return z;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
static inline VALUE
|
|
113
|
+
complex128_to_nucomp(VALUE self)
|
|
114
|
+
{
|
|
115
|
+
__complex128 z = GetC128(self);
|
|
116
|
+
return rb_Complex(
|
|
117
|
+
rb_float128_cf128(crealq(z)),
|
|
118
|
+
rb_float128_cf128(cimagq(z)));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
static VALUE
|
|
122
|
+
quadmath_exp_realsolve(__float128 x)
|
|
123
|
+
{
|
|
124
|
+
return rb_float128_cf128(expq(x));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
static VALUE
|
|
128
|
+
quadmath_exp_nucompsolve(__complex128 z)
|
|
129
|
+
{
|
|
130
|
+
return rb_complex128_cc128(cexpq(z));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/*
|
|
134
|
+
* call-seq:
|
|
135
|
+
* QuadMath.exp(x) -> Float128 | Complex | Complex128
|
|
136
|
+
*
|
|
137
|
+
* xの指数関数を返す.xが実数なら実数解,複素数なら複素数解として各々返却する.
|
|
138
|
+
*
|
|
139
|
+
* QuadMath.exp(1) # => 2.7182818284590452353602874713526
|
|
140
|
+
* QuadMath.exp(-2.1r) # => 0.122456428252981910218647376072626
|
|
141
|
+
* QuadMath.exp(1+0i) # => (2.7182818284590452353602874713526+0.0i)
|
|
142
|
+
* QuadMath.exp('-10.4'.to_f128) # => 0.0000304324830084036365062222042316828
|
|
143
|
+
* QuadMath.exp(Complex128.rect(1.1r, 1))
|
|
144
|
+
* # => (1.6231578299489788500278329108526+2.5279185426966278702444317537622i)
|
|
145
|
+
*/
|
|
146
|
+
static VALUE
|
|
147
|
+
quadmath_exp(VALUE unused_obj, VALUE x)
|
|
148
|
+
{
|
|
149
|
+
switch (convertion_num_types(x)) {
|
|
150
|
+
case NUM_FIXNUM:
|
|
151
|
+
return quadmath_exp_realsolve(fixnum_to_cf128(x));
|
|
152
|
+
break;
|
|
153
|
+
case NUM_BIGNUM:
|
|
154
|
+
return quadmath_exp_realsolve(bignum_to_cf128(x));
|
|
155
|
+
break;
|
|
156
|
+
case NUM_RATIONAL:
|
|
157
|
+
return quadmath_exp_realsolve(rational_to_cf128(x));
|
|
158
|
+
break;
|
|
159
|
+
case NUM_FLOAT:
|
|
160
|
+
return quadmath_exp_realsolve(float_to_cf128(x));
|
|
161
|
+
break;
|
|
162
|
+
case NUM_COMPLEX:
|
|
163
|
+
VALUE nucomp = quadmath_exp_nucompsolve(nucomp_to_cc128(x));
|
|
164
|
+
return complex128_to_nucomp(nucomp);
|
|
165
|
+
break;
|
|
166
|
+
case NUM_FLOAT128:
|
|
167
|
+
return quadmath_exp_realsolve(GetF128(x));
|
|
168
|
+
break;
|
|
169
|
+
case NUM_COMPLEX128:
|
|
170
|
+
return quadmath_exp_nucompsolve(GetC128(x));
|
|
171
|
+
break;
|
|
172
|
+
case NUM_OTHERTYPE:
|
|
173
|
+
default:
|
|
174
|
+
if (num_real_p(x))
|
|
175
|
+
return quadmath_exp_realsolve(rb_float128_value(x));
|
|
176
|
+
else
|
|
177
|
+
return quadmath_exp_nucompsolve(rb_complex128_value(x));
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
static inline VALUE
|
|
183
|
+
quadmath_exp2_realsolve(__float128 x)
|
|
184
|
+
{
|
|
185
|
+
return rb_float128_cf128(exp2q(x));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
static inline VALUE
|
|
189
|
+
quadmath_exp2_nucompsolve(__complex128 z)
|
|
190
|
+
{
|
|
191
|
+
return rb_complex128_cc128(cpowq(2, z));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/*
|
|
195
|
+
* call-seq:
|
|
196
|
+
* QuadMath.exp2(x) -> Integer | Rational | Float128 | Complex | Complex128
|
|
197
|
+
*
|
|
198
|
+
* 2のx乗を返す.xが整数なら正では整数解,負では有理数解,実数なら実数解,複素数なら複素数解として各々返却する.
|
|
199
|
+
* これは一般に`2 ** x`と計算するのとさして変わらない.唯一の違いは実数の精度が二倍ではなく四倍であることである.
|
|
200
|
+
*
|
|
201
|
+
* QuadMath.exp2(-1) # => (1/2)
|
|
202
|
+
* QuadMath.exp2(5) # => 32
|
|
203
|
+
* QuadMath.exp2(11/7r) # => 2.9719885782738968495997065734291
|
|
204
|
+
* QuadMath.exp2(Complex128::I) # => (0.76923890136397212657832999366127+0.638961276313634801150032911464701i)
|
|
205
|
+
*/
|
|
206
|
+
static VALUE
|
|
207
|
+
quadmath_exp2(VALUE unused_obj, VALUE x)
|
|
208
|
+
{
|
|
209
|
+
switch (convertion_num_types(x)) {
|
|
210
|
+
case NUM_FIXNUM:
|
|
211
|
+
case NUM_BIGNUM:
|
|
212
|
+
return rb_num_coerce_bin(INT2NUM(2), x, rb_intern("**"));
|
|
213
|
+
break;
|
|
214
|
+
case NUM_RATIONAL:
|
|
215
|
+
return quadmath_exp2_realsolve(rational_to_cf128(x));
|
|
216
|
+
break;
|
|
217
|
+
case NUM_FLOAT:
|
|
218
|
+
return quadmath_exp2_realsolve(float_to_cf128(x));
|
|
219
|
+
break;
|
|
220
|
+
case NUM_COMPLEX:
|
|
221
|
+
return float128_nucomp_pow(rb_float128_cf128(2), x);
|
|
222
|
+
break;
|
|
223
|
+
case NUM_FLOAT128:
|
|
224
|
+
return quadmath_exp2_realsolve(GetF128(x));
|
|
225
|
+
break;
|
|
226
|
+
case NUM_COMPLEX128:
|
|
227
|
+
return quadmath_exp2_nucompsolve(GetC128(x));
|
|
228
|
+
break;
|
|
229
|
+
case NUM_OTHERTYPE:
|
|
230
|
+
default:
|
|
231
|
+
if (num_real_p(x))
|
|
232
|
+
return quadmath_exp2_realsolve(GetF128(x));
|
|
233
|
+
else
|
|
234
|
+
return quadmath_exp2_nucompsolve(GetC128(x));
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
static inline VALUE
|
|
240
|
+
quadmath_expm1_realsolve(__float128 x)
|
|
241
|
+
{
|
|
242
|
+
return rb_float128_cf128(expm1q(x));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
static inline VALUE
|
|
246
|
+
quadmath_expm1_nucompsolve(__complex128 z)
|
|
247
|
+
{
|
|
248
|
+
if (cimagq(z) == 0)
|
|
249
|
+
{
|
|
250
|
+
__float128 real = crealq(z);
|
|
251
|
+
return rb_complex128_cc128((__complex128)expm1q(real));
|
|
252
|
+
}
|
|
253
|
+
else
|
|
254
|
+
{
|
|
255
|
+
__complex128 w = 2 * cexpq(z / 2) * csinhq(z / 2);
|
|
256
|
+
return rb_complex128_cc128(w);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/*
|
|
261
|
+
* call-seq:
|
|
262
|
+
* QuadMath.expm1(x) -> Float128 | Complex128
|
|
263
|
+
*
|
|
264
|
+
* xの指数関数より1を引いた値を返す.
|
|
265
|
+
* この関数はゼロに近傍な値を数式通りにexp(x)-1と計算するよりも高精度化する.
|
|
266
|
+
* xが実数なら実数解,複素数なら複素数解として各々返却する.
|
|
267
|
+
*
|
|
268
|
+
* QuadMath.expm1('-1e-33'.to_f128) # => -1.0e-33
|
|
269
|
+
* QuadMath.exp('-1e-33'.to_f128)-1 # => -9.62964972193617926527988971292464e-34
|
|
270
|
+
* QuadMath.expm1(Complex128::I) # => (-0.459697694131860282599063392557023+0.841470984807896506652502321630299i)
|
|
271
|
+
*/
|
|
272
|
+
static VALUE
|
|
273
|
+
quadmath_expm1(VALUE unused_obj, VALUE x)
|
|
274
|
+
{
|
|
275
|
+
switch (convertion_num_types(x)) {
|
|
276
|
+
case NUM_FIXNUM:
|
|
277
|
+
return quadmath_expm1_realsolve(fixnum_to_cf128(x));
|
|
278
|
+
break;
|
|
279
|
+
case NUM_BIGNUM:
|
|
280
|
+
return quadmath_expm1_realsolve(bignum_to_cf128(x));
|
|
281
|
+
break;
|
|
282
|
+
case NUM_RATIONAL:
|
|
283
|
+
return quadmath_expm1_realsolve(rational_to_cf128(x));
|
|
284
|
+
break;
|
|
285
|
+
case NUM_FLOAT:
|
|
286
|
+
return quadmath_expm1_realsolve(float_to_cf128(x));
|
|
287
|
+
break;
|
|
288
|
+
case NUM_COMPLEX:
|
|
289
|
+
VALUE nucomp = quadmath_expm1_nucompsolve(nucomp_to_cc128(x));
|
|
290
|
+
return complex128_to_nucomp(nucomp);
|
|
291
|
+
break;
|
|
292
|
+
case NUM_FLOAT128:
|
|
293
|
+
return quadmath_expm1_realsolve(GetF128(x));
|
|
294
|
+
break;
|
|
295
|
+
case NUM_COMPLEX128:
|
|
296
|
+
return quadmath_expm1_nucompsolve(GetC128(x));
|
|
297
|
+
break;
|
|
298
|
+
case NUM_OTHERTYPE:
|
|
299
|
+
default:
|
|
300
|
+
if (num_real_p(x))
|
|
301
|
+
return quadmath_expm1_realsolve(GetF128(x));
|
|
302
|
+
else
|
|
303
|
+
return quadmath_expm1_nucompsolve(GetC128(x));
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
static inline VALUE
|
|
309
|
+
quadmath_log_realsolve(__float128 x)
|
|
310
|
+
{
|
|
311
|
+
if (isnanq(x))
|
|
312
|
+
return rb_float128_cf128(x);
|
|
313
|
+
else if (!signbitq(x))
|
|
314
|
+
return rb_float128_cf128(logq(x));
|
|
315
|
+
else
|
|
316
|
+
{
|
|
317
|
+
__complex128 z;
|
|
318
|
+
__real__ z = logq(fabsq(x));
|
|
319
|
+
__imag__ z = M_PIq;
|
|
320
|
+
return rb_complex128_cc128(z);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
static inline VALUE
|
|
325
|
+
quadmath_log_nucompsolve(__complex128 z)
|
|
326
|
+
{
|
|
327
|
+
return rb_complex128_cc128(clogq(z));
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/*
|
|
331
|
+
* call-seq:
|
|
332
|
+
* QuadMath.log(x) -> Float128 | Complex128
|
|
333
|
+
*
|
|
334
|
+
* xの自然対数を返す.
|
|
335
|
+
* xが実数なら正ならば実数解,負なら複素数解,複素数なら複素数解として値を各々返す.
|
|
336
|
+
*
|
|
337
|
+
* QuadMath.log(2) # => 0.693147180559945309417232121458176
|
|
338
|
+
* QuadMath.log(-2) # => (0.693147180559945309417232121458176+3.1415926535897932384626433832795i)
|
|
339
|
+
* QuadMath.log(Complex128::I) # => (0.0+1.5707963267948966192313216916397i)
|
|
340
|
+
*/
|
|
341
|
+
static VALUE
|
|
342
|
+
quadmath_log(VALUE unused_obj, VALUE x)
|
|
343
|
+
{
|
|
344
|
+
switch (convertion_num_types(x)) {
|
|
345
|
+
case NUM_FIXNUM:
|
|
346
|
+
return quadmath_log_realsolve(fixnum_to_cf128(x));
|
|
347
|
+
break;
|
|
348
|
+
case NUM_BIGNUM:
|
|
349
|
+
return quadmath_log_realsolve(bignum_to_cf128(x));
|
|
350
|
+
break;
|
|
351
|
+
case NUM_RATIONAL:
|
|
352
|
+
return quadmath_log_realsolve(rational_to_cf128(x));
|
|
353
|
+
break;
|
|
354
|
+
case NUM_FLOAT:
|
|
355
|
+
return quadmath_log_realsolve(float_to_cf128(x));
|
|
356
|
+
break;
|
|
357
|
+
case NUM_COMPLEX:
|
|
358
|
+
VALUE nucomp = quadmath_log_nucompsolve(nucomp_to_cc128(x));
|
|
359
|
+
return complex128_to_nucomp(nucomp);
|
|
360
|
+
break;
|
|
361
|
+
case NUM_FLOAT128:
|
|
362
|
+
return quadmath_log_realsolve(GetF128(x));
|
|
363
|
+
break;
|
|
364
|
+
case NUM_COMPLEX128:
|
|
365
|
+
return quadmath_log_nucompsolve(GetC128(x));
|
|
366
|
+
break;
|
|
367
|
+
case NUM_OTHERTYPE:
|
|
368
|
+
default:
|
|
369
|
+
if (num_real_p(x))
|
|
370
|
+
return quadmath_log_realsolve(GetF128(x));
|
|
371
|
+
else
|
|
372
|
+
return quadmath_log_nucompsolve(GetC128(x));
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
static inline VALUE
|
|
378
|
+
quadmath_log2_realsolve(__float128 x)
|
|
379
|
+
{
|
|
380
|
+
if (isnanq(x))
|
|
381
|
+
return rb_float128_cf128(x);
|
|
382
|
+
else if (!signbitq(x))
|
|
383
|
+
return rb_float128_cf128(log2q(x));
|
|
384
|
+
else
|
|
385
|
+
{
|
|
386
|
+
__complex128 z;
|
|
387
|
+
__real__ z = log2q(fabsq(x));
|
|
388
|
+
__imag__ z = M_PIq / M_LN2q;
|
|
389
|
+
return rb_complex128_cc128(z);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
static inline VALUE
|
|
394
|
+
quadmath_log2_nucompsolve(__complex128 z)
|
|
395
|
+
{
|
|
396
|
+
return rb_complex128_cc128(clogq(z) / M_LN2q);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/*
|
|
400
|
+
* call-seq:
|
|
401
|
+
* QuadMath.log2(x) -> Float128 | Complex128
|
|
402
|
+
*
|
|
403
|
+
* xの2を底とする対数を返す.(Binary Logarithm)
|
|
404
|
+
* xが実数なら正ならば実数解,負なら複素数解,複素数なら複素数解として値を各々返す.
|
|
405
|
+
*
|
|
406
|
+
* Array.new(5){|i|i} # => [0, 1, 2, 3, 4]
|
|
407
|
+
* ary = Array.new(5){|i| 2**i} # => [1, 2, 4, 8, 16]
|
|
408
|
+
* ary.map {|x| QuadMath.log2(x)} # => [0.0, 1.0, 2.0, 3.0, 4.0]
|
|
409
|
+
*
|
|
410
|
+
* Array.new(5){|i|~i} # => [-1, -2, -3, -4, -5]
|
|
411
|
+
* ary = Array.new(5){|i| 2 ** ~i} # => [(1/2), (1/4), (1/8), (1/16), (1/32)]
|
|
412
|
+
* ary.map{|x| QuadMath.log2(x)} # => [-1.0, -2.0, -3.0, -4.0, -5.0]
|
|
413
|
+
*
|
|
414
|
+
* QuadMath.log2(1+1i) # => (0.5+1.1330900354567984524069207364291i)
|
|
415
|
+
*/
|
|
416
|
+
static VALUE
|
|
417
|
+
quadmath_log2(VALUE unused_obj, VALUE x)
|
|
418
|
+
{
|
|
419
|
+
switch (convertion_num_types(x)) {
|
|
420
|
+
case NUM_FIXNUM:
|
|
421
|
+
return quadmath_log2_realsolve(fixnum_to_cf128(x));
|
|
422
|
+
break;
|
|
423
|
+
case NUM_BIGNUM:
|
|
424
|
+
return quadmath_log2_realsolve(bignum_to_cf128(x));
|
|
425
|
+
break;
|
|
426
|
+
case NUM_RATIONAL:
|
|
427
|
+
return quadmath_log2_realsolve(rational_to_cf128(x));
|
|
428
|
+
break;
|
|
429
|
+
case NUM_FLOAT:
|
|
430
|
+
return quadmath_log2_realsolve(float_to_cf128(x));
|
|
431
|
+
break;
|
|
432
|
+
case NUM_COMPLEX:
|
|
433
|
+
VALUE nucomp = quadmath_log2_nucompsolve(nucomp_to_cc128(x));
|
|
434
|
+
return complex128_to_nucomp(nucomp);
|
|
435
|
+
break;
|
|
436
|
+
case NUM_FLOAT128:
|
|
437
|
+
return quadmath_log2_realsolve(GetF128(x));
|
|
438
|
+
break;
|
|
439
|
+
case NUM_COMPLEX128:
|
|
440
|
+
return quadmath_log2_nucompsolve(GetC128(x));
|
|
441
|
+
break;
|
|
442
|
+
case NUM_OTHERTYPE:
|
|
443
|
+
default:
|
|
444
|
+
if (num_real_p(x))
|
|
445
|
+
return quadmath_log2_realsolve(GetF128(x));
|
|
446
|
+
else
|
|
447
|
+
return quadmath_log2_nucompsolve(GetC128(x));
|
|
448
|
+
break;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
static inline VALUE
|
|
453
|
+
quadmath_log10_realsolve(__float128 x)
|
|
454
|
+
{
|
|
455
|
+
if (isnanq(x))
|
|
456
|
+
return rb_float128_cf128(x);
|
|
457
|
+
else if (!signbitq(x))
|
|
458
|
+
return rb_float128_cf128(log10q(x));
|
|
459
|
+
else
|
|
460
|
+
{
|
|
461
|
+
__complex128 z;
|
|
462
|
+
__real__ z = log10q(fabsq(x));
|
|
463
|
+
__imag__ z = M_PIq / M_LN10q;
|
|
464
|
+
return rb_complex128_cc128(z);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
static inline VALUE
|
|
469
|
+
quadmath_log10_nucompsolve(__complex128 z)
|
|
470
|
+
{
|
|
471
|
+
return rb_complex128_cc128(clog10q(z));
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/*
|
|
475
|
+
* call-seq:
|
|
476
|
+
* QuadMath.log10(x) -> Float128 | Complex128
|
|
477
|
+
*
|
|
478
|
+
* xの常用対数を返す.
|
|
479
|
+
* xが実数なら正ならば実数解,負なら複素数解,複素数なら複素数解として値を各々返す.
|
|
480
|
+
*
|
|
481
|
+
* Array.new(5){|i|i} # => [0, 1, 2, 3, 4]
|
|
482
|
+
* ary = Array.new(5){|i| 10**i} # => [1, 10, 100, 1000, 10000]
|
|
483
|
+
* ary.map {|x| QuadMath.log10(x)} # => [0.0, 1.0, 2.0, 3.0, 4.0]
|
|
484
|
+
*
|
|
485
|
+
* Array.new(5){|i|~i} # => [-1, -2, -3, -4, -5]
|
|
486
|
+
* ary = Array.new(5){|i|10 ** ~i} # => [(1/10), (1/100), (1/1000), (1/10000), (1/100000)]
|
|
487
|
+
* ary.map{|x| QuadMath.log10(x)} # => [-1.0, -2.0, -3.0, -4.0, -5.0]
|
|
488
|
+
*
|
|
489
|
+
* QuadMath.log10(1+1i) # => (0.150514997831990597606869447362246+0.341094088460460336871445906357839i)
|
|
490
|
+
|
|
491
|
+
*/
|
|
492
|
+
static VALUE
|
|
493
|
+
quadmath_log10(VALUE unused_obj, VALUE x)
|
|
494
|
+
{
|
|
495
|
+
switch (convertion_num_types(x)) {
|
|
496
|
+
case NUM_FIXNUM:
|
|
497
|
+
return quadmath_log10_realsolve(fixnum_to_cf128(x));
|
|
498
|
+
break;
|
|
499
|
+
case NUM_BIGNUM:
|
|
500
|
+
return quadmath_log10_realsolve(bignum_to_cf128(x));
|
|
501
|
+
break;
|
|
502
|
+
case NUM_RATIONAL:
|
|
503
|
+
return quadmath_log10_realsolve(rational_to_cf128(x));
|
|
504
|
+
break;
|
|
505
|
+
case NUM_FLOAT:
|
|
506
|
+
return quadmath_log10_realsolve(float_to_cf128(x));
|
|
507
|
+
break;
|
|
508
|
+
case NUM_COMPLEX:
|
|
509
|
+
VALUE nucomp = quadmath_log10_nucompsolve(nucomp_to_cc128(x));
|
|
510
|
+
return complex128_to_nucomp(nucomp);
|
|
511
|
+
break;
|
|
512
|
+
case NUM_FLOAT128:
|
|
513
|
+
return quadmath_log10_realsolve(GetF128(x));
|
|
514
|
+
break;
|
|
515
|
+
case NUM_COMPLEX128:
|
|
516
|
+
return quadmath_log10_nucompsolve(GetC128(x));
|
|
517
|
+
break;
|
|
518
|
+
case NUM_OTHERTYPE:
|
|
519
|
+
default:
|
|
520
|
+
if (num_real_p(x))
|
|
521
|
+
return quadmath_log10_realsolve(GetF128(x));
|
|
522
|
+
else
|
|
523
|
+
return quadmath_log10_nucompsolve(GetC128(x));
|
|
524
|
+
break;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
static inline VALUE
|
|
529
|
+
log1p_realsolve_neg(__float128 x)
|
|
530
|
+
{
|
|
531
|
+
__complex128 z = 2 * catanhq(x / (2 + x));
|
|
532
|
+
if (cimagq(z) != M_PIq)
|
|
533
|
+
__imag__ z = M_PIq;
|
|
534
|
+
return rb_complex128_cc128(z);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
static inline VALUE
|
|
538
|
+
quadmath_log1p_realsolve(__float128 x)
|
|
539
|
+
{
|
|
540
|
+
if (isnanq(x))
|
|
541
|
+
return nanq("");
|
|
542
|
+
if (x >= -1)
|
|
543
|
+
return rb_float128_cf128(log1pq(x));
|
|
544
|
+
else
|
|
545
|
+
return log1p_realsolve_neg(x);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
static inline VALUE
|
|
549
|
+
quadmath_log1p_nucompsolve(__complex128 z)
|
|
550
|
+
{
|
|
551
|
+
if (cimagq(z) == 0)
|
|
552
|
+
{
|
|
553
|
+
__float128 real = crealq(z);
|
|
554
|
+
if (real >= -1)
|
|
555
|
+
return rb_complex128_cc128((__complex128)log1pq(real));
|
|
556
|
+
else
|
|
557
|
+
return log1p_realsolve_neg(real);
|
|
558
|
+
}
|
|
559
|
+
else
|
|
560
|
+
return rb_complex128_cc128(clogq(1+z));
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/*
|
|
564
|
+
* call-seq:
|
|
565
|
+
* QuadMath.log1p(x) -> Float128 | Complex128
|
|
566
|
+
*
|
|
567
|
+
* xに1を加算した自然対数を返す.
|
|
568
|
+
* この関数はxがゼロに近傍な値のとき数式通りにlog(1+x)と計算するよりも高精度化する.
|
|
569
|
+
* xが実数なら実数解,複素数なら複素数解として各々返却する.
|
|
570
|
+
*
|
|
571
|
+
* x = '-1e-16'.to_f128 # => -1.0e-16
|
|
572
|
+
* QuadMath.log1p(x) # => -1.00000000000000005e-16
|
|
573
|
+
* QuadMath.log(1+x) # => -1.0000000000000000502830161122942e-16
|
|
574
|
+
|
|
575
|
+
*/
|
|
576
|
+
static VALUE
|
|
577
|
+
quadmath_log1p(VALUE unused_obj, VALUE x)
|
|
578
|
+
{
|
|
579
|
+
switch (convertion_num_types(x)) {
|
|
580
|
+
case NUM_FIXNUM:
|
|
581
|
+
return quadmath_log1p_realsolve(fixnum_to_cf128(x));
|
|
582
|
+
break;
|
|
583
|
+
case NUM_BIGNUM:
|
|
584
|
+
return quadmath_log1p_realsolve(bignum_to_cf128(x));
|
|
585
|
+
break;
|
|
586
|
+
case NUM_RATIONAL:
|
|
587
|
+
return quadmath_log1p_realsolve(rational_to_cf128(x));
|
|
588
|
+
break;
|
|
589
|
+
case NUM_FLOAT:
|
|
590
|
+
return quadmath_log1p_realsolve(float_to_cf128(x));
|
|
591
|
+
break;
|
|
592
|
+
case NUM_COMPLEX:
|
|
593
|
+
VALUE nucomp = quadmath_log1p_nucompsolve(nucomp_to_cc128(x));
|
|
594
|
+
return complex128_to_nucomp(nucomp);
|
|
595
|
+
break;
|
|
596
|
+
case NUM_FLOAT128:
|
|
597
|
+
return quadmath_log1p_realsolve(GetF128(x));
|
|
598
|
+
break;
|
|
599
|
+
case NUM_COMPLEX128:
|
|
600
|
+
return quadmath_log1p_nucompsolve(GetC128(x));
|
|
601
|
+
break;
|
|
602
|
+
case NUM_OTHERTYPE:
|
|
603
|
+
default:
|
|
604
|
+
if (num_real_p(x))
|
|
605
|
+
return quadmath_log1p_realsolve(GetF128(x));
|
|
606
|
+
else
|
|
607
|
+
return quadmath_log1p_nucompsolve(GetC128(x));
|
|
608
|
+
break;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
static inline VALUE
|
|
614
|
+
quadmath_sqrt_realsolve(__float128 x)
|
|
615
|
+
{
|
|
616
|
+
if (!signbitq(x))
|
|
617
|
+
return rb_float128_cf128(sqrtq(x));
|
|
618
|
+
else
|
|
619
|
+
{
|
|
620
|
+
__complex128 z;
|
|
621
|
+
__real__ z = 0.q;
|
|
622
|
+
__imag__ z = sqrtq(fabsq(x));
|
|
623
|
+
return rb_complex128_cc128(z);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
static inline VALUE
|
|
628
|
+
quadmath_sqrt_nucompsolve(__complex128 z)
|
|
629
|
+
{
|
|
630
|
+
return rb_complex128_cc128(csqrtq(z));
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/*
|
|
634
|
+
* call-seq:
|
|
635
|
+
* QuadMath.sqrt(x) -> Float128 | Complex128
|
|
636
|
+
*
|
|
637
|
+
* xの平方根を返す.
|
|
638
|
+
* xが実数であり正の場合は実数解,負の場合は虚数解,複素数の場合は複素数解として各々返却する.
|
|
639
|
+
*
|
|
640
|
+
* QuadMath.sqrt(4) # => 2.0
|
|
641
|
+
* QuadMath.sqrt(-1) == Complex128::I # => true
|
|
642
|
+
* QuadMath.sqrt(1+1i) # => (1.0986841134678099660398011952406+0.455089860562227341304357757822468i)
|
|
643
|
+
*/
|
|
644
|
+
static VALUE
|
|
645
|
+
quadmath_sqrt(VALUE unused_obj, VALUE x)
|
|
646
|
+
{
|
|
647
|
+
|
|
648
|
+
switch (convertion_num_types(x)) {
|
|
649
|
+
case NUM_FIXNUM:
|
|
650
|
+
return quadmath_sqrt_realsolve(fixnum_to_cf128(x));
|
|
651
|
+
break;
|
|
652
|
+
case NUM_BIGNUM:
|
|
653
|
+
return quadmath_sqrt_realsolve(bignum_to_cf128(x));
|
|
654
|
+
break;
|
|
655
|
+
case NUM_RATIONAL:
|
|
656
|
+
return quadmath_sqrt_realsolve(rational_to_cf128(x));
|
|
657
|
+
break;
|
|
658
|
+
case NUM_FLOAT:
|
|
659
|
+
return quadmath_sqrt_realsolve(float_to_cf128(x));
|
|
660
|
+
break;
|
|
661
|
+
case NUM_COMPLEX:
|
|
662
|
+
VALUE nucomp = quadmath_sqrt_nucompsolve(nucomp_to_cc128(x));
|
|
663
|
+
return complex128_to_nucomp(nucomp);
|
|
664
|
+
break;
|
|
665
|
+
case NUM_FLOAT128:
|
|
666
|
+
return quadmath_sqrt_realsolve(GetF128(x));
|
|
667
|
+
break;
|
|
668
|
+
case NUM_COMPLEX128:
|
|
669
|
+
return quadmath_sqrt_nucompsolve(GetC128(x));
|
|
670
|
+
break;
|
|
671
|
+
case NUM_OTHERTYPE:
|
|
672
|
+
default:
|
|
673
|
+
if (num_real_p(x))
|
|
674
|
+
return quadmath_sqrt_realsolve(GetF128(x));
|
|
675
|
+
else
|
|
676
|
+
return quadmath_sqrt_nucompsolve(GetC128(x));
|
|
677
|
+
break;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
static inline VALUE
|
|
682
|
+
quadmath_sqrt3_realsolve(__float128 x)
|
|
683
|
+
{
|
|
684
|
+
if (!signbitq(x))
|
|
685
|
+
return rb_float128_cf128(cbrtq(x));
|
|
686
|
+
else
|
|
687
|
+
return rb_complex128_cc128(cpowq((__complex128)x, 1.q/3.q));
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
static inline VALUE
|
|
691
|
+
quadmath_sqrt3_nucompsolve(__complex128 z)
|
|
692
|
+
{
|
|
693
|
+
return rb_complex128_cc128(cpowq(z, (__complex128)(1.q/3.q)));
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/*
|
|
697
|
+
* call-seq:
|
|
698
|
+
* QuadMath.sqrt3(x) -> Float128 | Complex128
|
|
699
|
+
*
|
|
700
|
+
* xの立方根を返す.
|
|
701
|
+
* xが実数であり正の場合は実数解,負の場合は複素数解,複素数の場合は複素数解として各々返却する.
|
|
702
|
+
*
|
|
703
|
+
* QuadMath.sqrt3(3*3*3) # => 3.0
|
|
704
|
+
* QuadMath.sqrt3(-1) # => (0.5+0.866025403784438646763723170752936i)
|
|
705
|
+
* QuadMath.sqrt3(1+1i) # => (1.0842150814913511818796660082610+0.290514555507251444503813188624929i)
|
|
706
|
+
*/
|
|
707
|
+
static VALUE
|
|
708
|
+
quadmath_sqrt3(VALUE unused_obj, VALUE x)
|
|
709
|
+
{
|
|
710
|
+
switch (convertion_num_types(x)) {
|
|
711
|
+
case NUM_FIXNUM:
|
|
712
|
+
return quadmath_sqrt3_realsolve(fixnum_to_cf128(x));
|
|
713
|
+
break;
|
|
714
|
+
case NUM_BIGNUM:
|
|
715
|
+
return quadmath_sqrt3_realsolve(bignum_to_cf128(x));
|
|
716
|
+
break;
|
|
717
|
+
case NUM_RATIONAL:
|
|
718
|
+
return quadmath_sqrt3_realsolve(rational_to_cf128(x));
|
|
719
|
+
break;
|
|
720
|
+
case NUM_FLOAT:
|
|
721
|
+
return quadmath_sqrt3_realsolve(float_to_cf128(x));
|
|
722
|
+
break;
|
|
723
|
+
case NUM_COMPLEX:
|
|
724
|
+
VALUE nucomp = quadmath_sqrt3_nucompsolve(nucomp_to_cc128(x));
|
|
725
|
+
return complex128_to_nucomp(nucomp);
|
|
726
|
+
break;
|
|
727
|
+
case NUM_FLOAT128:
|
|
728
|
+
return quadmath_sqrt3_realsolve(GetF128(x));
|
|
729
|
+
break;
|
|
730
|
+
case NUM_COMPLEX128:
|
|
731
|
+
return quadmath_sqrt3_nucompsolve(GetC128(x));
|
|
732
|
+
break;
|
|
733
|
+
case NUM_OTHERTYPE:
|
|
734
|
+
default:
|
|
735
|
+
if (num_real_p(x))
|
|
736
|
+
return quadmath_sqrt3_realsolve(GetF128(x));
|
|
737
|
+
else
|
|
738
|
+
return quadmath_sqrt3_nucompsolve(GetC128(x));
|
|
739
|
+
break;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
static inline VALUE
|
|
744
|
+
quadmath_cbrt_realsolve(__float128 x)
|
|
745
|
+
{
|
|
746
|
+
return rb_float128_cf128(cbrtq(x));
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
static inline VALUE
|
|
750
|
+
quadmath_cbrt_nucompsolve(__complex128 z)
|
|
751
|
+
{
|
|
752
|
+
if (cimagq(z) != 0)
|
|
753
|
+
return Qnil;
|
|
754
|
+
|
|
755
|
+
return quadmath_cbrt_realsolve(crealq(z));
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
/*
|
|
759
|
+
* call-seq:
|
|
760
|
+
* QuadMath.cbrt(x) -> Float128 | nil
|
|
761
|
+
*
|
|
762
|
+
* xの実数としての三乗根を返す.
|
|
763
|
+
* 実計算の'x ** 1/3'における複素根はcbrt関数では扱われない.そのため虚数が現れるならnilとして扱われる.
|
|
764
|
+
*
|
|
765
|
+
* QuadMath.cbrt(3*3*3) # => 3.0
|
|
766
|
+
* QuadMath.cbrt(-1) # => -1.0
|
|
767
|
+
* QuadMath.cbrt(1+1i) # => nil
|
|
768
|
+
*/
|
|
769
|
+
static VALUE
|
|
770
|
+
quadmath_cbrt(VALUE unused_obj, VALUE x)
|
|
771
|
+
{
|
|
772
|
+
switch (convertion_num_types(x)) {
|
|
773
|
+
case NUM_FIXNUM:
|
|
774
|
+
return quadmath_cbrt_realsolve(fixnum_to_cf128(x));
|
|
775
|
+
break;
|
|
776
|
+
case NUM_BIGNUM:
|
|
777
|
+
return quadmath_cbrt_realsolve(bignum_to_cf128(x));
|
|
778
|
+
break;
|
|
779
|
+
case NUM_RATIONAL:
|
|
780
|
+
return quadmath_cbrt_realsolve(rational_to_cf128(x));
|
|
781
|
+
break;
|
|
782
|
+
case NUM_FLOAT:
|
|
783
|
+
return quadmath_cbrt_realsolve(float_to_cf128(x));
|
|
784
|
+
break;
|
|
785
|
+
case NUM_COMPLEX:
|
|
786
|
+
return quadmath_cbrt_nucompsolve(nucomp_to_cc128(x));
|
|
787
|
+
break;
|
|
788
|
+
case NUM_FLOAT128:
|
|
789
|
+
return quadmath_cbrt_realsolve(GetF128(x));
|
|
790
|
+
break;
|
|
791
|
+
case NUM_COMPLEX128:
|
|
792
|
+
return quadmath_cbrt_nucompsolve(GetC128(x));
|
|
793
|
+
break;
|
|
794
|
+
case NUM_OTHERTYPE:
|
|
795
|
+
default:
|
|
796
|
+
if (num_real_p(x))
|
|
797
|
+
return quadmath_cbrt_realsolve(GetF128(x));
|
|
798
|
+
else
|
|
799
|
+
return quadmath_cbrt_nucompsolve(GetC128(x));
|
|
800
|
+
break;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
static inline VALUE
|
|
805
|
+
quadmath_sin_realsolve(__float128 x)
|
|
806
|
+
{
|
|
807
|
+
return rb_float128_cf128(sinq(x));
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
static inline VALUE
|
|
811
|
+
quadmath_sin_nucompsolve(__complex128 z)
|
|
812
|
+
{
|
|
813
|
+
return rb_complex128_cc128(csinq(z));
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
/*
|
|
817
|
+
* call-seq:
|
|
818
|
+
* QuadMath.sin(x) -> Float128 | Complex128
|
|
819
|
+
*
|
|
820
|
+
* xの正弦を返す.
|
|
821
|
+
* xが実数なら実数解,複素数なら複素数解として各々返却する.
|
|
822
|
+
*
|
|
823
|
+
* QuadMath.sin(0.5r * QuadMath::PI) / 0.5r # => 2.0
|
|
824
|
+
* QuadMath.sin(1+1i) # => (1.2984575814159772948260423658078+0.634963914784736108255082202991509i)
|
|
825
|
+
*/
|
|
826
|
+
static VALUE
|
|
827
|
+
quadmath_sin(VALUE unused_obj, VALUE x)
|
|
828
|
+
{
|
|
829
|
+
switch (convertion_num_types(x)) {
|
|
830
|
+
case NUM_FIXNUM:
|
|
831
|
+
return quadmath_sin_realsolve(fixnum_to_cf128(x));
|
|
832
|
+
break;
|
|
833
|
+
case NUM_BIGNUM:
|
|
834
|
+
return quadmath_sin_realsolve(bignum_to_cf128(x));
|
|
835
|
+
break;
|
|
836
|
+
case NUM_RATIONAL:
|
|
837
|
+
return quadmath_sin_realsolve(rational_to_cf128(x));
|
|
838
|
+
break;
|
|
839
|
+
case NUM_FLOAT:
|
|
840
|
+
return quadmath_sin_realsolve(float_to_cf128(x));
|
|
841
|
+
break;
|
|
842
|
+
case NUM_COMPLEX:
|
|
843
|
+
VALUE nucomp = quadmath_sin_nucompsolve(nucomp_to_cc128(x));
|
|
844
|
+
return complex128_to_nucomp(nucomp);
|
|
845
|
+
break;
|
|
846
|
+
case NUM_FLOAT128:
|
|
847
|
+
return quadmath_sin_realsolve(GetF128(x));
|
|
848
|
+
break;
|
|
849
|
+
case NUM_COMPLEX128:
|
|
850
|
+
return quadmath_sin_nucompsolve(GetC128(x));
|
|
851
|
+
break;
|
|
852
|
+
case NUM_OTHERTYPE:
|
|
853
|
+
default:
|
|
854
|
+
if (num_real_p(x))
|
|
855
|
+
return quadmath_sin_realsolve(GetF128(x));
|
|
856
|
+
else
|
|
857
|
+
return quadmath_sin_nucompsolve(GetC128(x));
|
|
858
|
+
break;
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
static inline VALUE
|
|
863
|
+
quadmath_cos_realsolve(__float128 x)
|
|
864
|
+
{
|
|
865
|
+
return rb_float128_cf128(cosq(x));
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
static inline VALUE
|
|
869
|
+
quadmath_cos_nucompsolve(__complex128 z)
|
|
870
|
+
{
|
|
871
|
+
return rb_complex128_cc128(ccosq(z));
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
/*
|
|
875
|
+
* call-seq:
|
|
876
|
+
* QuadMath.cos(x) -> Float128 | Complex128
|
|
877
|
+
*
|
|
878
|
+
* xの余弦を返す.
|
|
879
|
+
* xが実数なら実数解,複素数なら複素数解として各々返却する.
|
|
880
|
+
*
|
|
881
|
+
* QuadMath.cos(0.5r * QuadMath::PI) / 0.5r # => 8.67181013012378102479704402604335e-35
|
|
882
|
+
* QuadMath.cos(1+1i) # => (0.833730025131149048883885394335094-0.988897705762865096382129540892686i)
|
|
883
|
+
*/
|
|
884
|
+
static VALUE
|
|
885
|
+
quadmath_cos(VALUE unused_obj, VALUE x)
|
|
886
|
+
{
|
|
887
|
+
switch (convertion_num_types(x)) {
|
|
888
|
+
case NUM_FIXNUM:
|
|
889
|
+
return quadmath_cos_realsolve(fixnum_to_cf128(x));
|
|
890
|
+
break;
|
|
891
|
+
case NUM_BIGNUM:
|
|
892
|
+
return quadmath_cos_realsolve(bignum_to_cf128(x));
|
|
893
|
+
break;
|
|
894
|
+
case NUM_RATIONAL:
|
|
895
|
+
return quadmath_cos_realsolve(rational_to_cf128(x));
|
|
896
|
+
break;
|
|
897
|
+
case NUM_FLOAT:
|
|
898
|
+
return quadmath_cos_realsolve(float_to_cf128(x));
|
|
899
|
+
break;
|
|
900
|
+
case NUM_COMPLEX:
|
|
901
|
+
VALUE nucomp = quadmath_cos_nucompsolve(nucomp_to_cc128(x));
|
|
902
|
+
return complex128_to_nucomp(nucomp);
|
|
903
|
+
break;
|
|
904
|
+
case NUM_FLOAT128:
|
|
905
|
+
return quadmath_cos_realsolve(GetF128(x));
|
|
906
|
+
break;
|
|
907
|
+
case NUM_COMPLEX128:
|
|
908
|
+
return quadmath_cos_nucompsolve(GetC128(x));
|
|
909
|
+
break;
|
|
910
|
+
case NUM_OTHERTYPE:
|
|
911
|
+
default:
|
|
912
|
+
if (num_real_p(x))
|
|
913
|
+
return quadmath_cos_realsolve(GetF128(x));
|
|
914
|
+
else
|
|
915
|
+
return quadmath_cos_nucompsolve(GetC128(x));
|
|
916
|
+
break;
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
static inline __float128
|
|
921
|
+
tan_realsolve(__float128 x)
|
|
922
|
+
{
|
|
923
|
+
__float128 y;
|
|
924
|
+
switch (fpclassify(x)) {
|
|
925
|
+
case FP_NAN:
|
|
926
|
+
case FP_INFINITE:
|
|
927
|
+
y = nanq("");
|
|
928
|
+
break;
|
|
929
|
+
case FP_ZERO:
|
|
930
|
+
y = 0.q;
|
|
931
|
+
break;
|
|
932
|
+
default:
|
|
933
|
+
y = fmodq(fabsq(x), M_PIq * 2);
|
|
934
|
+
if (y == M_PI_2q)
|
|
935
|
+
y = copysignq(HUGE_VALQ, x);
|
|
936
|
+
else if (y == M_PIq)
|
|
937
|
+
y = 0.q;
|
|
938
|
+
else
|
|
939
|
+
y = tanq(x);
|
|
940
|
+
break;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
return y;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
static inline VALUE
|
|
947
|
+
quadmath_tan_realsolve(__float128 x)
|
|
948
|
+
{
|
|
949
|
+
return rb_float128_cf128(tan_realsolve(x));
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
static inline VALUE
|
|
953
|
+
quadmath_tan_nucompsolve(__complex128 z)
|
|
954
|
+
{
|
|
955
|
+
if (cimagq(z) == 0)
|
|
956
|
+
__real__ z = tan_realsolve(crealq(z));
|
|
957
|
+
else
|
|
958
|
+
z = ctanq(z);
|
|
959
|
+
return rb_complex128_cc128(z);
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
/*
|
|
963
|
+
* call-seq:
|
|
964
|
+
* QuadMath.tan(x) -> Float128 | Complex128
|
|
965
|
+
*
|
|
966
|
+
* xの正接を返す.
|
|
967
|
+
* xが実数なら実数解,複素数なら複素数解として各々返却する.
|
|
968
|
+
* この関数はxは周期性$2\pi$として虚数の現れていない数なら極と解釈し,特殊値を返す.
|
|
969
|
+
* 特殊値の送出は$-2\pi \le x \le 2\pi$の範囲内では正確な答を期待できる.しかし,範囲外で正確かどうかは機種依存である.
|
|
970
|
+
*
|
|
971
|
+
* QuadMath.tan(QuadMath.atan(Float128::INFINITY)) # => Infinity
|
|
972
|
+
* QuadMath.tan(3/4r * QuadMath::PI) # => -1.0
|
|
973
|
+
* QuadMath.tan(1+1i) # => (0.271752585319511716528843722498589+1.0839233273386945434757520612119i)
|
|
974
|
+
|
|
975
|
+
*/
|
|
976
|
+
static VALUE
|
|
977
|
+
quadmath_tan(VALUE unused_obj, VALUE x)
|
|
978
|
+
{
|
|
979
|
+
switch (convertion_num_types(x)) {
|
|
980
|
+
case NUM_FIXNUM:
|
|
981
|
+
return quadmath_tan_realsolve(fixnum_to_cf128(x));
|
|
982
|
+
break;
|
|
983
|
+
case NUM_BIGNUM:
|
|
984
|
+
return quadmath_tan_realsolve(bignum_to_cf128(x));
|
|
985
|
+
break;
|
|
986
|
+
case NUM_RATIONAL:
|
|
987
|
+
return quadmath_tan_realsolve(rational_to_cf128(x));
|
|
988
|
+
break;
|
|
989
|
+
case NUM_FLOAT:
|
|
990
|
+
return quadmath_tan_realsolve(float_to_cf128(x));
|
|
991
|
+
break;
|
|
992
|
+
case NUM_COMPLEX:
|
|
993
|
+
VALUE nucomp = quadmath_tan_nucompsolve(nucomp_to_cc128(x));
|
|
994
|
+
return complex128_to_nucomp(nucomp);
|
|
995
|
+
break;
|
|
996
|
+
case NUM_FLOAT128:
|
|
997
|
+
return quadmath_tan_realsolve(GetF128(x));
|
|
998
|
+
break;
|
|
999
|
+
case NUM_COMPLEX128:
|
|
1000
|
+
return quadmath_tan_nucompsolve(GetC128(x));
|
|
1001
|
+
break;
|
|
1002
|
+
case NUM_OTHERTYPE:
|
|
1003
|
+
default:
|
|
1004
|
+
if (num_real_p(x))
|
|
1005
|
+
return quadmath_tan_realsolve(GetF128(x));
|
|
1006
|
+
else
|
|
1007
|
+
return quadmath_tan_nucompsolve(GetC128(x));
|
|
1008
|
+
break;
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
static inline VALUE
|
|
1013
|
+
quadmath_asin_realsolve(__float128 x)
|
|
1014
|
+
{
|
|
1015
|
+
if (x >= -1 && x <= 1)
|
|
1016
|
+
return rb_float128_cf128(asinq(x));
|
|
1017
|
+
else
|
|
1018
|
+
return rb_complex128_cc128(casinq((__complex128)x));
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
static inline VALUE
|
|
1022
|
+
quadmath_asin_nucompsolve(__complex128 z)
|
|
1023
|
+
{
|
|
1024
|
+
return rb_complex128_cc128(casinq(z));
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
/*
|
|
1028
|
+
* call-seq:
|
|
1029
|
+
* QuadMath.asin(x) -> Float128 | Complex128
|
|
1030
|
+
*
|
|
1031
|
+
* xの逆正弦を返す.
|
|
1032
|
+
* xが(-1<=x<=1)の範囲なら実数解,ほかは複素数解として各々返却する.
|
|
1033
|
+
*
|
|
1034
|
+
* QuadMath.asin(-1/4r) # => -0.252680255142078653485657436993711
|
|
1035
|
+
* QuadMath.asin(5/4r) # => (1.5707963267948966192313216916397+0.693147180559945309417232121458176i)
|
|
1036
|
+
* QuadMath.asin(1+1i) # => (0.666239432492515255104004895977792+1.0612750619050356520330189162135i)
|
|
1037
|
+
|
|
1038
|
+
*/
|
|
1039
|
+
static VALUE
|
|
1040
|
+
quadmath_asin(VALUE unused_obj, VALUE x)
|
|
1041
|
+
{
|
|
1042
|
+
switch (convertion_num_types(x)) {
|
|
1043
|
+
case NUM_FIXNUM:
|
|
1044
|
+
return quadmath_asin_realsolve(fixnum_to_cf128(x));
|
|
1045
|
+
break;
|
|
1046
|
+
case NUM_BIGNUM:
|
|
1047
|
+
return quadmath_asin_realsolve(bignum_to_cf128(x));
|
|
1048
|
+
break;
|
|
1049
|
+
case NUM_RATIONAL:
|
|
1050
|
+
return quadmath_asin_realsolve(rational_to_cf128(x));
|
|
1051
|
+
break;
|
|
1052
|
+
case NUM_FLOAT:
|
|
1053
|
+
return quadmath_asin_realsolve(float_to_cf128(x));
|
|
1054
|
+
break;
|
|
1055
|
+
case NUM_COMPLEX:
|
|
1056
|
+
VALUE nucomp = quadmath_asin_nucompsolve(nucomp_to_cc128(x));
|
|
1057
|
+
return complex128_to_nucomp(nucomp);
|
|
1058
|
+
break;
|
|
1059
|
+
case NUM_FLOAT128:
|
|
1060
|
+
return quadmath_asin_realsolve(GetF128(x));
|
|
1061
|
+
break;
|
|
1062
|
+
case NUM_COMPLEX128:
|
|
1063
|
+
return quadmath_asin_nucompsolve(GetC128(x));
|
|
1064
|
+
break;
|
|
1065
|
+
case NUM_OTHERTYPE:
|
|
1066
|
+
default:
|
|
1067
|
+
if (num_real_p(x))
|
|
1068
|
+
return quadmath_asin_realsolve(GetF128(x));
|
|
1069
|
+
else
|
|
1070
|
+
return quadmath_asin_nucompsolve(GetC128(x));
|
|
1071
|
+
break;
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
static inline VALUE
|
|
1076
|
+
quadmath_acos_realsolve(__float128 x)
|
|
1077
|
+
{
|
|
1078
|
+
if (x >= -1 && x <= 1)
|
|
1079
|
+
return rb_float128_cf128(acosq(x));
|
|
1080
|
+
else
|
|
1081
|
+
return rb_complex128_cc128(cacosq((__complex128)x));
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
static inline VALUE
|
|
1085
|
+
quadmath_acos_nucompsolve(__complex128 z)
|
|
1086
|
+
{
|
|
1087
|
+
return rb_complex128_cc128(cacosq(z));
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
/*
|
|
1091
|
+
* call-seq:
|
|
1092
|
+
* QuadMath.acos(x) -> Float128 | Complex128
|
|
1093
|
+
*
|
|
1094
|
+
* xの逆余弦を返す.
|
|
1095
|
+
* xが(-1<=x<=1)の範囲なら実数解,ほかは複素数解として各々返却する.
|
|
1096
|
+
*
|
|
1097
|
+
* QuadMath.acos(-1/4r) # => 1.8234765819369752727169791286334
|
|
1098
|
+
* QuadMath.acos(5/4r) # => (0.0-0.693147180559945309417232121458176i)
|
|
1099
|
+
* QuadMath.acos(1+1i) # => (0.904556894302381364127316795661958-1.0612750619050356520330189162135i)
|
|
1100
|
+
*/
|
|
1101
|
+
static VALUE
|
|
1102
|
+
quadmath_acos(VALUE unused_obj, VALUE x)
|
|
1103
|
+
{
|
|
1104
|
+
switch (convertion_num_types(x)) {
|
|
1105
|
+
case NUM_FIXNUM:
|
|
1106
|
+
return quadmath_acos_realsolve(fixnum_to_cf128(x));
|
|
1107
|
+
break;
|
|
1108
|
+
case NUM_BIGNUM:
|
|
1109
|
+
return quadmath_acos_realsolve(bignum_to_cf128(x));
|
|
1110
|
+
break;
|
|
1111
|
+
case NUM_RATIONAL:
|
|
1112
|
+
return quadmath_acos_realsolve(rational_to_cf128(x));
|
|
1113
|
+
break;
|
|
1114
|
+
case NUM_FLOAT:
|
|
1115
|
+
return quadmath_acos_realsolve(float_to_cf128(x));
|
|
1116
|
+
break;
|
|
1117
|
+
case NUM_COMPLEX:
|
|
1118
|
+
VALUE nucomp = quadmath_acos_nucompsolve(nucomp_to_cc128(x));
|
|
1119
|
+
return complex128_to_nucomp(nucomp);
|
|
1120
|
+
break;
|
|
1121
|
+
case NUM_FLOAT128:
|
|
1122
|
+
return quadmath_acos_realsolve(GetF128(x));
|
|
1123
|
+
break;
|
|
1124
|
+
case NUM_COMPLEX128:
|
|
1125
|
+
return quadmath_acos_nucompsolve(GetC128(x));
|
|
1126
|
+
break;
|
|
1127
|
+
case NUM_OTHERTYPE:
|
|
1128
|
+
default:
|
|
1129
|
+
if (num_real_p(x))
|
|
1130
|
+
return quadmath_acos_realsolve(GetF128(x));
|
|
1131
|
+
else
|
|
1132
|
+
return quadmath_acos_nucompsolve(GetC128(x));
|
|
1133
|
+
break;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
static inline VALUE
|
|
1138
|
+
quadmath_atan_realsolve(__float128 x)
|
|
1139
|
+
{
|
|
1140
|
+
return rb_float128_cf128(atanq(x));
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
static inline VALUE
|
|
1144
|
+
quadmath_atan_nucompsolve(__complex128 z)
|
|
1145
|
+
{
|
|
1146
|
+
return rb_complex128_cc128(catanq(z));
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
/*
|
|
1150
|
+
* call-seq:
|
|
1151
|
+
* QuadMath.atan(x) -> Float128 | Complex128
|
|
1152
|
+
*
|
|
1153
|
+
* xの逆正接を返す.
|
|
1154
|
+
* xが実数なら実数解,複素数なら複素数解として各々返却する.
|
|
1155
|
+
*
|
|
1156
|
+
* QuadMath.atan(-Float128::INFINITY) == (-QuadMath::PI/2) # => true
|
|
1157
|
+
* QuadMath.atan(+Float128::INFINITY) == (+QuadMath::PI/2) # => true
|
|
1158
|
+
* QuadMath.atan(1+1i) # => (1.0172219678978513677227889615504+0.402359478108525093650189833306547i)
|
|
1159
|
+
*/
|
|
1160
|
+
static VALUE
|
|
1161
|
+
quadmath_atan(VALUE unused_obj, VALUE x)
|
|
1162
|
+
{
|
|
1163
|
+
switch (convertion_num_types(x)) {
|
|
1164
|
+
case NUM_FIXNUM:
|
|
1165
|
+
return quadmath_atan_realsolve(fixnum_to_cf128(x));
|
|
1166
|
+
break;
|
|
1167
|
+
case NUM_BIGNUM:
|
|
1168
|
+
return quadmath_atan_realsolve(bignum_to_cf128(x));
|
|
1169
|
+
break;
|
|
1170
|
+
case NUM_RATIONAL:
|
|
1171
|
+
return quadmath_atan_realsolve(rational_to_cf128(x));
|
|
1172
|
+
break;
|
|
1173
|
+
case NUM_FLOAT:
|
|
1174
|
+
return quadmath_atan_realsolve(float_to_cf128(x));
|
|
1175
|
+
break;
|
|
1176
|
+
case NUM_COMPLEX:
|
|
1177
|
+
VALUE nucomp = quadmath_atan_nucompsolve(nucomp_to_cc128(x));
|
|
1178
|
+
return complex128_to_nucomp(nucomp);
|
|
1179
|
+
break;
|
|
1180
|
+
case NUM_FLOAT128:
|
|
1181
|
+
return quadmath_atan_realsolve(GetF128(x));
|
|
1182
|
+
break;
|
|
1183
|
+
case NUM_COMPLEX128:
|
|
1184
|
+
return quadmath_atan_nucompsolve(GetC128(x));
|
|
1185
|
+
break;
|
|
1186
|
+
case NUM_OTHERTYPE:
|
|
1187
|
+
default:
|
|
1188
|
+
if (num_real_p(x))
|
|
1189
|
+
return quadmath_atan_realsolve(GetF128(x));
|
|
1190
|
+
else
|
|
1191
|
+
return quadmath_atan_nucompsolve(GetC128(x));
|
|
1192
|
+
break;
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
|
|
1197
|
+
static inline VALUE
|
|
1198
|
+
quadmath_quadrant_realsolve(__float128 x, __float128 y)
|
|
1199
|
+
{
|
|
1200
|
+
return rb_float128_cf128(atan2q(y, x));
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
static inline __complex128
|
|
1204
|
+
catan2q(__complex128 w, __complex128 z)
|
|
1205
|
+
{
|
|
1206
|
+
if (cimagq(z) == 0 && cimagq(w) == 0)
|
|
1207
|
+
{
|
|
1208
|
+
return (__complex128)atan2q(crealq(w), crealq(z));
|
|
1209
|
+
}
|
|
1210
|
+
else
|
|
1211
|
+
{
|
|
1212
|
+
__complex128 c1 = 0-1i;
|
|
1213
|
+
__complex128 c2 = z + 0+1i * w;
|
|
1214
|
+
__complex128 c3 = csqrtq(z * z + w * w);
|
|
1215
|
+
return c1 * clogq(c2 / c3);
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
static inline VALUE
|
|
1220
|
+
quadmath_quadrant_nucompsolve(__complex128 z, __complex128 w)
|
|
1221
|
+
{
|
|
1222
|
+
return rb_complex128_cc128(catan2q(w, z));
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
static VALUE
|
|
1226
|
+
quadrant_inline(VALUE xsh, VALUE ysh)
|
|
1227
|
+
{
|
|
1228
|
+
VALUE nucomp;
|
|
1229
|
+
static __float128 x, y;
|
|
1230
|
+
static __complex128 z, w;
|
|
1231
|
+
bool x_nucomp_p = false, y_nucomp_p = false, using_rb_complex = false;
|
|
1232
|
+
|
|
1233
|
+
switch (convertion_num_types(xsh)) {
|
|
1234
|
+
case NUM_FIXNUM:
|
|
1235
|
+
x = fixnum_to_cf128(xsh);
|
|
1236
|
+
break;
|
|
1237
|
+
case NUM_BIGNUM:
|
|
1238
|
+
x = bignum_to_cf128(xsh);
|
|
1239
|
+
break;
|
|
1240
|
+
case NUM_RATIONAL:
|
|
1241
|
+
x = rational_to_cf128(xsh);
|
|
1242
|
+
break;
|
|
1243
|
+
case NUM_FLOAT:
|
|
1244
|
+
x = float_to_cf128(xsh);
|
|
1245
|
+
break;
|
|
1246
|
+
case NUM_COMPLEX:
|
|
1247
|
+
z = nucomp_to_cc128(xsh);
|
|
1248
|
+
x_nucomp_p = true;
|
|
1249
|
+
using_rb_complex = true;
|
|
1250
|
+
break;
|
|
1251
|
+
case NUM_FLOAT128:
|
|
1252
|
+
x = GetF128(xsh);
|
|
1253
|
+
break;
|
|
1254
|
+
case NUM_COMPLEX128:
|
|
1255
|
+
z = GetC128(xsh);
|
|
1256
|
+
x_nucomp_p = true;
|
|
1257
|
+
break;
|
|
1258
|
+
case NUM_OTHERTYPE:
|
|
1259
|
+
default:
|
|
1260
|
+
if (num_real_p(xsh))
|
|
1261
|
+
x = GetF128(xsh);
|
|
1262
|
+
else
|
|
1263
|
+
{
|
|
1264
|
+
z = GetC128(xsh);
|
|
1265
|
+
x_nucomp_p = true;
|
|
1266
|
+
}
|
|
1267
|
+
break;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
switch (convertion_num_types(ysh)) {
|
|
1271
|
+
case NUM_FIXNUM:
|
|
1272
|
+
y = fixnum_to_cf128(ysh);
|
|
1273
|
+
break;
|
|
1274
|
+
case NUM_BIGNUM:
|
|
1275
|
+
y = bignum_to_cf128(ysh);
|
|
1276
|
+
break;
|
|
1277
|
+
case NUM_RATIONAL:
|
|
1278
|
+
y = rational_to_cf128(ysh);
|
|
1279
|
+
break;
|
|
1280
|
+
case NUM_FLOAT:
|
|
1281
|
+
y = float_to_cf128(ysh);
|
|
1282
|
+
break;
|
|
1283
|
+
case NUM_COMPLEX:
|
|
1284
|
+
w = nucomp_to_cc128(ysh);
|
|
1285
|
+
y_nucomp_p = true;
|
|
1286
|
+
using_rb_complex = true;
|
|
1287
|
+
break;
|
|
1288
|
+
case NUM_FLOAT128:
|
|
1289
|
+
y = GetF128(ysh);
|
|
1290
|
+
break;
|
|
1291
|
+
case NUM_COMPLEX128:
|
|
1292
|
+
w = GetC128(ysh);
|
|
1293
|
+
y_nucomp_p = true;
|
|
1294
|
+
break;
|
|
1295
|
+
case NUM_OTHERTYPE:
|
|
1296
|
+
default:
|
|
1297
|
+
if (num_real_p(ysh))
|
|
1298
|
+
y = GetF128(ysh);
|
|
1299
|
+
else
|
|
1300
|
+
{
|
|
1301
|
+
w = GetC128(ysh);
|
|
1302
|
+
y_nucomp_p = true;
|
|
1303
|
+
}
|
|
1304
|
+
break;
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
if (x_nucomp_p && y_nucomp_p)
|
|
1308
|
+
nucomp = quadmath_quadrant_nucompsolve(z, w);
|
|
1309
|
+
else if (x_nucomp_p && !y_nucomp_p)
|
|
1310
|
+
nucomp = quadmath_quadrant_nucompsolve(z, y);
|
|
1311
|
+
else if (!x_nucomp_p && y_nucomp_p)
|
|
1312
|
+
nucomp = quadmath_quadrant_nucompsolve(x, w);
|
|
1313
|
+
else
|
|
1314
|
+
return quadmath_quadrant_realsolve(x, y);
|
|
1315
|
+
if (using_rb_complex)
|
|
1316
|
+
return complex128_to_nucomp(nucomp);
|
|
1317
|
+
else
|
|
1318
|
+
return nucomp;
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
/*
|
|
1322
|
+
* call-seq:
|
|
1323
|
+
* QuadMath.atan2(y, x) -> Float128 | Complex128
|
|
1324
|
+
*
|
|
1325
|
+
* xとyが象限のどのあたりにあるかを考慮し,atan(y/x)の答を返す.
|
|
1326
|
+
* 2変数に虚数が現れているならば `-i log( (x+iy) sqrt(x^2 + y^2))`を計算する.
|
|
1327
|
+
*
|
|
1328
|
+
* x = 2; y = 1.2r
|
|
1329
|
+
* QuadMath.atan2(y, x) # => 0.5404195002705841554435783646086
|
|
1330
|
+
* x = -2.1r; y = 1.2r+1i
|
|
1331
|
+
* QuadMath.atan2(y, x) # => (2.5425012953584908680165071231190-0.356967696991407745539638230102346i)
|
|
1332
|
+
*/
|
|
1333
|
+
static VALUE
|
|
1334
|
+
quadmath_atan2(VALUE unused_obj, VALUE y, VALUE x)
|
|
1335
|
+
{
|
|
1336
|
+
return quadrant_inline(x, y);
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
/*
|
|
1340
|
+
* call-seq:
|
|
1341
|
+
* QuadMath.quadrant(x, y) -> Float128 | Complex128
|
|
1342
|
+
*
|
|
1343
|
+
* xとyが象限のどのあたりにあるかを考慮し,atan(y/x)の答を返す.
|
|
1344
|
+
* 2変数に虚数が現れているならば `-i log( (x+iy) sqrt(x^2 + y^2))`を計算する.
|
|
1345
|
+
* この関数はatan2のaliasであるものの,引数の順番を考慮している.
|
|
1346
|
+
*
|
|
1347
|
+
* x = 2; y = 1.2r
|
|
1348
|
+
* QuadMath.quadrant(x, y) # => 0.5404195002705841554435783646086
|
|
1349
|
+
* x = -2.1r; y = 1.2r+1i
|
|
1350
|
+
* QuadMath.quadrant(x, y) # => (2.5425012953584908680165071231190-0.356967696991407745539638230102346i)
|
|
1351
|
+
*/
|
|
1352
|
+
static VALUE
|
|
1353
|
+
quadmath_quadrant(VALUE unused_obj, VALUE x, VALUE y)
|
|
1354
|
+
{
|
|
1355
|
+
return quadrant_inline(x, y);
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
static inline VALUE
|
|
1359
|
+
quadmath_sinh_realsolve(__float128 x)
|
|
1360
|
+
{
|
|
1361
|
+
return rb_float128_cf128(sinhq(x));
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
static inline VALUE
|
|
1365
|
+
quadmath_sinh_nucompsolve(__complex128 x)
|
|
1366
|
+
{
|
|
1367
|
+
return rb_complex128_cc128(csinhq(x));
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
/*
|
|
1371
|
+
* call-seq:
|
|
1372
|
+
* QuadMath.sinh(x) -> Float128 | Complex128
|
|
1373
|
+
*
|
|
1374
|
+
* xの双曲線正弦を返す.
|
|
1375
|
+
* xが実数なら実数解,複素数なら複素数解として各々返却する.
|
|
1376
|
+
*
|
|
1377
|
+
* QuadMath.sinh(1.2r) # => 1.5094613554121726964428949112592
|
|
1378
|
+
* QuadMath.sinh(1+1i) # => (0.634963914784736108255082202991509+1.2984575814159772948260423658078i)
|
|
1379
|
+
*/
|
|
1380
|
+
static VALUE
|
|
1381
|
+
quadmath_sinh(VALUE unused_obj, VALUE x)
|
|
1382
|
+
{
|
|
1383
|
+
switch (convertion_num_types(x)) {
|
|
1384
|
+
case NUM_FIXNUM:
|
|
1385
|
+
return quadmath_sinh_realsolve(fixnum_to_cf128(x));
|
|
1386
|
+
break;
|
|
1387
|
+
case NUM_BIGNUM:
|
|
1388
|
+
return quadmath_sinh_realsolve(bignum_to_cf128(x));
|
|
1389
|
+
break;
|
|
1390
|
+
case NUM_RATIONAL:
|
|
1391
|
+
return quadmath_sinh_realsolve(rational_to_cf128(x));
|
|
1392
|
+
break;
|
|
1393
|
+
case NUM_FLOAT:
|
|
1394
|
+
return quadmath_sinh_realsolve(float_to_cf128(x));
|
|
1395
|
+
break;
|
|
1396
|
+
case NUM_COMPLEX:
|
|
1397
|
+
VALUE nucomp = quadmath_sinh_nucompsolve(nucomp_to_cc128(x));
|
|
1398
|
+
return complex128_to_nucomp(nucomp);
|
|
1399
|
+
break;
|
|
1400
|
+
case NUM_FLOAT128:
|
|
1401
|
+
return quadmath_sinh_realsolve(GetF128(x));
|
|
1402
|
+
break;
|
|
1403
|
+
case NUM_COMPLEX128:
|
|
1404
|
+
return quadmath_sinh_nucompsolve(GetC128(x));
|
|
1405
|
+
break;
|
|
1406
|
+
case NUM_OTHERTYPE:
|
|
1407
|
+
default:
|
|
1408
|
+
if (num_real_p(x))
|
|
1409
|
+
return quadmath_sinh_realsolve(GetF128(x));
|
|
1410
|
+
else
|
|
1411
|
+
return quadmath_sinh_nucompsolve(GetC128(x));
|
|
1412
|
+
break;
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
static inline VALUE
|
|
1417
|
+
quadmath_cosh_realsolve(__float128 x)
|
|
1418
|
+
{
|
|
1419
|
+
return rb_float128_cf128(coshq(x));
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
static inline VALUE
|
|
1423
|
+
quadmath_cosh_nucompsolve(__complex128 x)
|
|
1424
|
+
{
|
|
1425
|
+
return rb_complex128_cc128(ccoshq(x));
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
/*
|
|
1429
|
+
* call-seq:
|
|
1430
|
+
* QuadMath.cosh(x) -> Float128 | Complex128
|
|
1431
|
+
*
|
|
1432
|
+
* xの双曲線余弦を返す.
|
|
1433
|
+
* xが実数なら実数解,複素数なら複素数解として各々返却する.
|
|
1434
|
+
*
|
|
1435
|
+
* QuadMath.cosh(1.2r) # => 1.8106555673243747930878725183424
|
|
1436
|
+
* QuadMath.cosh(1+1i) # => (0.833730025131149048883885394335094+0.988897705762865096382129540892686i)
|
|
1437
|
+
*/
|
|
1438
|
+
static VALUE
|
|
1439
|
+
quadmath_cosh(VALUE unused_obj, VALUE x)
|
|
1440
|
+
{
|
|
1441
|
+
switch (convertion_num_types(x)) {
|
|
1442
|
+
case NUM_FIXNUM:
|
|
1443
|
+
return quadmath_cosh_realsolve(fixnum_to_cf128(x));
|
|
1444
|
+
break;
|
|
1445
|
+
case NUM_BIGNUM:
|
|
1446
|
+
return quadmath_cosh_realsolve(bignum_to_cf128(x));
|
|
1447
|
+
break;
|
|
1448
|
+
case NUM_RATIONAL:
|
|
1449
|
+
return quadmath_cosh_realsolve(rational_to_cf128(x));
|
|
1450
|
+
break;
|
|
1451
|
+
case NUM_FLOAT:
|
|
1452
|
+
return quadmath_cosh_realsolve(float_to_cf128(x));
|
|
1453
|
+
break;
|
|
1454
|
+
case NUM_COMPLEX:
|
|
1455
|
+
VALUE nucomp = quadmath_cosh_nucompsolve(nucomp_to_cc128(x));
|
|
1456
|
+
return complex128_to_nucomp(nucomp);
|
|
1457
|
+
break;
|
|
1458
|
+
case NUM_FLOAT128:
|
|
1459
|
+
return quadmath_cosh_realsolve(GetF128(x));
|
|
1460
|
+
break;
|
|
1461
|
+
case NUM_COMPLEX128:
|
|
1462
|
+
return quadmath_cosh_nucompsolve(GetC128(x));
|
|
1463
|
+
break;
|
|
1464
|
+
case NUM_OTHERTYPE:
|
|
1465
|
+
default:
|
|
1466
|
+
if (num_real_p(x))
|
|
1467
|
+
return quadmath_cosh_realsolve(GetF128(x));
|
|
1468
|
+
else
|
|
1469
|
+
return quadmath_cosh_nucompsolve(GetC128(x));
|
|
1470
|
+
break;
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
static inline VALUE
|
|
1475
|
+
quadmath_tanh_realsolve(__float128 x)
|
|
1476
|
+
{
|
|
1477
|
+
return rb_float128_cf128(tanhq(x));
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
static inline VALUE
|
|
1481
|
+
quadmath_tanh_nucompsolve(__complex128 x)
|
|
1482
|
+
{
|
|
1483
|
+
return rb_complex128_cc128(ctanhq(x));
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
/*
|
|
1487
|
+
* call-seq:
|
|
1488
|
+
* QuadMath.tanh(x) -> Float128 | Complex128
|
|
1489
|
+
*
|
|
1490
|
+
* xの双曲線正接を返す.
|
|
1491
|
+
* xが実数なら実数解,複素数なら複素数解として各々返却する.
|
|
1492
|
+
*
|
|
1493
|
+
* QuadMath.tanh(+Float128::INFINITY) == +1 # => true
|
|
1494
|
+
* QuadMath.tanh(-Float128::INFINITY) == -1 # => true
|
|
1495
|
+
* QuadMath.tanh(1+1i) # => (1.0839233273386945434757520612119+0.271752585319511716528843722498589i)
|
|
1496
|
+
*/
|
|
1497
|
+
static VALUE
|
|
1498
|
+
quadmath_tanh(VALUE unused_obj, VALUE x)
|
|
1499
|
+
{
|
|
1500
|
+
switch (convertion_num_types(x)) {
|
|
1501
|
+
case NUM_FIXNUM:
|
|
1502
|
+
return quadmath_tanh_realsolve(fixnum_to_cf128(x));
|
|
1503
|
+
break;
|
|
1504
|
+
case NUM_BIGNUM:
|
|
1505
|
+
return quadmath_tanh_realsolve(bignum_to_cf128(x));
|
|
1506
|
+
break;
|
|
1507
|
+
case NUM_RATIONAL:
|
|
1508
|
+
return quadmath_tanh_realsolve(rational_to_cf128(x));
|
|
1509
|
+
break;
|
|
1510
|
+
case NUM_FLOAT:
|
|
1511
|
+
return quadmath_tanh_realsolve(float_to_cf128(x));
|
|
1512
|
+
break;
|
|
1513
|
+
case NUM_COMPLEX:
|
|
1514
|
+
VALUE nucomp = quadmath_tanh_nucompsolve(nucomp_to_cc128(x));
|
|
1515
|
+
return complex128_to_nucomp(nucomp);
|
|
1516
|
+
break;
|
|
1517
|
+
case NUM_FLOAT128:
|
|
1518
|
+
return quadmath_tanh_realsolve(GetF128(x));
|
|
1519
|
+
break;
|
|
1520
|
+
case NUM_COMPLEX128:
|
|
1521
|
+
return quadmath_tanh_nucompsolve(GetC128(x));
|
|
1522
|
+
break;
|
|
1523
|
+
case NUM_OTHERTYPE:
|
|
1524
|
+
default:
|
|
1525
|
+
if (num_real_p(x))
|
|
1526
|
+
return quadmath_tanh_realsolve(GetF128(x));
|
|
1527
|
+
else
|
|
1528
|
+
return quadmath_tanh_nucompsolve(GetC128(x));
|
|
1529
|
+
break;
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
static inline VALUE
|
|
1534
|
+
quadmath_asinh_realsolve(__float128 x)
|
|
1535
|
+
{
|
|
1536
|
+
return rb_float128_cf128(asinhq(x));
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
static inline VALUE
|
|
1540
|
+
quadmath_asinh_nucompsolve(__complex128 x)
|
|
1541
|
+
{
|
|
1542
|
+
return rb_complex128_cc128(casinhq(x));
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
/*
|
|
1546
|
+
* call-seq:
|
|
1547
|
+
* QuadMath.asinh(x) -> Float128 | Complex128
|
|
1548
|
+
*
|
|
1549
|
+
* xの逆双曲線正弦を返す.
|
|
1550
|
+
* xが実数なら実数解,複素数なら複素数解として各々返却する.
|
|
1551
|
+
*
|
|
1552
|
+
* QuadMath.asinh(1) # => 0.881373587019543025232609324979792
|
|
1553
|
+
* QuadMath.asinh(1+1i) # => (1.0612750619050356520330189162135+0.666239432492515255104004895977792i)
|
|
1554
|
+
*/
|
|
1555
|
+
static VALUE
|
|
1556
|
+
quadmath_asinh(VALUE unused_obj, VALUE x)
|
|
1557
|
+
{
|
|
1558
|
+
switch (convertion_num_types(x)) {
|
|
1559
|
+
case NUM_FIXNUM:
|
|
1560
|
+
return quadmath_asinh_realsolve(fixnum_to_cf128(x));
|
|
1561
|
+
break;
|
|
1562
|
+
case NUM_BIGNUM:
|
|
1563
|
+
return quadmath_asinh_realsolve(bignum_to_cf128(x));
|
|
1564
|
+
break;
|
|
1565
|
+
case NUM_RATIONAL:
|
|
1566
|
+
return quadmath_asinh_realsolve(rational_to_cf128(x));
|
|
1567
|
+
break;
|
|
1568
|
+
case NUM_FLOAT:
|
|
1569
|
+
return quadmath_asinh_realsolve(float_to_cf128(x));
|
|
1570
|
+
break;
|
|
1571
|
+
case NUM_COMPLEX:
|
|
1572
|
+
VALUE nucomp = quadmath_asinh_nucompsolve(nucomp_to_cc128(x));
|
|
1573
|
+
return complex128_to_nucomp(nucomp);
|
|
1574
|
+
break;
|
|
1575
|
+
case NUM_FLOAT128:
|
|
1576
|
+
return quadmath_asinh_realsolve(GetF128(x));
|
|
1577
|
+
break;
|
|
1578
|
+
case NUM_COMPLEX128:
|
|
1579
|
+
return quadmath_asinh_nucompsolve(GetC128(x));
|
|
1580
|
+
break;
|
|
1581
|
+
case NUM_OTHERTYPE:
|
|
1582
|
+
default:
|
|
1583
|
+
if (num_real_p(x))
|
|
1584
|
+
return quadmath_asinh_realsolve(GetF128(x));
|
|
1585
|
+
else
|
|
1586
|
+
return quadmath_asinh_nucompsolve(GetC128(x));
|
|
1587
|
+
break;
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
static inline VALUE
|
|
1592
|
+
quadmath_acosh_realsolve(__float128 x)
|
|
1593
|
+
{
|
|
1594
|
+
if (isnan(x))
|
|
1595
|
+
return rb_float128_cf128(nanq(""));
|
|
1596
|
+
if (x >= 1)
|
|
1597
|
+
return rb_float128_cf128(acoshq(x));
|
|
1598
|
+
else
|
|
1599
|
+
return rb_complex128_cc128(cacoshq((__complex128)x));
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
static inline VALUE
|
|
1603
|
+
quadmath_acosh_nucompsolve(__complex128 x)
|
|
1604
|
+
{
|
|
1605
|
+
return rb_complex128_cc128(cacoshq(x));
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
/*
|
|
1609
|
+
* call-seq:
|
|
1610
|
+
* QuadMath.acosh(x) -> Float128 | Complex128
|
|
1611
|
+
*
|
|
1612
|
+
* xの逆双曲線余弦を返す.
|
|
1613
|
+
* xが実数なら定義域(1<=x<=∞)は実数解,それ以外は複素数解,複素数なら複素数解として各々返却する.
|
|
1614
|
+
*
|
|
1615
|
+
* puts "%s %s" % [" (x)", " cosh^-1(x)"]
|
|
1616
|
+
* 0.step(20, 5){|x|
|
|
1617
|
+
* x/=10.0;
|
|
1618
|
+
* y = QuadMath.acosh(x)
|
|
1619
|
+
* y_str = y.to_s
|
|
1620
|
+
* if !y.real.negative? then y_str = " #{y.to_s}"; end
|
|
1621
|
+
* puts "%s %s" % [quadmath_sprintf("% 1.1Qf", x), y_str]
|
|
1622
|
+
* }
|
|
1623
|
+
* # => (x) cosh^-1(x)
|
|
1624
|
+
* # => 0.0 0.0+1.5707963267948966192313216916397i
|
|
1625
|
+
* # => 0.5 0.0+1.0471975511965977461542144610931i
|
|
1626
|
+
* # => 1.0 0.0
|
|
1627
|
+
* # => 1.5 0.962423650119206894995517826848737
|
|
1628
|
+
* # => 2.0 1.3169578969248167086250463473079
|
|
1629
|
+
*
|
|
1630
|
+
* QuadMath.acosh(1+1i) # => (1.0612750619050356520330189162135+0.904556894302381364127316795661958i)
|
|
1631
|
+
*/
|
|
1632
|
+
static VALUE
|
|
1633
|
+
quadmath_acosh(VALUE unused_obj, VALUE x)
|
|
1634
|
+
{
|
|
1635
|
+
switch (convertion_num_types(x)) {
|
|
1636
|
+
case NUM_FIXNUM:
|
|
1637
|
+
return quadmath_acosh_realsolve(fixnum_to_cf128(x));
|
|
1638
|
+
break;
|
|
1639
|
+
case NUM_BIGNUM:
|
|
1640
|
+
return quadmath_acosh_realsolve(bignum_to_cf128(x));
|
|
1641
|
+
break;
|
|
1642
|
+
case NUM_RATIONAL:
|
|
1643
|
+
return quadmath_acosh_realsolve(rational_to_cf128(x));
|
|
1644
|
+
break;
|
|
1645
|
+
case NUM_FLOAT:
|
|
1646
|
+
return quadmath_acosh_realsolve(float_to_cf128(x));
|
|
1647
|
+
break;
|
|
1648
|
+
case NUM_COMPLEX:
|
|
1649
|
+
VALUE nucomp = quadmath_acosh_nucompsolve(nucomp_to_cc128(x));
|
|
1650
|
+
return complex128_to_nucomp(nucomp);
|
|
1651
|
+
break;
|
|
1652
|
+
case NUM_FLOAT128:
|
|
1653
|
+
return quadmath_acosh_realsolve(GetF128(x));
|
|
1654
|
+
break;
|
|
1655
|
+
case NUM_COMPLEX128:
|
|
1656
|
+
return quadmath_acosh_nucompsolve(GetC128(x));
|
|
1657
|
+
break;
|
|
1658
|
+
case NUM_OTHERTYPE:
|
|
1659
|
+
default:
|
|
1660
|
+
if (num_real_p(x))
|
|
1661
|
+
return quadmath_acosh_realsolve(GetF128(x));
|
|
1662
|
+
else
|
|
1663
|
+
return quadmath_acosh_nucompsolve(GetC128(x));
|
|
1664
|
+
break;
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
static inline VALUE
|
|
1669
|
+
quadmath_atanh_realsolve(__float128 x)
|
|
1670
|
+
{
|
|
1671
|
+
if (isnan(x))
|
|
1672
|
+
return rb_float128_cf128(nanq(""));
|
|
1673
|
+
if (x >= -1 && x <= 1)
|
|
1674
|
+
return rb_float128_cf128(atanhq(x));
|
|
1675
|
+
else
|
|
1676
|
+
return rb_complex128_cc128(catanhq((__complex128)x));
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
static inline VALUE
|
|
1680
|
+
quadmath_atanh_nucompsolve(__complex128 x)
|
|
1681
|
+
{
|
|
1682
|
+
return rb_complex128_cc128(catanhq(x));
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
/*
|
|
1686
|
+
* call-seq:
|
|
1687
|
+
* QuadMath.atanh(x) -> Float128 | Complex128
|
|
1688
|
+
*
|
|
1689
|
+
* xの逆双曲線正接を返す.
|
|
1690
|
+
* xが実数なら定義域(-1<=x<=1)は実数解,それ以外は複素数解,複素数なら複素数解として各々返却する.
|
|
1691
|
+
*
|
|
1692
|
+
* puts "%s %s" % [" (x)", " tanh^-1(x)"]
|
|
1693
|
+
* -15.step(15, 5){|x|
|
|
1694
|
+
* x/=10.0;
|
|
1695
|
+
* y = QuadMath.atanh(x)
|
|
1696
|
+
* y_str = y.to_s
|
|
1697
|
+
* if !y.real.negative? then y_str = " #{y.to_s}"; end
|
|
1698
|
+
* puts "%s %s" % [quadmath_sprintf("% 1.1Qf", x), y_str]
|
|
1699
|
+
* }
|
|
1700
|
+
* # => (x) tanh^-1(x)
|
|
1701
|
+
* # => -1.5 -0.804718956217050187300379666613093+1.5707963267948966192313216916397i
|
|
1702
|
+
* # => -1.0 -Infinity
|
|
1703
|
+
* # => -0.5 -0.549306144334054845697622618461263
|
|
1704
|
+
* # => 0.0 0.0
|
|
1705
|
+
* # => 0.5 0.549306144334054845697622618461263
|
|
1706
|
+
* # => 1.0 Infinity
|
|
1707
|
+
* # => 1.5 0.804718956217050187300379666613093+1.5707963267948966192313216916397i
|
|
1708
|
+
* QuadMath.atanh(1+1i) # => (0.402359478108525093650189833306547+1.0172219678978513677227889615504i)
|
|
1709
|
+
*/
|
|
1710
|
+
static VALUE
|
|
1711
|
+
quadmath_atanh(VALUE unused_obj, VALUE x)
|
|
1712
|
+
{
|
|
1713
|
+
switch (convertion_num_types(x)) {
|
|
1714
|
+
case NUM_FIXNUM:
|
|
1715
|
+
return quadmath_atanh_realsolve(fixnum_to_cf128(x));
|
|
1716
|
+
break;
|
|
1717
|
+
case NUM_BIGNUM:
|
|
1718
|
+
return quadmath_atanh_realsolve(bignum_to_cf128(x));
|
|
1719
|
+
break;
|
|
1720
|
+
case NUM_RATIONAL:
|
|
1721
|
+
return quadmath_atanh_realsolve(rational_to_cf128(x));
|
|
1722
|
+
break;
|
|
1723
|
+
case NUM_FLOAT:
|
|
1724
|
+
return quadmath_atanh_realsolve(float_to_cf128(x));
|
|
1725
|
+
break;
|
|
1726
|
+
case NUM_COMPLEX:
|
|
1727
|
+
VALUE nucomp = quadmath_atanh_nucompsolve(nucomp_to_cc128(x));
|
|
1728
|
+
return complex128_to_nucomp(nucomp);
|
|
1729
|
+
break;
|
|
1730
|
+
case NUM_FLOAT128:
|
|
1731
|
+
return quadmath_atanh_realsolve(GetF128(x));
|
|
1732
|
+
break;
|
|
1733
|
+
case NUM_COMPLEX128:
|
|
1734
|
+
return quadmath_atanh_nucompsolve(GetC128(x));
|
|
1735
|
+
break;
|
|
1736
|
+
case NUM_OTHERTYPE:
|
|
1737
|
+
default:
|
|
1738
|
+
if (num_real_p(x))
|
|
1739
|
+
return quadmath_atanh_realsolve(GetF128(x));
|
|
1740
|
+
else
|
|
1741
|
+
return quadmath_atanh_nucompsolve(GetC128(x));
|
|
1742
|
+
break;
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
#ifndef HAVE_CL2NORM2Q
|
|
1747
|
+
__float128 cl2norm2q(__complex128, __complex128);
|
|
1748
|
+
|
|
1749
|
+
# include "missing/cl2norm2q.c"
|
|
1750
|
+
|
|
1751
|
+
#endif
|
|
1752
|
+
|
|
1753
|
+
static inline VALUE
|
|
1754
|
+
quadmath_hypot_realsolve(__float128 x, __float128 y)
|
|
1755
|
+
{
|
|
1756
|
+
return rb_float128_cf128(hypotq(x, y));
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
static inline VALUE
|
|
1760
|
+
quadmath_hypot_nucompsolve(__complex128 z, __complex128 w)
|
|
1761
|
+
{
|
|
1762
|
+
return rb_float128_cf128(cl2norm2q(z, w));
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1765
|
+
static VALUE
|
|
1766
|
+
hypot_inline(VALUE xsh, VALUE ysh)
|
|
1767
|
+
{
|
|
1768
|
+
static __float128 x, y;
|
|
1769
|
+
static __complex128 z, w;
|
|
1770
|
+
bool x_nucomp_p = false, y_nucomp_p = false;
|
|
1771
|
+
|
|
1772
|
+
switch (convertion_num_types(xsh)) {
|
|
1773
|
+
case NUM_FIXNUM:
|
|
1774
|
+
x = fixnum_to_cf128(xsh);
|
|
1775
|
+
break;
|
|
1776
|
+
case NUM_BIGNUM:
|
|
1777
|
+
x = bignum_to_cf128(xsh);
|
|
1778
|
+
break;
|
|
1779
|
+
case NUM_RATIONAL:
|
|
1780
|
+
x = rational_to_cf128(xsh);
|
|
1781
|
+
break;
|
|
1782
|
+
case NUM_FLOAT:
|
|
1783
|
+
x = float_to_cf128(xsh);
|
|
1784
|
+
break;
|
|
1785
|
+
case NUM_COMPLEX:
|
|
1786
|
+
z = nucomp_to_cc128(xsh);
|
|
1787
|
+
x_nucomp_p = true;
|
|
1788
|
+
break;
|
|
1789
|
+
case NUM_FLOAT128:
|
|
1790
|
+
x = GetF128(xsh);
|
|
1791
|
+
break;
|
|
1792
|
+
case NUM_COMPLEX128:
|
|
1793
|
+
z = GetC128(xsh);
|
|
1794
|
+
x_nucomp_p = true;
|
|
1795
|
+
break;
|
|
1796
|
+
case NUM_OTHERTYPE:
|
|
1797
|
+
default:
|
|
1798
|
+
if (num_real_p(xsh))
|
|
1799
|
+
x = GetF128(xsh);
|
|
1800
|
+
else
|
|
1801
|
+
{
|
|
1802
|
+
z = GetC128(xsh);
|
|
1803
|
+
x_nucomp_p = true;
|
|
1804
|
+
}
|
|
1805
|
+
break;
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
switch (convertion_num_types(ysh)) {
|
|
1809
|
+
case NUM_FIXNUM:
|
|
1810
|
+
y = fixnum_to_cf128(ysh);
|
|
1811
|
+
break;
|
|
1812
|
+
case NUM_BIGNUM:
|
|
1813
|
+
y = bignum_to_cf128(ysh);
|
|
1814
|
+
break;
|
|
1815
|
+
case NUM_RATIONAL:
|
|
1816
|
+
y = rational_to_cf128(ysh);
|
|
1817
|
+
break;
|
|
1818
|
+
case NUM_FLOAT:
|
|
1819
|
+
y = float_to_cf128(ysh);
|
|
1820
|
+
break;
|
|
1821
|
+
case NUM_COMPLEX:
|
|
1822
|
+
w = nucomp_to_cc128(ysh);
|
|
1823
|
+
y_nucomp_p = true;
|
|
1824
|
+
break;
|
|
1825
|
+
case NUM_FLOAT128:
|
|
1826
|
+
y = GetF128(ysh);
|
|
1827
|
+
break;
|
|
1828
|
+
case NUM_COMPLEX128:
|
|
1829
|
+
w = GetC128(ysh);
|
|
1830
|
+
y_nucomp_p = true;
|
|
1831
|
+
break;
|
|
1832
|
+
case NUM_OTHERTYPE:
|
|
1833
|
+
default:
|
|
1834
|
+
if (num_real_p(ysh))
|
|
1835
|
+
y = GetF128(ysh);
|
|
1836
|
+
else
|
|
1837
|
+
{
|
|
1838
|
+
w = GetC128(ysh);
|
|
1839
|
+
y_nucomp_p = true;
|
|
1840
|
+
}
|
|
1841
|
+
break;
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
if (x_nucomp_p && y_nucomp_p)
|
|
1845
|
+
return quadmath_hypot_nucompsolve(z, w);
|
|
1846
|
+
else if (x_nucomp_p && !y_nucomp_p)
|
|
1847
|
+
return quadmath_hypot_nucompsolve(z, y);
|
|
1848
|
+
else if (!x_nucomp_p && y_nucomp_p)
|
|
1849
|
+
return quadmath_hypot_nucompsolve(x, w);
|
|
1850
|
+
else
|
|
1851
|
+
return quadmath_hypot_realsolve(x, y);
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
/*
|
|
1855
|
+
* call-seq:
|
|
1856
|
+
* QuadMath.hypot(x, y) -> Float128
|
|
1857
|
+
*
|
|
1858
|
+
* xとyの直角三角形の斜辺の長さを実数で返す.
|
|
1859
|
+
* 2変数に複素数が含まれているならL2ノルムの答を返す.答は実数解・複素数解ともに常に正の実数である.
|
|
1860
|
+
*
|
|
1861
|
+
* QuadMath.hypot(3, 4) # => 5.0
|
|
1862
|
+
*
|
|
1863
|
+
* z = w = 2+1i;
|
|
1864
|
+
* 5.times do
|
|
1865
|
+
* ans = QuadMath.hypot(z, w)
|
|
1866
|
+
* print "hypot(%s, %s)^2 = %s^2 " % [z, w, ans]
|
|
1867
|
+
* puts "= %s" % [ans ** 2]
|
|
1868
|
+
* z += 1; w += 1;
|
|
1869
|
+
* end
|
|
1870
|
+
* # => hypot(2+1i, 2+1i)^2 = 3.1622776601683793319988935444327^2 = 10.0
|
|
1871
|
+
* # => hypot(3+1i, 3+1i)^2 = 4.4721359549995793928183473374625^2 = 20.0
|
|
1872
|
+
* # => hypot(4+1i, 4+1i)^2 = 5.8309518948453004708741528775455^2 = 34.0
|
|
1873
|
+
* # => hypot(5+1i, 5+1i)^2 = 7.2111025509279785862384425349409^2 = 52.0
|
|
1874
|
+
* # => hypot(6+1i, 6+1i)^2 = 8.6023252670426267717294735350497^2 = 74.0
|
|
1875
|
+
*/
|
|
1876
|
+
static VALUE
|
|
1877
|
+
quadmath_hypot(VALUE unused_obj, VALUE x, VALUE y)
|
|
1878
|
+
{
|
|
1879
|
+
return hypot_inline(x, y);
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
|
|
1883
|
+
#ifndef HAVE_CERFCQ
|
|
1884
|
+
extern __complex128 cerfcq(__complex128);
|
|
1885
|
+
# include "missing/cerfcq.c"
|
|
1886
|
+
#endif
|
|
1887
|
+
|
|
1888
|
+
#ifndef HAVE_CERFQ
|
|
1889
|
+
extern __complex128 cerfq(__complex128);
|
|
1890
|
+
# include "missing/cerfq.c"
|
|
1891
|
+
#endif
|
|
1892
|
+
|
|
1893
|
+
|
|
1894
|
+
static inline VALUE
|
|
1895
|
+
quadmath_erf_realsolve(__float128 x)
|
|
1896
|
+
{
|
|
1897
|
+
return rb_float128_cf128(erfq(x));
|
|
1898
|
+
}
|
|
1899
|
+
|
|
1900
|
+
static inline VALUE
|
|
1901
|
+
quadmath_erf_nucompsolve(__complex128 z)
|
|
1902
|
+
{
|
|
1903
|
+
if (cimagq(z) == 0)
|
|
1904
|
+
return rb_complex128_cc128((__complex128)erfq(crealq(z)));
|
|
1905
|
+
else
|
|
1906
|
+
return rb_complex128_cc128(cerfq(z));
|
|
1907
|
+
}
|
|
1908
|
+
|
|
1909
|
+
/*
|
|
1910
|
+
* call-seq:
|
|
1911
|
+
* QuadMath.erf(x) -> Float128 | Complex128
|
|
1912
|
+
*
|
|
1913
|
+
* xの誤差関数を返す.
|
|
1914
|
+
* xが実数なら実数解,複素数なら複素数解として各々返却する.
|
|
1915
|
+
*
|
|
1916
|
+
* QuadMath.erf(-2) # => -0.995322265018952734162069256367253
|
|
1917
|
+
* QuadMath.erf( 2) # => 0.995322265018952734162069256367253
|
|
1918
|
+
* QuadMath.erf(Complex128::I) # => (0.0+1.6504257587975428760253377295613i)
|
|
1919
|
+
* QuadMath.erf(1+1i) # => (1.3161512816979476448802710802436+0.190453469237834686284108861969162i)
|
|
1920
|
+
*/
|
|
1921
|
+
static VALUE
|
|
1922
|
+
quadmath_erf(VALUE unused_obj, VALUE x)
|
|
1923
|
+
{
|
|
1924
|
+
switch (convertion_num_types(x)) {
|
|
1925
|
+
case NUM_FIXNUM:
|
|
1926
|
+
return quadmath_erf_realsolve(fixnum_to_cf128(x));
|
|
1927
|
+
break;
|
|
1928
|
+
case NUM_BIGNUM:
|
|
1929
|
+
return quadmath_erf_realsolve(bignum_to_cf128(x));
|
|
1930
|
+
break;
|
|
1931
|
+
case NUM_RATIONAL:
|
|
1932
|
+
return quadmath_erf_realsolve(rational_to_cf128(x));
|
|
1933
|
+
break;
|
|
1934
|
+
case NUM_FLOAT:
|
|
1935
|
+
return quadmath_erf_realsolve(float_to_cf128(x));
|
|
1936
|
+
break;
|
|
1937
|
+
case NUM_COMPLEX:
|
|
1938
|
+
VALUE nucomp = quadmath_erf_nucompsolve(nucomp_to_cc128(x));
|
|
1939
|
+
return complex128_to_nucomp(nucomp);
|
|
1940
|
+
break;
|
|
1941
|
+
case NUM_FLOAT128:
|
|
1942
|
+
return quadmath_erf_realsolve(GetF128(x));
|
|
1943
|
+
break;
|
|
1944
|
+
case NUM_COMPLEX128:
|
|
1945
|
+
return quadmath_erf_nucompsolve(GetC128(x));
|
|
1946
|
+
break;
|
|
1947
|
+
case NUM_OTHERTYPE:
|
|
1948
|
+
default:
|
|
1949
|
+
if (num_real_p(x))
|
|
1950
|
+
return quadmath_erf_realsolve(GetF128(x));
|
|
1951
|
+
else
|
|
1952
|
+
return quadmath_erf_nucompsolve(GetC128(x));
|
|
1953
|
+
break;
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1957
|
+
static inline VALUE
|
|
1958
|
+
quadmath_erfc_realsolve(__float128 x)
|
|
1959
|
+
{
|
|
1960
|
+
return rb_float128_cf128(erfcq(x));
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1963
|
+
static inline VALUE
|
|
1964
|
+
quadmath_erfc_nucompsolve(__complex128 z)
|
|
1965
|
+
{
|
|
1966
|
+
if (cimagq(z) == 0)
|
|
1967
|
+
return rb_complex128_cc128((__complex128)erfcq(crealq(z)));
|
|
1968
|
+
else
|
|
1969
|
+
return rb_complex128_cc128(cerfcq(z));
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1972
|
+
/*
|
|
1973
|
+
* call-seq:
|
|
1974
|
+
* QuadMath.erfc(x) -> Float128 | Complex128
|
|
1975
|
+
*
|
|
1976
|
+
* xの相補誤差関数を返す.
|
|
1977
|
+
* xが実数なら実数解,複素数なら複素数解として各々返却する.
|
|
1978
|
+
*
|
|
1979
|
+
* QuadMath.erfc(-2) # => 1.9953222650189527341620692563672
|
|
1980
|
+
* QuadMath.erfc( 2) # => 0.00467773498104726583793074363274707
|
|
1981
|
+
* QuadMath.erfc(Complex128::I) # => (1.0-1.6504257587975428760253377295613i)
|
|
1982
|
+
* QuadMath.erfc(1+1i) # => (-0.31615128169794764488027108024367-0.190453469237834686284108861969162i)
|
|
1983
|
+
*/
|
|
1984
|
+
static VALUE
|
|
1985
|
+
quadmath_erfc(VALUE unused_obj, VALUE x)
|
|
1986
|
+
{
|
|
1987
|
+
switch (convertion_num_types(x)) {
|
|
1988
|
+
case NUM_FIXNUM:
|
|
1989
|
+
return quadmath_erfc_realsolve(fixnum_to_cf128(x));
|
|
1990
|
+
break;
|
|
1991
|
+
case NUM_BIGNUM:
|
|
1992
|
+
return quadmath_erfc_realsolve(bignum_to_cf128(x));
|
|
1993
|
+
break;
|
|
1994
|
+
case NUM_RATIONAL:
|
|
1995
|
+
return quadmath_erfc_realsolve(rational_to_cf128(x));
|
|
1996
|
+
break;
|
|
1997
|
+
case NUM_FLOAT:
|
|
1998
|
+
return quadmath_erfc_realsolve(float_to_cf128(x));
|
|
1999
|
+
break;
|
|
2000
|
+
case NUM_COMPLEX:
|
|
2001
|
+
VALUE nucomp = quadmath_erfc_nucompsolve(nucomp_to_cc128(x));
|
|
2002
|
+
return complex128_to_nucomp(nucomp);
|
|
2003
|
+
break;
|
|
2004
|
+
case NUM_FLOAT128:
|
|
2005
|
+
return quadmath_erfc_realsolve(GetF128(x));
|
|
2006
|
+
break;
|
|
2007
|
+
case NUM_COMPLEX128:
|
|
2008
|
+
return quadmath_erfc_nucompsolve(GetC128(x));
|
|
2009
|
+
break;
|
|
2010
|
+
case NUM_OTHERTYPE:
|
|
2011
|
+
default:
|
|
2012
|
+
if (num_real_p(x))
|
|
2013
|
+
return quadmath_erfc_realsolve(GetF128(x));
|
|
2014
|
+
else
|
|
2015
|
+
return quadmath_erfc_nucompsolve(GetC128(x));
|
|
2016
|
+
break;
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
|
|
2021
|
+
|
|
2022
|
+
#ifndef HAVE_CLGAMMAQ
|
|
2023
|
+
extern __complex128 clgammaq(__complex128);
|
|
2024
|
+
# include "missing/clgammaq.c"
|
|
2025
|
+
#endif
|
|
2026
|
+
|
|
2027
|
+
static inline __complex128
|
|
2028
|
+
lgamma_negarg(__float128 x)
|
|
2029
|
+
{
|
|
2030
|
+
__complex128 z;
|
|
2031
|
+
__real__ z = lgammaq(x);
|
|
2032
|
+
__imag__ z = floorq(x) * M_PIq;
|
|
2033
|
+
return z;
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
|
|
2037
|
+
static inline VALUE
|
|
2038
|
+
quadmath_lgamma_realsolve(__float128 x)
|
|
2039
|
+
{
|
|
2040
|
+
if (isnan(x))
|
|
2041
|
+
return rb_float128_cf128(nanq(""));
|
|
2042
|
+
if (!signbitq(x))
|
|
2043
|
+
return rb_float128_cf128(lgammaq(x));
|
|
2044
|
+
else
|
|
2045
|
+
return rb_complex128_cc128(lgamma_negarg(x));
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
|
|
2049
|
+
|
|
2050
|
+
static inline VALUE
|
|
2051
|
+
quadmath_lgamma_nucompsolve(__complex128 z)
|
|
2052
|
+
{
|
|
2053
|
+
if (cimagq(z) == 0)
|
|
2054
|
+
{
|
|
2055
|
+
__float128 real = crealq(z);
|
|
2056
|
+
if (isnanq(real))
|
|
2057
|
+
return rb_complex128_cc128((__complex128)real);
|
|
2058
|
+
else if (!signbitq(real))
|
|
2059
|
+
return rb_complex128_cc128((__complex128)lgammaq(real));
|
|
2060
|
+
else
|
|
2061
|
+
return rb_complex128_cc128(lgamma_negarg(real));
|
|
2062
|
+
}
|
|
2063
|
+
else
|
|
2064
|
+
return rb_complex128_cc128(clgammaq(z));
|
|
2065
|
+
}
|
|
2066
|
+
|
|
2067
|
+
/*
|
|
2068
|
+
* call-seq:
|
|
2069
|
+
* QuadMath.lgamma(x) -> Float128 | Complex128
|
|
2070
|
+
*
|
|
2071
|
+
* xの対数ガンマ関数を返す.
|
|
2072
|
+
* xが実数で正なら実数解,負なら複素数解,複素数なら複素数解を返す.
|
|
2073
|
+
*
|
|
2074
|
+
*
|
|
2075
|
+
*/
|
|
2076
|
+
static VALUE
|
|
2077
|
+
quadmath_lgamma(VALUE unused_obj, VALUE x)
|
|
2078
|
+
{
|
|
2079
|
+
switch (convertion_num_types(x)) {
|
|
2080
|
+
case NUM_FIXNUM:
|
|
2081
|
+
return quadmath_lgamma_realsolve(fixnum_to_cf128(x));
|
|
2082
|
+
break;
|
|
2083
|
+
case NUM_BIGNUM:
|
|
2084
|
+
return quadmath_lgamma_realsolve(bignum_to_cf128(x));
|
|
2085
|
+
break;
|
|
2086
|
+
case NUM_RATIONAL:
|
|
2087
|
+
return quadmath_lgamma_realsolve(rational_to_cf128(x));
|
|
2088
|
+
break;
|
|
2089
|
+
case NUM_FLOAT:
|
|
2090
|
+
return quadmath_lgamma_realsolve(float_to_cf128(x));
|
|
2091
|
+
break;
|
|
2092
|
+
case NUM_COMPLEX:
|
|
2093
|
+
VALUE nucomp = quadmath_lgamma_nucompsolve(nucomp_to_cc128(x));
|
|
2094
|
+
// return complex128_to_nucomp(nucomp);
|
|
2095
|
+
return nucomp;
|
|
2096
|
+
break;
|
|
2097
|
+
case NUM_FLOAT128:
|
|
2098
|
+
return quadmath_lgamma_realsolve(GetF128(x));
|
|
2099
|
+
break;
|
|
2100
|
+
case NUM_COMPLEX128:
|
|
2101
|
+
return quadmath_lgamma_nucompsolve(GetC128(x));
|
|
2102
|
+
break;
|
|
2103
|
+
case NUM_OTHERTYPE:
|
|
2104
|
+
default:
|
|
2105
|
+
if (num_real_p(x))
|
|
2106
|
+
return quadmath_lgamma_realsolve(GetF128(x));
|
|
2107
|
+
else
|
|
2108
|
+
return quadmath_lgamma_nucompsolve(GetC128(x));
|
|
2109
|
+
break;
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
|
|
2113
|
+
static inline VALUE
|
|
2114
|
+
quadmath_lgamma_r_realsolve(__float128 x)
|
|
2115
|
+
{
|
|
2116
|
+
int sign = 1;
|
|
2117
|
+
__float128 y = lgammaq(x);
|
|
2118
|
+
|
|
2119
|
+
if (x < 0 && fmodq(floorq(x), 2))
|
|
2120
|
+
sign = -1;
|
|
2121
|
+
|
|
2122
|
+
return rb_assoc_new(rb_float128_cf128(y), INT2FIX(sign));
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
static inline VALUE
|
|
2126
|
+
quadmath_lgamma_r_nucompsolve(__complex128 z)
|
|
2127
|
+
{
|
|
2128
|
+
int sign = 1;
|
|
2129
|
+
if (cimagq(z) == 0)
|
|
2130
|
+
{
|
|
2131
|
+
__float128 real = crealq(z);
|
|
2132
|
+
if (real < 0 && fmodq(floorq(real), 2))
|
|
2133
|
+
sign = -1;
|
|
2134
|
+
return rb_assoc_new(
|
|
2135
|
+
rb_float128_cf128(lgammaq(real)),
|
|
2136
|
+
INT2FIX(sign)
|
|
2137
|
+
);
|
|
2138
|
+
}
|
|
2139
|
+
else
|
|
2140
|
+
return rb_assoc_new(Qnil, INT2FIX(0));
|
|
2141
|
+
}
|
|
2142
|
+
|
|
2143
|
+
/*
|
|
2144
|
+
* call-seq:
|
|
2145
|
+
* QuadMath.lgamma_r(x) -> [Float128, Integer] | [nil, 0]
|
|
2146
|
+
* QuadMath.signgam(x) -> [Float128, Integer] | [nil, 0]
|
|
2147
|
+
*
|
|
2148
|
+
* 伝統的なlgamma_r()関数をquadmathモジュールとして提供する.対数ガンマ関数の実数解とその符号値が配列で渡される.
|
|
2149
|
+
* 値を指数に戻す場合,周期性$2\pi$は数値計算に精度を保証できない.オイラー積分で対数から指数に戻す場合は,大概にこのような関数を使用するべきである.
|
|
2150
|
+
* 虚数の現れている数値を渡すと,計算不能と判断し,nilと0のペアを返す.
|
|
2151
|
+
*
|
|
2152
|
+
* x = -0.5r
|
|
2153
|
+
* lgamm, sign = QuadMath.lgamma_r(x)
|
|
2154
|
+
* # => [1.2655121234846453964889457971347, -1]
|
|
2155
|
+
* QuadMath.exp(lgamm) * sign
|
|
2156
|
+
* # => -3.5449077018110320545963349666822
|
|
2157
|
+
* QuadMath.gamma(x)
|
|
2158
|
+
* # => -3.5449077018110320545963349666822
|
|
2159
|
+
*/
|
|
2160
|
+
static VALUE
|
|
2161
|
+
quadmath_lgamma_r(VALUE unused_obj, VALUE x)
|
|
2162
|
+
{
|
|
2163
|
+
switch (convertion_num_types(x)) {
|
|
2164
|
+
case NUM_FIXNUM:
|
|
2165
|
+
return quadmath_lgamma_r_realsolve(fixnum_to_cf128(x));
|
|
2166
|
+
break;
|
|
2167
|
+
case NUM_BIGNUM:
|
|
2168
|
+
return quadmath_lgamma_r_realsolve(bignum_to_cf128(x));
|
|
2169
|
+
break;
|
|
2170
|
+
case NUM_RATIONAL:
|
|
2171
|
+
return quadmath_lgamma_r_realsolve(rational_to_cf128(x));
|
|
2172
|
+
break;
|
|
2173
|
+
case NUM_FLOAT:
|
|
2174
|
+
return quadmath_lgamma_r_realsolve(float_to_cf128(x));
|
|
2175
|
+
break;
|
|
2176
|
+
case NUM_COMPLEX:
|
|
2177
|
+
VALUE nucomp = quadmath_lgamma_r_nucompsolve(nucomp_to_cc128(x));
|
|
2178
|
+
// return complex128_to_nucomp(nucomp);
|
|
2179
|
+
return nucomp;
|
|
2180
|
+
break;
|
|
2181
|
+
case NUM_FLOAT128:
|
|
2182
|
+
return quadmath_lgamma_r_realsolve(GetF128(x));
|
|
2183
|
+
break;
|
|
2184
|
+
case NUM_COMPLEX128:
|
|
2185
|
+
return quadmath_lgamma_r_nucompsolve(GetC128(x));
|
|
2186
|
+
break;
|
|
2187
|
+
case NUM_OTHERTYPE:
|
|
2188
|
+
default:
|
|
2189
|
+
if (num_real_p(x))
|
|
2190
|
+
return quadmath_lgamma_r_realsolve(GetF128(x));
|
|
2191
|
+
else
|
|
2192
|
+
return quadmath_lgamma_r_nucompsolve(GetC128(x));
|
|
2193
|
+
break;
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
|
|
2197
|
+
|
|
2198
|
+
#ifndef HAVE_CTGAMMAQ
|
|
2199
|
+
extern __complex128 ctgammaq(__complex128);
|
|
2200
|
+
# include "missing/ctgammaq.c"
|
|
2201
|
+
#endif
|
|
2202
|
+
|
|
2203
|
+
|
|
2204
|
+
static inline VALUE
|
|
2205
|
+
quadmath_gamma_realsolve(__float128 x)
|
|
2206
|
+
{
|
|
2207
|
+
return rb_float128_cf128(tgammaq(x));
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
|
|
2211
|
+
|
|
2212
|
+
static inline VALUE
|
|
2213
|
+
quadmath_gamma_nucompsolve(__complex128 z)
|
|
2214
|
+
{
|
|
2215
|
+
if (cimagq(z) == 0)
|
|
2216
|
+
return rb_complex128_cc128((__complex128)tgammaq(crealq(z)));
|
|
2217
|
+
else
|
|
2218
|
+
#if 0
|
|
2219
|
+
return rb_complex128_cc128(ctgammaq(z));
|
|
2220
|
+
#else
|
|
2221
|
+
rb_raise(rb_eTypeError, "not a real");
|
|
2222
|
+
#endif
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
/*
|
|
2226
|
+
* call-seq:
|
|
2227
|
+
* QuadMath.gamma(x) -> Float128 | Complex128
|
|
2228
|
+
*
|
|
2229
|
+
* xのガンマ関数を返す.
|
|
2230
|
+
* xが実数なら実数解,素数なら複素数解として各々返却する.
|
|
2231
|
+
*
|
|
2232
|
+
*
|
|
2233
|
+
*/
|
|
2234
|
+
static VALUE
|
|
2235
|
+
quadmath_gamma(VALUE unused_obj, VALUE x)
|
|
2236
|
+
{
|
|
2237
|
+
switch (convertion_num_types(x)) {
|
|
2238
|
+
case NUM_FIXNUM:
|
|
2239
|
+
return quadmath_gamma_realsolve(fixnum_to_cf128(x));
|
|
2240
|
+
break;
|
|
2241
|
+
case NUM_BIGNUM:
|
|
2242
|
+
return quadmath_gamma_realsolve(bignum_to_cf128(x));
|
|
2243
|
+
break;
|
|
2244
|
+
case NUM_RATIONAL:
|
|
2245
|
+
return quadmath_gamma_realsolve(rational_to_cf128(x));
|
|
2246
|
+
break;
|
|
2247
|
+
case NUM_FLOAT:
|
|
2248
|
+
return quadmath_gamma_realsolve(float_to_cf128(x));
|
|
2249
|
+
break;
|
|
2250
|
+
case NUM_COMPLEX:
|
|
2251
|
+
VALUE nucomp = quadmath_gamma_nucompsolve(nucomp_to_cc128(x));
|
|
2252
|
+
#if 0
|
|
2253
|
+
return complex128_to_nucomp(nucomp);
|
|
2254
|
+
#else
|
|
2255
|
+
return nucomp;
|
|
2256
|
+
#endif
|
|
2257
|
+
break;
|
|
2258
|
+
case NUM_FLOAT128:
|
|
2259
|
+
return quadmath_gamma_realsolve(GetF128(x));
|
|
2260
|
+
break;
|
|
2261
|
+
case NUM_COMPLEX128:
|
|
2262
|
+
return quadmath_gamma_nucompsolve(GetC128(x));
|
|
2263
|
+
break;
|
|
2264
|
+
case NUM_OTHERTYPE:
|
|
2265
|
+
default:
|
|
2266
|
+
if (num_real_p(x))
|
|
2267
|
+
return quadmath_gamma_realsolve(GetF128(x));
|
|
2268
|
+
else
|
|
2269
|
+
return quadmath_gamma_nucompsolve(GetC128(x));
|
|
2270
|
+
break;
|
|
2271
|
+
}
|
|
2272
|
+
}
|
|
2273
|
+
|
|
2274
|
+
static inline VALUE
|
|
2275
|
+
quadmath_j0_realsolve(__float128 x)
|
|
2276
|
+
{
|
|
2277
|
+
return rb_float128_cf128(j0q(x));
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2280
|
+
static inline VALUE
|
|
2281
|
+
quadmath_j0_nucompsolve(__float128 z)
|
|
2282
|
+
{
|
|
2283
|
+
if (cimagq(z) == 0)
|
|
2284
|
+
return rb_complex128_cc128((__complex128)j0q(crealq(z)));
|
|
2285
|
+
else
|
|
2286
|
+
#if 0
|
|
2287
|
+
return rb_complex128_cc128(cj0q(z));
|
|
2288
|
+
#else
|
|
2289
|
+
rb_raise(rb_eTypeError, "not a real");
|
|
2290
|
+
#endif
|
|
2291
|
+
}
|
|
2292
|
+
|
|
2293
|
+
/*
|
|
2294
|
+
* call-seq:
|
|
2295
|
+
* QuadMath.j0(x) -> Float128
|
|
2296
|
+
*
|
|
2297
|
+
* Computes the Bessel function of the first kind, first order of +x+.
|
|
2298
|
+
*
|
|
2299
|
+
* QuadMath.j0(Float128('1.5')) # => 0.511827671735918128749051744283412
|
|
2300
|
+
* QuadMath.j0(-2) # => 0.223890779141235668051827454649949
|
|
2301
|
+
* QuadMath.j0(2/5r) # => 0.960398226659563450344165306607428
|
|
2302
|
+
*
|
|
2303
|
+
*/
|
|
2304
|
+
static VALUE
|
|
2305
|
+
quadmath_j0(VALUE unused_obj, VALUE x)
|
|
2306
|
+
{
|
|
2307
|
+
switch (convertion_num_types(x)) {
|
|
2308
|
+
case NUM_FIXNUM:
|
|
2309
|
+
return quadmath_j0_realsolve(fixnum_to_cf128(x));
|
|
2310
|
+
break;
|
|
2311
|
+
case NUM_BIGNUM:
|
|
2312
|
+
return quadmath_j0_realsolve(bignum_to_cf128(x));
|
|
2313
|
+
break;
|
|
2314
|
+
case NUM_RATIONAL:
|
|
2315
|
+
return quadmath_j0_realsolve(rational_to_cf128(x));
|
|
2316
|
+
break;
|
|
2317
|
+
case NUM_FLOAT:
|
|
2318
|
+
return quadmath_j0_realsolve(float_to_cf128(x));
|
|
2319
|
+
break;
|
|
2320
|
+
case NUM_COMPLEX:
|
|
2321
|
+
VALUE nucomp = quadmath_j0_nucompsolve(nucomp_to_cc128(x));
|
|
2322
|
+
#if 0
|
|
2323
|
+
return complex128_to_nucomp(nucomp);
|
|
2324
|
+
#else
|
|
2325
|
+
return nucomp;
|
|
2326
|
+
#endif
|
|
2327
|
+
break;
|
|
2328
|
+
case NUM_FLOAT128:
|
|
2329
|
+
return quadmath_j0_realsolve(GetF128(x));
|
|
2330
|
+
break;
|
|
2331
|
+
case NUM_COMPLEX128:
|
|
2332
|
+
return quadmath_j0_nucompsolve(GetC128(x));
|
|
2333
|
+
break;
|
|
2334
|
+
case NUM_OTHERTYPE:
|
|
2335
|
+
default:
|
|
2336
|
+
if (num_real_p(x))
|
|
2337
|
+
return quadmath_j0_realsolve(GetF128(x));
|
|
2338
|
+
else
|
|
2339
|
+
return quadmath_j0_nucompsolve(GetC128(x));
|
|
2340
|
+
break;
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
|
|
2344
|
+
static inline VALUE
|
|
2345
|
+
quadmath_j1_realsolve(__float128 x)
|
|
2346
|
+
{
|
|
2347
|
+
return rb_float128_cf128(j1q(x));
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2350
|
+
static inline VALUE
|
|
2351
|
+
quadmath_j1_nucompsolve(__float128 z)
|
|
2352
|
+
{
|
|
2353
|
+
if (cimagq(z) == 0)
|
|
2354
|
+
return rb_complex128_cc128((__complex128)j1q(crealq(z)));
|
|
2355
|
+
else
|
|
2356
|
+
#if 0
|
|
2357
|
+
return rb_complex128_cc128(cj1q(z));
|
|
2358
|
+
#else
|
|
2359
|
+
rb_raise(rb_eTypeError, "not a real");
|
|
2360
|
+
#endif
|
|
2361
|
+
}
|
|
2362
|
+
|
|
2363
|
+
/*
|
|
2364
|
+
* call-seq:
|
|
2365
|
+
* QuadMath.j1(x) -> Float128
|
|
2366
|
+
*
|
|
2367
|
+
* Computes the Bessel function of the first kind, second order of +x+.
|
|
2368
|
+
*
|
|
2369
|
+
* QuadMath.j1(Float128('1.7')) # => 0.577765231529023219798092027156419
|
|
2370
|
+
* QuadMath.j1(3/7r) # => 0.209403397190135593919658594927937
|
|
2371
|
+
*
|
|
2372
|
+
*/
|
|
2373
|
+
static VALUE
|
|
2374
|
+
quadmath_j1(VALUE unused_obj, VALUE x)
|
|
2375
|
+
{
|
|
2376
|
+
switch (convertion_num_types(x)) {
|
|
2377
|
+
case NUM_FIXNUM:
|
|
2378
|
+
return quadmath_j1_realsolve(fixnum_to_cf128(x));
|
|
2379
|
+
break;
|
|
2380
|
+
case NUM_BIGNUM:
|
|
2381
|
+
return quadmath_j1_realsolve(bignum_to_cf128(x));
|
|
2382
|
+
break;
|
|
2383
|
+
case NUM_RATIONAL:
|
|
2384
|
+
return quadmath_j1_realsolve(rational_to_cf128(x));
|
|
2385
|
+
break;
|
|
2386
|
+
case NUM_FLOAT:
|
|
2387
|
+
return quadmath_j1_realsolve(float_to_cf128(x));
|
|
2388
|
+
break;
|
|
2389
|
+
case NUM_COMPLEX:
|
|
2390
|
+
VALUE nucomp = quadmath_j1_nucompsolve(nucomp_to_cc128(x));
|
|
2391
|
+
#if 0
|
|
2392
|
+
return complex128_to_nucomp(nucomp);
|
|
2393
|
+
#else
|
|
2394
|
+
return nucomp;
|
|
2395
|
+
#endif
|
|
2396
|
+
break;
|
|
2397
|
+
case NUM_FLOAT128:
|
|
2398
|
+
return quadmath_j1_realsolve(GetF128(x));
|
|
2399
|
+
break;
|
|
2400
|
+
case NUM_COMPLEX128:
|
|
2401
|
+
return quadmath_j1_nucompsolve(GetC128(x));
|
|
2402
|
+
break;
|
|
2403
|
+
case NUM_OTHERTYPE:
|
|
2404
|
+
default:
|
|
2405
|
+
if (num_real_p(x))
|
|
2406
|
+
return quadmath_j1_realsolve(GetF128(x));
|
|
2407
|
+
else
|
|
2408
|
+
return quadmath_j1_nucompsolve(GetC128(x));
|
|
2409
|
+
break;
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
|
|
2413
|
+
static inline int
|
|
2414
|
+
value_to_cint(VALUE x)
|
|
2415
|
+
{
|
|
2416
|
+
#if 0
|
|
2417
|
+
ID cover_p = rb_intern("cover?");
|
|
2418
|
+
VALUE range = rb_range_new(INT2FIX(INT_MIN), INT2FIX(INT_MAX), false);
|
|
2419
|
+
#endif
|
|
2420
|
+
if (!RB_INTEGER_TYPE_P(x))
|
|
2421
|
+
x = rb_Integer(x);
|
|
2422
|
+
#if 0
|
|
2423
|
+
if (!RTEST(rb_funcall(range, cover_p, 1, x)))
|
|
2424
|
+
rb_raise(rb_eRangeError, "integer order not in range");
|
|
2425
|
+
#endif
|
|
2426
|
+
return NUM2INT(x);
|
|
2427
|
+
}
|
|
2428
|
+
|
|
2429
|
+
static inline VALUE
|
|
2430
|
+
quadmath_jn_realsolve(int order, __float128 x)
|
|
2431
|
+
{
|
|
2432
|
+
return rb_float128_cf128(jnq(order, x));
|
|
2433
|
+
}
|
|
2434
|
+
|
|
2435
|
+
static inline VALUE
|
|
2436
|
+
quadmath_jn_nucompsolve(int order, __float128 z)
|
|
2437
|
+
{
|
|
2438
|
+
if (cimagq(z) == 0)
|
|
2439
|
+
return rb_complex128_cc128((__complex128)jnq(order, crealq(z)));
|
|
2440
|
+
else
|
|
2441
|
+
#if 0
|
|
2442
|
+
return rb_complex128_cc128(cjnq(order, z));
|
|
2443
|
+
#else
|
|
2444
|
+
rb_raise(rb_eTypeError, "not a real");
|
|
2445
|
+
#endif
|
|
2446
|
+
}
|
|
2447
|
+
|
|
2448
|
+
/*
|
|
2449
|
+
* call-seq:
|
|
2450
|
+
* QuadMath.jn(order, x) -> Float128
|
|
2451
|
+
*
|
|
2452
|
+
* Computes the Bessel function of the first kind, +order+ of +x+.
|
|
2453
|
+
*
|
|
2454
|
+
* QuadMath.jn(2, 1) # => 0.114903484931900480469646881335167
|
|
2455
|
+
* QuadMath.jn(3, Float128('2.7')) # => 0.254045291587227349961546499656304
|
|
2456
|
+
*/
|
|
2457
|
+
static VALUE
|
|
2458
|
+
quadmath_jn(VALUE unused_obj, VALUE order, VALUE x)
|
|
2459
|
+
{
|
|
2460
|
+
int vorder = value_to_cint(order);
|
|
2461
|
+
switch (convertion_num_types(x)) {
|
|
2462
|
+
case NUM_FIXNUM:
|
|
2463
|
+
return quadmath_jn_realsolve(vorder, fixnum_to_cf128(x));
|
|
2464
|
+
break;
|
|
2465
|
+
case NUM_BIGNUM:
|
|
2466
|
+
return quadmath_jn_realsolve(vorder, bignum_to_cf128(x));
|
|
2467
|
+
break;
|
|
2468
|
+
case NUM_RATIONAL:
|
|
2469
|
+
return quadmath_jn_realsolve(vorder, rational_to_cf128(x));
|
|
2470
|
+
break;
|
|
2471
|
+
case NUM_FLOAT:
|
|
2472
|
+
return quadmath_jn_realsolve(vorder, float_to_cf128(x));
|
|
2473
|
+
break;
|
|
2474
|
+
case NUM_COMPLEX:
|
|
2475
|
+
VALUE nucomp = quadmath_jn_nucompsolve(vorder, nucomp_to_cc128(x));
|
|
2476
|
+
#if 0
|
|
2477
|
+
return complex128_to_nucomp(nucomp);
|
|
2478
|
+
#else
|
|
2479
|
+
return nucomp;
|
|
2480
|
+
#endif
|
|
2481
|
+
break;
|
|
2482
|
+
case NUM_FLOAT128:
|
|
2483
|
+
return quadmath_jn_realsolve(vorder, GetF128(x));
|
|
2484
|
+
break;
|
|
2485
|
+
case NUM_COMPLEX128:
|
|
2486
|
+
return quadmath_jn_nucompsolve(vorder, GetC128(x));
|
|
2487
|
+
break;
|
|
2488
|
+
case NUM_OTHERTYPE:
|
|
2489
|
+
default:
|
|
2490
|
+
if (num_real_p(x))
|
|
2491
|
+
return quadmath_jn_realsolve(vorder, GetF128(x));
|
|
2492
|
+
else
|
|
2493
|
+
return quadmath_jn_nucompsolve(vorder, GetC128(x));
|
|
2494
|
+
break;
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
|
|
2498
|
+
static inline VALUE
|
|
2499
|
+
quadmath_y0_realsolve(__float128 x)
|
|
2500
|
+
{
|
|
2501
|
+
return rb_float128_cf128(y0q(x));
|
|
2502
|
+
}
|
|
2503
|
+
|
|
2504
|
+
static inline VALUE
|
|
2505
|
+
quadmath_y0_nucompsolve(__float128 z)
|
|
2506
|
+
{
|
|
2507
|
+
if (cimagq(z) == 0)
|
|
2508
|
+
return rb_complex128_cc128((__complex128)y0q(crealq(z)));
|
|
2509
|
+
else
|
|
2510
|
+
#if 0
|
|
2511
|
+
return rb_complex128_cc128(cy0q(z));
|
|
2512
|
+
#else
|
|
2513
|
+
rb_raise(rb_eTypeError, "not a real");
|
|
2514
|
+
#endif
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2517
|
+
/*
|
|
2518
|
+
* call-seq:
|
|
2519
|
+
* QuadMath.y0(x) -> Float128
|
|
2520
|
+
*
|
|
2521
|
+
* Computes the Bessel function of the second kind, first order of +x+.
|
|
2522
|
+
*
|
|
2523
|
+
* QuadMath.y0(1) # => 0.0882569642156769579829267660235151
|
|
2524
|
+
* QuadMath.y0(Float128('1.3')) # => 0.286535357165570093402992512691284
|
|
2525
|
+
* QuadMath.y0(2) # => 0.510375672649745119596606592727158
|
|
2526
|
+
* QuadMath.y0(200) # => -0.054265775249817910693500115141763
|
|
2527
|
+
* QuadMath.y0(20000) # => -0.000922448896060731022547929946760507
|
|
2528
|
+
* QuadMath.y0(1/3r) # => -0.734373073454472607761165475056708
|
|
2529
|
+
*/
|
|
2530
|
+
static VALUE
|
|
2531
|
+
quadmath_y0(VALUE unused_obj, VALUE x)
|
|
2532
|
+
{
|
|
2533
|
+
switch (convertion_num_types(x)) {
|
|
2534
|
+
case NUM_FIXNUM:
|
|
2535
|
+
return quadmath_y0_realsolve(fixnum_to_cf128(x));
|
|
2536
|
+
break;
|
|
2537
|
+
case NUM_BIGNUM:
|
|
2538
|
+
return quadmath_y0_realsolve(bignum_to_cf128(x));
|
|
2539
|
+
break;
|
|
2540
|
+
case NUM_RATIONAL:
|
|
2541
|
+
return quadmath_y0_realsolve(rational_to_cf128(x));
|
|
2542
|
+
break;
|
|
2543
|
+
case NUM_FLOAT:
|
|
2544
|
+
return quadmath_y0_realsolve(float_to_cf128(x));
|
|
2545
|
+
break;
|
|
2546
|
+
case NUM_COMPLEX:
|
|
2547
|
+
VALUE nucomp = quadmath_y0_nucompsolve(nucomp_to_cc128(x));
|
|
2548
|
+
#if 0
|
|
2549
|
+
return complex128_to_nucomp(nucomp);
|
|
2550
|
+
#else
|
|
2551
|
+
return nucomp;
|
|
2552
|
+
#endif
|
|
2553
|
+
break;
|
|
2554
|
+
case NUM_FLOAT128:
|
|
2555
|
+
return quadmath_y0_realsolve(GetF128(x));
|
|
2556
|
+
break;
|
|
2557
|
+
case NUM_COMPLEX128:
|
|
2558
|
+
return quadmath_y0_nucompsolve(GetC128(x));
|
|
2559
|
+
break;
|
|
2560
|
+
case NUM_OTHERTYPE:
|
|
2561
|
+
default:
|
|
2562
|
+
if (num_real_p(x))
|
|
2563
|
+
return quadmath_y0_realsolve(GetF128(x));
|
|
2564
|
+
else
|
|
2565
|
+
return quadmath_y0_nucompsolve(GetC128(x));
|
|
2566
|
+
break;
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2569
|
+
|
|
2570
|
+
static inline VALUE
|
|
2571
|
+
quadmath_y1_realsolve(__float128 x)
|
|
2572
|
+
{
|
|
2573
|
+
return rb_float128_cf128(y1q(x));
|
|
2574
|
+
}
|
|
2575
|
+
|
|
2576
|
+
static inline VALUE
|
|
2577
|
+
quadmath_y1_nucompsolve(__float128 z)
|
|
2578
|
+
{
|
|
2579
|
+
if (cimagq(z) == 0)
|
|
2580
|
+
return rb_complex128_cc128((__complex128)y1q(crealq(z)));
|
|
2581
|
+
else
|
|
2582
|
+
#if 0
|
|
2583
|
+
return rb_complex128_cc128(cy1q(z));
|
|
2584
|
+
#else
|
|
2585
|
+
rb_raise(rb_eTypeError, "not a real");
|
|
2586
|
+
#endif
|
|
2587
|
+
}
|
|
2588
|
+
|
|
2589
|
+
/*
|
|
2590
|
+
* call-seq:
|
|
2591
|
+
* QuadMath.y1(x) -> Float128
|
|
2592
|
+
*
|
|
2593
|
+
* Computes the Bessel function of the second kind, second order of +x+.
|
|
2594
|
+
*
|
|
2595
|
+
* QuadMath.y1(1) # => -0.781212821300288716547150000047965
|
|
2596
|
+
* QuadMath.y1(Float128('1.3')) # => -0.548519729980776075246816253582645
|
|
2597
|
+
* QuadMath.y1(2) # => -0.107032431540937546888370772277477
|
|
2598
|
+
* QuadMath.y1(100) # => -0.0203723120027597933047039326664145
|
|
2599
|
+
* QuadMath.y1(1000) # => -0.0247843312923517789148623560971413
|
|
2600
|
+
* QuadMath.y1(1/3r) # => -2.0881657798883862661909621637453
|
|
2601
|
+
*/
|
|
2602
|
+
static VALUE
|
|
2603
|
+
quadmath_y1(VALUE unused_obj, VALUE x)
|
|
2604
|
+
{
|
|
2605
|
+
switch (convertion_num_types(x)) {
|
|
2606
|
+
case NUM_FIXNUM:
|
|
2607
|
+
return quadmath_y1_realsolve(fixnum_to_cf128(x));
|
|
2608
|
+
break;
|
|
2609
|
+
case NUM_BIGNUM:
|
|
2610
|
+
return quadmath_y1_realsolve(bignum_to_cf128(x));
|
|
2611
|
+
break;
|
|
2612
|
+
case NUM_RATIONAL:
|
|
2613
|
+
return quadmath_y1_realsolve(rational_to_cf128(x));
|
|
2614
|
+
break;
|
|
2615
|
+
case NUM_FLOAT:
|
|
2616
|
+
return quadmath_y1_realsolve(float_to_cf128(x));
|
|
2617
|
+
break;
|
|
2618
|
+
case NUM_COMPLEX:
|
|
2619
|
+
VALUE nucomp = quadmath_y1_nucompsolve(nucomp_to_cc128(x));
|
|
2620
|
+
#if 0
|
|
2621
|
+
return complex128_to_nucomp(nucomp);
|
|
2622
|
+
#else
|
|
2623
|
+
return nucomp;
|
|
2624
|
+
#endif
|
|
2625
|
+
break;
|
|
2626
|
+
case NUM_FLOAT128:
|
|
2627
|
+
return quadmath_y1_realsolve(GetF128(x));
|
|
2628
|
+
break;
|
|
2629
|
+
case NUM_COMPLEX128:
|
|
2630
|
+
return quadmath_y1_nucompsolve(GetC128(x));
|
|
2631
|
+
break;
|
|
2632
|
+
case NUM_OTHERTYPE:
|
|
2633
|
+
default:
|
|
2634
|
+
if (num_real_p(x))
|
|
2635
|
+
return quadmath_y1_realsolve(GetF128(x));
|
|
2636
|
+
else
|
|
2637
|
+
return quadmath_y1_nucompsolve(GetC128(x));
|
|
2638
|
+
break;
|
|
2639
|
+
}
|
|
2640
|
+
}
|
|
2641
|
+
|
|
2642
|
+
static inline VALUE
|
|
2643
|
+
quadmath_yn_realsolve(int order, __float128 x)
|
|
2644
|
+
{
|
|
2645
|
+
return rb_float128_cf128(ynq(order, x));
|
|
2646
|
+
}
|
|
2647
|
+
|
|
2648
|
+
static inline VALUE
|
|
2649
|
+
quadmath_yn_nucompsolve(int order, __float128 z)
|
|
2650
|
+
{
|
|
2651
|
+
if (cimagq(z) == 0)
|
|
2652
|
+
return rb_complex128_cc128((__complex128)ynq(order, crealq(z)));
|
|
2653
|
+
else
|
|
2654
|
+
#if 0
|
|
2655
|
+
return rb_complex128_cc128(cynq(order, z));
|
|
2656
|
+
#else
|
|
2657
|
+
rb_raise(rb_eTypeError, "not a real");
|
|
2658
|
+
#endif
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2661
|
+
/*
|
|
2662
|
+
* call-seq:
|
|
2663
|
+
* QuadMath.yn(order, x) -> Float128
|
|
2664
|
+
*
|
|
2665
|
+
* Computes the Bessel function of the second kind, +order+ of +x+.
|
|
2666
|
+
*
|
|
2667
|
+
* QuadMath.yn(3, 2/3r) # => -18.2021440952126114787933209537936
|
|
2668
|
+
* QuadMath.yn(5, Float128('1.6')) # => -27.4921544939634722522098623648692
|
|
2669
|
+
*/
|
|
2670
|
+
static VALUE
|
|
2671
|
+
quadmath_yn(VALUE unused_obj, VALUE order, VALUE x)
|
|
2672
|
+
{
|
|
2673
|
+
int vorder = value_to_cint(order);
|
|
2674
|
+
switch (convertion_num_types(x)) {
|
|
2675
|
+
case NUM_FIXNUM:
|
|
2676
|
+
return quadmath_yn_realsolve(vorder, fixnum_to_cf128(x));
|
|
2677
|
+
break;
|
|
2678
|
+
case NUM_BIGNUM:
|
|
2679
|
+
return quadmath_yn_realsolve(vorder, bignum_to_cf128(x));
|
|
2680
|
+
break;
|
|
2681
|
+
case NUM_RATIONAL:
|
|
2682
|
+
return quadmath_yn_realsolve(vorder, rational_to_cf128(x));
|
|
2683
|
+
break;
|
|
2684
|
+
case NUM_FLOAT:
|
|
2685
|
+
return quadmath_yn_realsolve(vorder, float_to_cf128(x));
|
|
2686
|
+
break;
|
|
2687
|
+
case NUM_COMPLEX:
|
|
2688
|
+
VALUE nucomp = quadmath_yn_nucompsolve(vorder, nucomp_to_cc128(x));
|
|
2689
|
+
#if 0
|
|
2690
|
+
return complex128_to_nucomp(nucomp);
|
|
2691
|
+
#else
|
|
2692
|
+
return nucomp;
|
|
2693
|
+
#endif
|
|
2694
|
+
break;
|
|
2695
|
+
case NUM_FLOAT128:
|
|
2696
|
+
return quadmath_yn_realsolve(vorder, GetF128(x));
|
|
2697
|
+
break;
|
|
2698
|
+
case NUM_COMPLEX128:
|
|
2699
|
+
return quadmath_yn_nucompsolve(vorder, GetC128(x));
|
|
2700
|
+
break;
|
|
2701
|
+
case NUM_OTHERTYPE:
|
|
2702
|
+
default:
|
|
2703
|
+
if (num_real_p(x))
|
|
2704
|
+
return quadmath_yn_realsolve(vorder, GetF128(x));
|
|
2705
|
+
else
|
|
2706
|
+
return quadmath_yn_nucompsolve(vorder, GetC128(x));
|
|
2707
|
+
break;
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
|
|
2711
|
+
void
|
|
2712
|
+
InitVM_QuadMath(void)
|
|
2713
|
+
{
|
|
2714
|
+
/* Math-Functions */
|
|
2715
|
+
rb_define_module_function(rb_mQuadMath, "exp", quadmath_exp, 1);
|
|
2716
|
+
rb_define_module_function(rb_mQuadMath, "exp2", quadmath_exp2, 1);
|
|
2717
|
+
rb_define_module_function(rb_mQuadMath, "expm1", quadmath_expm1, 1);
|
|
2718
|
+
rb_define_module_function(rb_mQuadMath, "log", quadmath_log, 1);
|
|
2719
|
+
rb_define_module_function(rb_mQuadMath, "log2", quadmath_log2, 1);
|
|
2720
|
+
rb_define_module_function(rb_mQuadMath, "log10", quadmath_log10, 1);
|
|
2721
|
+
rb_define_module_function(rb_mQuadMath, "log1p", quadmath_log1p, 1);
|
|
2722
|
+
rb_define_module_function(rb_mQuadMath, "sqrt", quadmath_sqrt, 1);
|
|
2723
|
+
rb_define_module_function(rb_mQuadMath, "sqrt3", quadmath_sqrt3, 1);
|
|
2724
|
+
rb_define_module_function(rb_mQuadMath, "cbrt", quadmath_cbrt, 1);
|
|
2725
|
+
rb_define_module_function(rb_mQuadMath, "sin", quadmath_sin, 1);
|
|
2726
|
+
rb_define_module_function(rb_mQuadMath, "cos", quadmath_cos, 1);
|
|
2727
|
+
rb_define_module_function(rb_mQuadMath, "tan", quadmath_tan, 1);
|
|
2728
|
+
rb_define_module_function(rb_mQuadMath, "asin", quadmath_asin, 1);
|
|
2729
|
+
rb_define_module_function(rb_mQuadMath, "acos", quadmath_acos, 1);
|
|
2730
|
+
rb_define_module_function(rb_mQuadMath, "atan", quadmath_atan, 1);
|
|
2731
|
+
rb_define_module_function(rb_mQuadMath, "atan2", quadmath_atan2, 2);
|
|
2732
|
+
rb_define_module_function(rb_mQuadMath, "quadrant", quadmath_quadrant, 2);
|
|
2733
|
+
rb_define_module_function(rb_mQuadMath, "sinh", quadmath_sinh, 1);
|
|
2734
|
+
rb_define_module_function(rb_mQuadMath, "cosh", quadmath_cosh, 1);
|
|
2735
|
+
rb_define_module_function(rb_mQuadMath, "tanh", quadmath_tanh, 1);
|
|
2736
|
+
rb_define_module_function(rb_mQuadMath, "asinh", quadmath_asinh, 1);
|
|
2737
|
+
rb_define_module_function(rb_mQuadMath, "acosh", quadmath_acosh, 1);
|
|
2738
|
+
rb_define_module_function(rb_mQuadMath, "atanh", quadmath_atanh, 1);
|
|
2739
|
+
rb_define_module_function(rb_mQuadMath, "hypot", quadmath_hypot, 2);
|
|
2740
|
+
rb_define_module_function(rb_mQuadMath, "erf", quadmath_erf, 1);
|
|
2741
|
+
rb_define_module_function(rb_mQuadMath, "erfc", quadmath_erfc, 1);
|
|
2742
|
+
rb_define_module_function(rb_mQuadMath, "lgamma", quadmath_lgamma, 1);
|
|
2743
|
+
rb_define_module_function(rb_mQuadMath, "lgamma_r", quadmath_lgamma_r, 1);
|
|
2744
|
+
rb_define_module_function(rb_mQuadMath, "signgam", quadmath_lgamma_r, 1);
|
|
2745
|
+
rb_define_module_function(rb_mQuadMath, "gamma", quadmath_gamma, 1);
|
|
2746
|
+
rb_define_module_function(rb_mQuadMath, "j0", quadmath_j0, 1);
|
|
2747
|
+
rb_define_module_function(rb_mQuadMath, "j1", quadmath_j1, 1);
|
|
2748
|
+
rb_define_module_function(rb_mQuadMath, "jn", quadmath_jn, 2);
|
|
2749
|
+
rb_define_module_function(rb_mQuadMath, "y0", quadmath_y0, 1);
|
|
2750
|
+
rb_define_module_function(rb_mQuadMath, "y1", quadmath_y1, 1);
|
|
2751
|
+
rb_define_module_function(rb_mQuadMath, "yn", quadmath_yn, 2);
|
|
2752
|
+
|
|
2753
|
+
|
|
2754
|
+
/* Math-Constants */
|
|
2755
|
+
rb_define_const(rb_mQuadMath, "E", rb_float128_cf128(M_Eq));
|
|
2756
|
+
rb_define_const(rb_mQuadMath, "LOG2E", rb_float128_cf128(M_LOG2Eq));
|
|
2757
|
+
rb_define_const(rb_mQuadMath, "LOG10E", rb_float128_cf128(M_LOG10Eq));
|
|
2758
|
+
rb_define_const(rb_mQuadMath, "LN2", rb_float128_cf128(M_LN2q));
|
|
2759
|
+
rb_define_const(rb_mQuadMath, "LN10", rb_float128_cf128(M_LN10q));
|
|
2760
|
+
rb_define_const(rb_mQuadMath, "PI", rb_float128_cf128(M_PIq));
|
|
2761
|
+
rb_define_const(rb_mQuadMath, "PI_2", rb_float128_cf128(M_PI_2q));
|
|
2762
|
+
rb_define_const(rb_mQuadMath, "PI_4", rb_float128_cf128(M_PI_4q));
|
|
2763
|
+
rb_define_const(rb_mQuadMath, "ONE_PI", rb_float128_cf128(M_1_PIq));
|
|
2764
|
+
rb_define_const(rb_mQuadMath, "TWO_PI", rb_float128_cf128(M_2_PIq));
|
|
2765
|
+
rb_define_const(rb_mQuadMath, "TWO_SQRTPI", rb_float128_cf128(M_2_SQRTPIq));
|
|
2766
|
+
rb_define_const(rb_mQuadMath, "SQRT2", rb_float128_cf128(M_SQRT2q));
|
|
2767
|
+
rb_define_const(rb_mQuadMath, "SQRT1_2", rb_float128_cf128(M_SQRT1_2q));
|
|
2768
|
+
}
|