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