1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
#ifndef RBIMPL_INTERN_RATIONAL_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_RATIONAL_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cRational.
*/
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/arithmetic/long.h" /* INT2FIX is here. */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* rational.c */
/**
* Identical to rb_rational_new(), except it skips argument validations. It is
* thus dangerous for extension libraries. For instance `1/0r` could be
* constructed using this.
*
* @param[in] num Numerator, an instance of ::rb_cInteger.
* @param[in] den Denominator, an instance of ::rb_cInteger.
* @exception rb_eTypeError Either argument is not an Integer.
* @return An instance of ::rb_cRational whose value is `(num/den)r`.
*/
VALUE rb_rational_raw(VALUE num, VALUE den);
/**
* Shorthand of `(x/1)r`. As `x` is already an Integer, it practically
* converts it into a Rational of the identical value.
*
* @param[in] x An instance of ::rb_cInteger.
* @return An instance of ::rb_cRational, whose value is `(x/1)r`.
*/
#define rb_rational_raw1(x) rb_rational_raw((x), INT2FIX(1))
/** @alias{rb_rational_raw} */
#define rb_rational_raw2(x,y) rb_rational_raw((x), (y))
/**
* Constructs a Rational, with reduction. This returns for instance `(2/3)r`
* for `rb_rational_new(INT2NUM(-384), INT2NUM(-576))`.
*
* @param[in] num Numerator, an instance of ::rb_cInteger.
* @param[in] den Denominator, an instance of ::rb_cInteger.
* @exception rb_eZeroDivError `den` is zero.
* @return An instance of ::rb_cRational whose value is `(num/den)r`.
*/
VALUE rb_rational_new(VALUE num, VALUE den);
/**
* Shorthand of `(x/1)r`. As `x` is already an Integer, it practically
* converts it into a Rational of the identical value.
*
* @param[in] x An instance of ::rb_cInteger.
* @return An instance of ::rb_cRational, whose value is `(x/1)r`.
*/
#define rb_rational_new1(x) rb_rational_new((x), INT2FIX(1))
/** @alias{rb_rational_new} */
#define rb_rational_new2(x,y) rb_rational_new((x), (y))
/**
* Converts various values into a Rational. This function accepts:
*
* - Instances of ::rb_cInteger (taken as-is),
* - Instances of ::rb_cRational (taken as-is),
* - Instances of ::rb_cFloat (applies `#to_r`),
* - Instances of ::rb_cComplex (applies `#to_r`),
* - Instances of ::rb_cString (applies `#to_r`),
* - Other objects that respond to `#to_r`.
*
* It (possibly recursively) applies `#to_r` until both sides become either
* Integer or Rational, then divides them.
*
* As a special case, passing ::RUBY_Qundef to `den` is the same as passing
* `RB_INT2NUM(1)`.
*
* @param[in] num Numerator (see above).
* @param[in] den Denominator (see above).
* @exception rb_eTypeError Passed something not described above.
* @exception rb_eFloatDomainError `#to_r` produced Nan/Inf.
* @exception rb_eZeroDivError `#to_r` produced zero for `den`.
* @return An instance of ::rb_cRational whose value is `(num/den)r`.
*
* @internal
*
* This was the implementation of `Kernel#Rational` before, but they diverged.
*/
VALUE rb_Rational(VALUE num, VALUE den);
/**
* Shorthand of `(x/1)r`. It practically converts it into a Rational of the
* identical value.
*
* @param[in] x ::rb_cInteger, ::rb_cRational, or something that responds to
* `#to_r`.
* @return An instance of ::rb_cRational, whose value is `(x/1)r`.
*/
#define rb_Rational1(x) rb_Rational((x), INT2FIX(1))
/** @alias{rb_Rational} */
#define rb_Rational2(x,y) rb_Rational((x), (y))
RBIMPL_ATTR_PURE()
/**
* Queries the numerator of the passed Rational.
*
* @param[in] rat An instance of ::rb_cRational.
* @return Its numerator part, which is an instance of ::rb_cInteger.
*/
VALUE rb_rational_num(VALUE rat);
RBIMPL_ATTR_PURE()
/**
* Queries the denominator of the passed Rational.
*
* @param[in] rat An instance of ::rb_cRational.
* @return Its denominator part, which is an instance of ::rb_cInteger
* greater than or equal to one..
*/
VALUE rb_rational_den(VALUE rat);
/**
* Simplified approximation of a float. It returns a rational `rat` which
* satisfies:
*
* ```
* flt - |prec| <= rat <= flt + |prec|
* ```
*
* ```ruby
* 3.141592.rationalize(0.001) # => (201/64)r
* 3.141592.rationalize(0.01)' # => (22/7)r
* 3.141592.rationalize(0.1)' # => (16/5)r
* 3.141592.rationalize(1)' # => (3/1)r
* ```
*
* @param[in] flt An instance of ::rb_cFloat to rationalise.
* @param[in] prec Another ::rb_cFloat, which is the "precision".
* @return Approximation of `flt`, in ::rb_cRational.
*/
VALUE rb_flt_rationalize_with_prec(VALUE flt, VALUE prec);
/**
* Identical to rb_flt_rationalize_with_prec(), except it auto-detects
* appropriate precision depending on the passed value.
*
* @param[in] flt An instance of ::rb_cFloat to rationalise.
* @return Approximation of `flt`, in ::rb_cRational.
*/
VALUE rb_flt_rationalize(VALUE flt);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_RATIONAL_H */
|