1 /*
2  * number.h - Public API for Scheme numbers
3  *
4  *   Copyright (c) 2000-2020  Shiro Kawai  <shiro@acm.org>
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *   1. Redistributions of source code must retain the above copyright
11  *      notice, this list of conditions and the following disclaimer.
12  *
13  *   2. Redistributions in binary form must reproduce the above copyright
14  *      notice, this list of conditions and the following disclaimer in the
15  *      documentation and/or other materials provided with the distribution.
16  *
17  *   3. Neither the name of the authors nor the names of its contributors
18  *      may be used to endorse or promote products derived from this
19  *      software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27  *   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28  *   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29  *   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31  *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /* This file is included from gauche.h */
35 
36 #ifndef GAUCHE_NUMBER_H
37 #define GAUCHE_NUMBER_H
38 
39 /* "Normalized" numbers
40  *
41  * In Scheme world, numbers should be always in normalized form.
42  *
43  *  - Exact integers that can be representable in fixnum should be in
44  *    the fixnum form, not in the bignum form.
45  *  - Complex numbers whose imaginary part is 0.0 should be in the flonum
46  *    form, not in the complexnum form.
47  *
48  * Some C API returns anormalized numbers to avoid unnecessary
49  * conversion overhead.  These anormalized numbers shuold be used
50  * strictly in the intermediate form within C world.  Anything that
51  * is passed back to Scheme world must be normalized.
52  */
53 
54 #define SCM_SMALL_INT_SIZE         (SIZEOF_LONG*8-3)
55 #define SCM_SMALL_INT_MAX          ((1L << SCM_SMALL_INT_SIZE) - 1)
56 #define SCM_SMALL_INT_MIN          (-SCM_SMALL_INT_MAX-1)
57 #define SCM_SMALL_INT_FITS(k) \
58     (((k)<=SCM_SMALL_INT_MAX)&&((k)>=SCM_SMALL_INT_MIN))
59 
60 #define SCM_RADIX_MAX              36
61 #define SCM_RADIX_MIN              2
62 
63 #define SCM_INTEGERP(obj)          (SCM_INTP(obj) || SCM_BIGNUMP(obj))
64 #define SCM_RATIONALP(obj)         (SCM_INTEGERP(obj)||SCM_RATNUMP(obj))
65 #define SCM_REALP(obj)             (SCM_RATIONALP(obj)||SCM_FLONUMP(obj))
66 #define SCM_NUMBERP(obj)           (SCM_REALP(obj)||SCM_COMPNUMP(obj))
67 #define SCM_EXACTP(obj)            SCM_RATIONALP(obj)
68 #define SCM_INEXACTP(obj)          (SCM_FLONUMP(obj)||SCM_COMPNUMP(obj))
69 
70 #define SCM_EXACT_ZERO_P(obj)      SCM_EQ(obj, SCM_MAKE_INT(0))
71 #define SCM_EXACT_ONE_P(obj)       SCM_EQ(obj, SCM_MAKE_INT(1))
72 
73 #define SCM_UINTEGERP(obj) \
74     (SCM_UINTP(obj) || (SCM_BIGNUMP(obj)&&SCM_BIGNUM_SIGN(obj)>=0))
75 
76 SCM_CLASS_DECL(Scm_NumberClass);
77 SCM_CLASS_DECL(Scm_ComplexClass);
78 SCM_CLASS_DECL(Scm_RealClass);
79 SCM_CLASS_DECL(Scm_RationalClass);
80 SCM_CLASS_DECL(Scm_IntegerClass);
81 
82 #define SCM_CLASS_NUMBER        (&Scm_NumberClass)
83 #define SCM_CLASS_COMPLEX       (&Scm_ComplexClass)
84 #define SCM_CLASS_REAL          (&Scm_RealClass)
85 #define SCM_CLASS_RATIONAL      (&Scm_RationalClass)
86 #define SCM_CLASS_INTEGER       (&Scm_IntegerClass)
87 
88 struct ScmBignumRec {
89     SCM_HEADER;
90     int sign : 2;
91     unsigned int size : (SIZEOF_INT*CHAR_BIT-2);
92     unsigned long values[1];           /* variable length */
93 };
94 
95 #define SCM_BIGNUM(obj)        ((ScmBignum*)(obj))
96 #define SCM_BIGNUMP(obj)       SCM_XTYPEP(obj, SCM_CLASS_INTEGER)
97 #define SCM_BIGNUM_SIZE(obj)   SCM_BIGNUM(obj)->size
98 #define SCM_BIGNUM_SIGN(obj)   SCM_BIGNUM(obj)->sign
99 
100 #define SCM_BIGNUM_MAX_DIGITS  ((1UL<<(SIZEOF_INT*CHAR_BIT-2))-1)
101 
102 struct ScmRatnumRec {
103     SCM_HEADER;
104     ScmObj numerator;
105     ScmObj denominator;
106 };
107 
108 #define SCM_RATNUM(obj)            ((ScmRatnum*)(obj))
109 #define SCM_RATNUMP(obj)           SCM_XTYPEP(obj, SCM_CLASS_RATIONAL)
110 #define SCM_RATNUM_NUMER(obj)      SCM_RATNUM(obj)->numerator
111 #define SCM_RATNUM_DENOM(obj)      SCM_RATNUM(obj)->denominator
112 
113 struct ScmCompnumRec {
114     SCM_HEADER;
115     double real;
116     double imag;
117 };
118 
119 #define SCM_COMPNUM(obj)           ((ScmCompnum*)(obj))
120 #define SCM_COMPNUMP(obj)          SCM_XTYPEP(obj, SCM_CLASS_COMPLEX)
121 #define SCM_COMPNUM_REAL(obj)      SCM_COMPNUM(obj)->real
122 #define SCM_COMPNUM_IMAG(obj)      SCM_COMPNUM(obj)->imag
123 
124 /*
125    Internal macros concerning FFX (fast flonum extension).  Normal
126    users doesn't need to care about these.
127 
128    When GAUCHE_FFX is defined,
129    new flonums generated by the system is put in the designated area
130    of the VM instead of the heap, thus eliminating most of
131    intermediate flonum allocations.  Flonum pointers have two flavors;
132    if SCM_FLONUM_REG_P is true, it is allocated in the VM registers,
133    and if SCM_FLONUM_MEM_P is true, it is allocated in heap.  An
134    invariance: only ScmObjs in VM stack are allowed to be FLONUM_REGs.
135    If such an ScmObj is moved to the heap, a new FLONUM_MEM is
136    allocated and the pointer is fixed.
137 
138    User routines don't usually receive or return FLONUM_REGs.  If the
139    routine is directly called from VM as SUBR, and it never stores
140    received ScmObjs in the heap (in other words, if the routine
141    immediately retrieves doubles from the received ScmObjs), the
142    routine denotes the fact by marking its stub with "immediate-arg"
143    so that VM can pass FLONUM_REGs.  If the routine is sure that its
144    return value is used directly by the VM, it can call
145    Scm_VMReturnFlonum to generate FLONUM_REGs.
146  */
147 
148 #define SCM_MAKE_FLONUM_REG(dptr)  SCM_OBJ(SCM_WORD(dptr)+0x02)
149 #define SCM_MAKE_FLONUM_MEM(dptr)  SCM_OBJ(SCM_WORD(dptr)+0x06)
150 
151 #define SCM_FLONUM_REG_P(obj)      ((SCM_WORD(obj)&0x7) == 0x02)
152 #define SCM_FLONUM_MEM_P(obj)      ((SCM_WORD(obj)&0x7) == 0x06)
153 
154 #if GAUCHE_FFX
155 #define SCM_FLONUM_ENSURE_MEM(var)                              \
156     do {                                                        \
157         if (SCM_FLONUM_REG_P(var)) {                            \
158             var = Scm_MakeFlonum(SCM_FLONUM_VALUE(var));        \
159         }                                                       \
160     } while (0)
161 #else  /*!GAUCHE_FFX*/
162 #define SCM_FLONUM_ENSURE_MEM(var) /* empty */
163 #endif /*!GAUCHE_FFX*/
164 
165 /* Converting a Scheme number to a C number:
166  *
167  * It's a tricky business.  It's always possible that the Scheme number
168  * you got may not fit into the desired C variable.  There are several
169  * options you can choose.
170  *
171  *  - Error.  Throws an error.
172  *  - Clamping.  If the Scheme value falls out of the supported range
173  *    of C variable, use the closest representable value.
174  *  - Convert only when possible.  If conversion is not possible, use
175  *    the Scheme value as-is.  It is useful to provide a shortcut path
176  *    to improve performance.
177  *
178  * Some APIs take 'clamp' argument to specify the behavior.  The value
179  * can be one of the SCM_CLAMP_* enums.  If an API supports SCM_CLAMP_NONE,
180  * it also takes an output argument to return a flag whether the argument
181  * is out of range or not.  This output argument can be NULL if the caller
182  * doesn't specify SCM_CLAMP_NONE flag.
183  */
184 
185 enum ScmClampMode {
186     SCM_CLAMP_ERROR = 0,       /* throws an error when out-of-range */
187     SCM_CLAMP_HI = 1,
188     SCM_CLAMP_LO = 2,
189     SCM_CLAMP_BOTH = 3,
190     SCM_CLAMP_NONE = 4         /* do not convert when out-of-range */
191 };
192 
193 SCM_EXTERN int    Scm_ClampMode(ScmObj clamp);
194 
195 SCM_EXTERN ScmObj Scm_MakeInteger(long i);
196 SCM_EXTERN ScmObj Scm_MakeIntegerU(u_long i);
197 
198 SCM_EXTERN long   Scm_GetIntegerClamp(ScmObj obj, int clamp, int *oor);
199 SCM_EXTERN u_long Scm_GetIntegerUClamp(ScmObj obj, int clamp, int *oor);
200 SCM_EXTERN int    Scm_GetInteger8Clamp(ScmObj obj, int clamp, int *oor);
201 SCM_EXTERN u_int  Scm_GetIntegerU8Clamp(ScmObj obj, int clamp, int *oor);
202 SCM_EXTERN int    Scm_GetInteger16Clamp(ScmObj obj, int clamp, int *oor);
203 SCM_EXTERN u_int  Scm_GetIntegerU16Clamp(ScmObj obj, int clamp, int *oor);
204 SCM_EXTERN int32_t  Scm_GetInteger32Clamp(ScmObj obj, int clamp, int *oor);
205 SCM_EXTERN uint32_t Scm_GetIntegerU32Clamp(ScmObj obj, int clamp, int *oor);
206 
207 SCM_EXTERN u_long Scm_GetIntegerUMod(ScmObj obj);
208 
209 /* 64bit integer stuff */
210 #if SIZEOF_LONG == 4
211 SCM_EXTERN ScmObj Scm_MakeInteger64(int64_t i);
212 SCM_EXTERN ScmObj Scm_MakeIntegerU64(uint64_t i);
213 SCM_EXTERN int64_t  Scm_GetInteger64Clamp(ScmObj obj, int clamp, int *oor);
214 SCM_EXTERN uint64_t Scm_GetIntegerU64Clamp(ScmObj obj, int clamp, int *oor);
215 #else  /* SIZEOF_LONG >= 8 */
216 #define Scm_MakeInteger64      Scm_MakeInteger
217 #define Scm_MakeIntegerU64     Scm_MakeIntegerU
218 #define Scm_GetInteger64Clamp  Scm_GetIntegerClamp
219 #define Scm_GetIntegerU64Clamp Scm_GetIntegerUClamp
220 #endif /* SIZEOF_LONG >= 8 */
221 
222 /* Convenience macros - Scm_GetInteger() family throws an error when
223    the input is out-of-range.
224    NB: Before 0.9.4, we only had Scm_GetInteger, Scm_GetIntegerU,
225    Scm_GetInteger64 and Scm_GetIntegerU64, and they were clamping.
226    We change it in 0.9.4 to make error-signaling default, in the spirit
227    of safety by default.
228 */
229 #define Scm_GetInteger(x)    Scm_GetIntegerClamp(x, SCM_CLAMP_ERROR, NULL)
230 #define Scm_GetIntegerU(x)   Scm_GetIntegerUClamp(x, SCM_CLAMP_ERROR, NULL)
231 #define Scm_GetInteger8(x)   Scm_GetInteger8Clamp(x, SCM_CLAMP_ERROR, NULL)
232 #define Scm_GetIntegerU8(x)  Scm_GetIntegerU8Clamp(x, SCM_CLAMP_ERROR, NULL)
233 #define Scm_GetInteger16(x)  Scm_GetInteger16Clamp(x, SCM_CLAMP_ERROR, NULL)
234 #define Scm_GetIntegerU16(x) Scm_GetIntegerU16Clamp(x, SCM_CLAMP_ERROR, NULL)
235 #define Scm_GetInteger32(x)  Scm_GetInteger32Clamp(x, SCM_CLAMP_ERROR, NULL)
236 #define Scm_GetIntegerU32(x) Scm_GetIntegerU32Clamp(x, SCM_CLAMP_ERROR, NULL)
237 #define Scm_GetInteger64(x)  Scm_GetInteger64Clamp(x, SCM_CLAMP_ERROR, NULL)
238 #define Scm_GetIntegerU64(x) Scm_GetIntegerU64Clamp(x, SCM_CLAMP_ERROR, NULL)
239 
240 /* for backward compatibility -- will be gone soon */
241 #define Scm_MakeIntegerFromUI(x) Scm_MakeIntegerU(x)
242 #define Scm_GetUInteger(x)       Scm_GetIntegerU(x)
243 
244 SCM_EXTERN ScmObj Scm_MakeRational(ScmObj numer, ScmObj denom);
245 SCM_EXTERN ScmObj Scm_MakeRatnum(ScmObj numer, ScmObj denom);
246 SCM_EXTERN ScmObj Scm_ReduceRational(ScmObj rational);
247 
248 SCM_EXTERN ScmObj Scm_MakeFlonum(double d);
249 SCM_EXTERN double Scm_GetDouble(ScmObj obj);
250 SCM_EXTERN ScmObj Scm_DecodeFlonum(double d, int *exp, int *sign);
251 SCM_EXTERN double Scm_EncodeFlonum(ScmObj mant, int exp, int sign);
252 SCM_EXTERN int    Scm_FlonumSign(double d);
253 SCM_EXTERN ScmObj Scm_MakeFlonumToNumber(double d, int exactp);
254 SCM_EXTERN double       Scm_HalfToDouble(ScmHalfFloat v);
255 SCM_EXTERN ScmHalfFloat Scm_DoubleToHalf(double v);
256 
257 SCM_EXTERN ScmObj Scm_MakeCompnum(double real, double imag);
258 SCM_EXTERN ScmObj Scm_MakeComplex(double real, double imag);
259 SCM_EXTERN ScmObj Scm_MakeComplexPolar(double magnitude, double angle);
260 SCM_EXTERN ScmHalfComplex Scm_GetHalfComplex(ScmObj obj);
261 SCM_EXTERN ScmFloatComplex  Scm_GetFloatComplex(ScmObj obj);
262 SCM_EXTERN ScmDoubleComplex Scm_GetDoubleComplex(ScmObj obj);
263 SCM_EXTERN ScmObj Scm_HalfComplexToComplex(const ScmHalfComplex c);
264 SCM_EXTERN ScmObj Scm_FloatComplexToComplex(const ScmFloatComplex c);
265 SCM_EXTERN ScmObj Scm_DoubleComplexToComplex(const ScmDoubleComplex c);
266 
267 SCM_EXTERN int    Scm_IntegerP(ScmObj obj);
268 SCM_EXTERN int    Scm_OddP(ScmObj obj);
269 SCM_EXTERN int    Scm_FiniteP(ScmObj obj);
270 SCM_EXTERN int    Scm_InfiniteP(ScmObj obj);
271 SCM_EXTERN int    Scm_NanP(ScmObj obj);
272 SCM_EXTERN ScmObj Scm_Abs(ScmObj obj);
273 SCM_EXTERN int    Scm_Sign(ScmObj obj);
274 SCM_EXTERN ScmObj Scm_Negate(ScmObj obj);
275 SCM_EXTERN ScmObj Scm_Reciprocal(ScmObj obj);
276 SCM_EXTERN ScmObj Scm_ReciprocalInexact(ScmObj obj);
277 
278 /* TODO: We'll switch to make Scm_Exact/Scm_Inexact official in 1.0
279    and obsolete longer versions.  During 0.9.x we keep the old name
280    for binary compatibility. */
281 SCM_EXTERN ScmObj Scm_InexactToExact(ScmObj obj);
282 SCM_EXTERN ScmObj Scm_ExactToInexact(ScmObj obj);
283 #define Scm_Exact    Scm_InexactToExact
284 #define Scm_Inexact  Scm_ExactToInexact
285 
286 SCM_EXTERN ScmObj Scm_Add(ScmObj arg1, ScmObj arg2);
287 SCM_EXTERN ScmObj Scm_Sub(ScmObj arg1, ScmObj arg2);
288 SCM_EXTERN ScmObj Scm_Mul(ScmObj arg1, ScmObj arg2);
289 SCM_EXTERN ScmObj Scm_Div(ScmObj arg1, ScmObj arg2);
290 SCM_EXTERN ScmObj Scm_DivInexact(ScmObj arg1, ScmObj arg2);
291 SCM_EXTERN ScmObj Scm_DivCompat(ScmObj arg1, ScmObj arg2);
292 
293 SCM_EXTERN ScmObj Scm_Quotient(ScmObj arg1, ScmObj arg2, ScmObj *rem);
294 SCM_EXTERN ScmObj Scm_Modulo(ScmObj arg1, ScmObj arg2, int remainder);
295 SCM_EXTERN ScmObj Scm_Gcd(ScmObj x, ScmObj y);
296 
297 SCM_EXTERN ScmObj Scm_Expt(ScmObj x, ScmObj y);
298 SCM_EXTERN ScmObj Scm_ExactIntegerExpt(ScmObj x, ScmObj y);
299 SCM_EXTERN long   Scm_TwosPower(ScmObj n);
300 SCM_EXTERN double Scm_SinPi(double x);
301 SCM_EXTERN double Scm_CosPi(double x);
302 SCM_EXTERN double Scm_TanPi(double x);
303 
304 SCM_EXTERN int    Scm_NumEq(ScmObj x, ScmObj y);
305 SCM_EXTERN int    Scm_NumLT(ScmObj x, ScmObj y);
306 SCM_EXTERN int    Scm_NumLE(ScmObj x, ScmObj y);
307 SCM_EXTERN int    Scm_NumGT(ScmObj x, ScmObj y);
308 SCM_EXTERN int    Scm_NumGE(ScmObj x, ScmObj y);
309 SCM_EXTERN int    Scm_NumCmp(ScmObj x, ScmObj y);
310 SCM_EXTERN void   Scm_MinMax(ScmObj arg0, ScmObj args, ScmObj *min, ScmObj *max);
311 
312 SCM_EXTERN ScmObj Scm_LogAnd(ScmObj x, ScmObj y);
313 SCM_EXTERN ScmObj Scm_LogIor(ScmObj x, ScmObj y);
314 SCM_EXTERN ScmObj Scm_LogXor(ScmObj x, ScmObj y);
315 SCM_EXTERN ScmObj Scm_LogNot(ScmObj x);
316 SCM_EXTERN ScmObj Scm_Ash(ScmObj x, ScmSmallInt cnt);
317 
318 enum ScmRoundMode {
319     SCM_ROUND_FLOOR,
320     SCM_ROUND_CEIL,
321     SCM_ROUND_TRUNC,
322     SCM_ROUND_ROUND
323 };
324 SCM_EXTERN ScmObj Scm_Round(ScmObj num, int mode);
325 SCM_EXTERN ScmObj Scm_RoundToExact(ScmObj num, int mode);
326 
327 SCM_EXTERN ScmObj Scm_Numerator(ScmObj n);
328 SCM_EXTERN ScmObj Scm_Denominator(ScmObj n);
329 
330 SCM_EXTERN double Scm_Magnitude(ScmObj z);
331 SCM_EXTERN double Scm_Angle(ScmObj z);
332 SCM_EXTERN double Scm_RealPart(ScmObj z);
333 SCM_EXTERN double Scm_ImagPart(ScmObj z);
334 
335 /* Flags for ScmNumberFormat.  Scm_NumberToString and Scm_StringToNumber
336    also take those flags.  The [N] and [S] mark the meaning of the flag
337    in Scm_NumberToString and Scm_StringToNumber, respectively. */
338 enum ScmNumberFormatFlags {
339     SCM_NUMBER_FORMAT_USE_UPPER = (1L<<0), /* use ABCDEF.. for base > 10
340                                               [N] same.
341                                               [S] ignored. */
342     SCM_NUMBER_FORMAT_SHOW_PLUS = (1L<<1), /* show '+' in positive number
343                                               [N] same.
344                                               [S] ignored. */
345     SCM_NUMBER_FORMAT_ALT_RADIX = (1L<<2), /* alternative radix prefix handling
346                                               specifying non-default behavior
347                                               (the actual behavior differs
348                                               between N and S:
349                                               [N] always add radix prefix
350                                               [S] never allow radix prefix */
351     SCM_NUMBER_FORMAT_ROUND_NOTATIONAL = (1L<<3),
352                                            /* Using notational decimal rounding.
353                                               [N] When rounding fractional part,
354                                               we first generate the closest
355                                               decimal notation, then round.
356                                               [S] ignored.
357                                             */
358     SCM_NUMBER_FORMAT_STRICT_R7RS = (1L<<4),/*[N] ignored.
359                                               [S] reject syntax outside of R7RS*/
360     SCM_NUMBER_FORMAT_EXACT = (1L<<5),    /* [N] ignored.
361                                              [S] treat as if #e is present if
362                                              no exactness prefix is given */
363     SCM_NUMBER_FORMAT_INEXACT = (1L<<6)   /* [N] ignored.
364                                              [S] treat as if #i is present if
365                                              no exactness prefix is given */
366 };
367 
368 typedef struct ScmNumberFormatRec {
369     u_long flags;
370     int radix;
371     int precision;    /* # of digits after decimal point, -1 for unlimited */
372     int exp_lo;       /* use exp notation if exponent <= exp_lo */
373     int exp_hi;       /* use exp notation if exponent >= exp_hi */
374     int exp_width;    /* min # of digits used for exponent */
375 } ScmNumberFormat;
376 
377 SCM_EXTERN void   Scm_NumberFormatInit(ScmNumberFormat*);
378 SCM_EXTERN size_t Scm_PrintNumber(ScmPort *port, ScmObj n, ScmNumberFormat *f);
379 SCM_EXTERN size_t Scm_PrintDouble(ScmPort *port, double d, ScmNumberFormat *f);
380 
381 /* Higher-level convenience routines */
382 SCM_EXTERN ScmObj Scm_NumberToString(ScmObj num, int radix, u_long flags);
383 SCM_EXTERN ScmObj Scm_StringToNumber(ScmString *str, int radix, u_long flags);
384 
385 /* The Scm_VM* version leaves unboxed flonum (FLONUM_REG) in VM's VAL0
386    register.   They can only be called "on VM", that is, when its return
387    value is used immediately by VM. */
388 
389 SCM_EXTERN ScmObj Scm_VMNegate(ScmObj obj);
390 SCM_EXTERN ScmObj Scm_VMReciprocal(ScmObj obj);
391 SCM_EXTERN ScmObj Scm_VMReciprocalInexact(ScmObj obj);
392 SCM_EXTERN ScmObj Scm_VMExactToInexact(ScmObj obj); /* during 0.9 for backward compatibility */
393 #define Scm_VMInexact Scm_VMExactToInexact          /* on 1.0, shorter name will be a real name */
394 SCM_EXTERN ScmObj Scm_VMAbs(ScmObj obj);
395 SCM_EXTERN ScmObj Scm_VMAdd(ScmObj arg1, ScmObj arg2);
396 SCM_EXTERN ScmObj Scm_VMSub(ScmObj arg1, ScmObj arg2);
397 SCM_EXTERN ScmObj Scm_VMMul(ScmObj arg1, ScmObj arg2);
398 SCM_EXTERN ScmObj Scm_VMDiv(ScmObj arg1, ScmObj arg2);
399 SCM_EXTERN ScmObj Scm_VMDivInexact(ScmObj arg1, ScmObj arg2);
400 SCM_EXTERN ScmObj Scm_VMExpt(ScmObj x, ScmObj y);
401 SCM_EXTERN ScmObj Scm_VMRound(ScmObj num, int mode);
402 
403 #endif /* GAUCHE_NUMBER_H */
404 
405