blob: e8d0d6857e0aa795de9e7297bdd52097221a6841 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum6610ad91995-01-04 19:07:38 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* Float object implementation */
33
Guido van Rossum2a9096b1990-10-21 22:15:08 +000034/* XXX There should be overflow checks here, but it's hard to check
35 for any kind of float exception without losing portability. */
36
Guido van Rossum3f5da241990-12-20 15:06:42 +000037#include "allobjects.h"
Guido van Rossume5372401993-03-16 12:15:04 +000038#include "modsupport.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000039
Guido van Rossumc211ee41990-12-20 23:06:26 +000040#include <errno.h>
Guido van Rossum3f5da241990-12-20 15:06:42 +000041#include <ctype.h>
Guido van Rossum07e3a7e1995-02-27 10:13:37 +000042#include "mymath.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000043
Guido van Rossum9575a441993-04-07 14:06:14 +000044#ifdef i860
45/* Cray APP has bogus definition of HUGE_VAL in <math.h> */
46#undef HUGE_VAL
47#endif
48
Guido van Rossum9d81b551996-06-26 18:27:19 +000049#if defined(HUGE_VAL) && !defined(CHECK)
Guido van Rossum7fa52f81991-12-16 15:43:14 +000050#define CHECK(x) if (errno != 0) ; \
51 else if (-HUGE_VAL <= (x) && (x) <= HUGE_VAL) ; \
52 else errno = ERANGE
Guido van Rossum9d81b551996-06-26 18:27:19 +000053#endif
54
55#ifndef CHECK
Guido van Rossum7fa52f81991-12-16 15:43:14 +000056#define CHECK(x) /* Don't know how to check */
57#endif
58
Guido van Rossum03093a21994-09-28 15:51:32 +000059#ifdef HAVE_LIMITS_H
60#include <limits.h>
61#endif
62
63#ifndef LONG_MAX
64#define LONG_MAX 0X7FFFFFFFL
65#endif
66
67#ifndef LONG_MIN
68#define LONG_MIN (-LONG_MAX-1)
69#endif
70
Guido van Rossum67ca7011995-02-13 16:38:41 +000071#ifdef __NeXT__
72#ifdef __sparc__
73/*
74 * This works around a bug in the NS/Sparc 3.3 pre-release
75 * limits.h header file.
76 * 10-Feb-1995 bwarsaw@cnri.reston.va.us
77 */
78#undef LONG_MIN
79#define LONG_MIN (-LONG_MAX-1)
80#endif
81#endif
82
Guido van Rossum07e3a7e1995-02-27 10:13:37 +000083#if !defined(__STDC__) && !defined(macintosh)
Guido van Rossum6923e131990-11-02 17:50:43 +000084extern double fmod PROTO((double, double));
85extern double pow PROTO((double, double));
86#endif
87
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000088object *
Guido van Rossum07e3a7e1995-02-27 10:13:37 +000089#ifdef __SC__
90newfloatobject(double fval)
91#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000092newfloatobject(fval)
93 double fval;
Guido van Rossum07e3a7e1995-02-27 10:13:37 +000094#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000095{
96 /* For efficiency, this code is copied from newobject() */
97 register floatobject *op = (floatobject *) malloc(sizeof(floatobject));
Guido van Rossum2a9096b1990-10-21 22:15:08 +000098 if (op == NULL)
99 return err_nomem();
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000100 op->ob_type = &Floattype;
101 op->ob_fval = fval;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000102 NEWREF(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000103 return (object *) op;
104}
105
Guido van Rossum234f9421993-06-17 12:35:49 +0000106static void
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000107float_dealloc(op)
108 object *op;
109{
110 DEL(op);
111}
112
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000113double
114getfloatvalue(op)
115 object *op;
116{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000117 number_methods *nb;
118 floatobject *fo;
119 double val;
120
121 if (op && is_floatobject(op))
122 return GETFLOATVALUE((floatobject*) op);
123
124 if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL ||
125 nb->nb_float == NULL) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000126 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127 return -1;
128 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000129
130 fo = (floatobject*) (*nb->nb_float) (op);
131 if (fo == NULL)
132 return -1;
133 if (!is_floatobject(fo)) {
134 err_setstr(TypeError, "nb_float should return float object");
135 return -1;
136 }
137
138 val = GETFLOATVALUE(fo);
139 DECREF(fo);
140
141 return val;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000142}
143
144/* Methods */
145
Guido van Rossum27dec7e1991-06-04 19:42:53 +0000146void
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000147float_buf_repr(buf, v)
148 char *buf;
149 floatobject *v;
150{
151 register char *cp;
152 /* Subroutine for float_repr and float_print.
153 We want float numbers to be recognizable as such,
154 i.e., they should contain a decimal point or an exponent.
155 However, %g may print the number as an integer;
156 in such cases, we append ".0" to the string. */
157 sprintf(buf, "%.12g", v->ob_fval);
158 cp = buf;
159 if (*cp == '-')
160 cp++;
161 for (; *cp != '\0'; cp++) {
162 /* Any non-digit means it's not an integer;
163 this takes care of NAN and INF as well. */
Guido van Rossum9fa2c111995-02-10 17:00:37 +0000164 if (!isdigit(Py_CHARMASK(*cp)))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000165 break;
166 }
167 if (*cp == '\0') {
168 *cp++ = '.';
169 *cp++ = '0';
170 *cp++ = '\0';
171 }
172}
173
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000174/* ARGSUSED */
Guido van Rossum90933611991-06-07 16:10:43 +0000175static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176float_print(v, fp, flags)
177 floatobject *v;
178 FILE *fp;
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000179 int flags; /* Not used but required by interface */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000180{
181 char buf[100];
182 float_buf_repr(buf, v);
183 fputs(buf, fp);
Guido van Rossum90933611991-06-07 16:10:43 +0000184 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000185}
186
187static object *
188float_repr(v)
189 floatobject *v;
190{
191 char buf[100];
192 float_buf_repr(buf, v);
193 return newstringobject(buf);
194}
195
196static int
197float_compare(v, w)
198 floatobject *v, *w;
199{
200 double i = v->ob_fval;
201 double j = w->ob_fval;
202 return (i < j) ? -1 : (i > j) ? 1 : 0;
203}
204
Guido van Rossum9bfef441993-03-29 10:43:31 +0000205static long
206float_hash(v)
207 floatobject *v;
208{
209 double intpart, fractpart;
210 int expo;
211 long x;
212 /* This is designed so that Python numbers with the same
213 value hash to the same value, otherwise comparisons
214 of mapping keys will turn out weird */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215
216#ifdef MPW /* MPW C modf expects pointer to extended as second argument */
217{
218 extended e;
219 fractpart = modf(v->ob_fval, &e);
220 intpart = e;
221}
222#else
Guido van Rossum9bfef441993-03-29 10:43:31 +0000223 fractpart = modf(v->ob_fval, &intpart);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224#endif
225
Guido van Rossum9bfef441993-03-29 10:43:31 +0000226 if (fractpart == 0.0) {
227 if (intpart > 0x7fffffffL || -intpart > 0x7fffffffL) {
228 /* Convert to long int and use its hash... */
229 object *w = dnewlongobject(v->ob_fval);
230 if (w == NULL)
231 return -1;
232 x = hashobject(w);
233 DECREF(w);
234 return x;
235 }
236 x = (long)intpart;
237 }
238 else {
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000239 /* Note -- if you change this code, also change the copy
240 in complexobject.c */
241 long hipart;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000242 fractpart = frexp(fractpart, &expo);
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000243 fractpart = fractpart * 2147483648.0; /* 2**31 */
244 hipart = (long)fractpart; /* Take the top 32 bits */
245 fractpart = (fractpart - (double)hipart) * 2147483648.0;
246 /* Get the next 32 bits */
247 x = hipart + (long)fractpart + (long)intpart + (expo << 15);
248 /* Combine everything */
Guido van Rossum9bfef441993-03-29 10:43:31 +0000249 }
250 if (x == -1)
251 x = -2;
252 return x;
253}
254
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000255static object *
256float_add(v, w)
257 floatobject *v;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000258 floatobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000259{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000260 double result;
261 PyFPE_START_PROTECT("add", return 0)
262 result = v->ob_fval + w->ob_fval;
263 PyFPE_END_PROTECT
264 return newfloatobject(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000265}
266
267static object *
268float_sub(v, w)
269 floatobject *v;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000270 floatobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000271{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000272 double result;
273 PyFPE_START_PROTECT("subtract", return 0)
274 result = v->ob_fval - w->ob_fval;
275 PyFPE_END_PROTECT
276 return newfloatobject(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000277}
278
279static object *
280float_mul(v, w)
281 floatobject *v;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000282 floatobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000284 double result;
285
286 PyFPE_START_PROTECT("multiply", return 0)
287 result = v->ob_fval * w->ob_fval;
288 PyFPE_END_PROTECT
289 return newfloatobject(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290}
291
292static object *
293float_div(v, w)
294 floatobject *v;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000295 floatobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000296{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000297 double result;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000298 if (w->ob_fval == 0) {
Guido van Rossum9a9fadd1991-12-10 13:56:55 +0000299 err_setstr(ZeroDivisionError, "float division");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000300 return NULL;
301 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000302 PyFPE_START_PROTECT("divide", return 0)
303 result = v->ob_fval / w->ob_fval;
304 PyFPE_END_PROTECT
305 return newfloatobject(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000306}
307
308static object *
309float_rem(v, w)
310 floatobject *v;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000311 floatobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000312{
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000313 double vx, wx;
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000314 double /* div, */ mod;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000315 wx = w->ob_fval;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000316 if (wx == 0.0) {
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000317 err_setstr(ZeroDivisionError, "float modulo");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000318 return NULL;
319 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000320 PyFPE_START_PROTECT("modulo", return 0)
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000321 vx = v->ob_fval;
322 mod = fmod(vx, wx);
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000323 /* div = (vx - mod) / wx; */
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000324 if (wx*mod < 0) {
325 mod += wx;
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000326 /* div -= 1.0; */
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000327 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000328 PyFPE_END_PROTECT
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000329 return newfloatobject(mod);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000330}
331
332static object *
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000333float_divmod(v, w)
334 floatobject *v;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000335 floatobject *w;
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000336{
Guido van Rossum15ecff41991-10-20 20:16:45 +0000337 double vx, wx;
338 double div, mod;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000339 wx = w->ob_fval;
Guido van Rossum15ecff41991-10-20 20:16:45 +0000340 if (wx == 0.0) {
Guido van Rossum9a9fadd1991-12-10 13:56:55 +0000341 err_setstr(ZeroDivisionError, "float divmod()");
Guido van Rossum15ecff41991-10-20 20:16:45 +0000342 return NULL;
343 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000344 PyFPE_START_PROTECT("divmod", return 0)
Guido van Rossum15ecff41991-10-20 20:16:45 +0000345 vx = v->ob_fval;
346 mod = fmod(vx, wx);
347 div = (vx - mod) / wx;
348 if (wx*mod < 0) {
349 mod += wx;
350 div -= 1.0;
351 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000352 PyFPE_END_PROTECT
Guido van Rossume5372401993-03-16 12:15:04 +0000353 return mkvalue("(dd)", div, mod);
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000354}
355
Guido van Rossum363078a1996-05-24 20:45:01 +0000356static double powu(x, n)
Guido van Rossum39739ea1996-01-12 01:22:56 +0000357 double x;
358 long n;
359{
360 double r = 1.;
361 double p = x;
362 long mask = 1;
363 while (mask > 0 && n >= mask) {
364 if (n & mask)
365 r *= p;
366 mask <<= 1;
367 p *= p;
368 }
369 return r;
370}
371
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000372static object *
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000373float_pow(v, w, z)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000374 floatobject *v;
Guido van Rossum39739ea1996-01-12 01:22:56 +0000375 object *w;
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000376 floatobject *z;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000377{
378 double iv, iw, ix;
Guido van Rossum39739ea1996-01-12 01:22:56 +0000379 long intw;
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000380 /* XXX Doesn't handle overflows if z!=None yet; it may never do so :(
381 * The z parameter is really only going to be useful for integers and
382 * long integers. Maybe something clever with logarithms could be done.
383 * [AMK]
384 */
Guido van Rossum39739ea1996-01-12 01:22:56 +0000385 iv = v->ob_fval;
386 iw = ((floatobject *)w)->ob_fval;
387 intw = (long)iw;
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000388 if (iw == intw && -10000 < intw && intw < 10000) {
Guido van Rossum39739ea1996-01-12 01:22:56 +0000389 /* Sort out special cases here instead of relying on pow() */
Guido van Rossum86c04c21996-08-09 20:50:14 +0000390 if (intw == 0) { /* x**0 is 1, even 0**0 */
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000391 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossum39739ea1996-01-12 01:22:56 +0000392 if ((object *)z!=None) {
393 ix=fmod(1.0, z->ob_fval);
394 if (ix!=0 && z->ob_fval<0) ix+=z->ob_fval;
395 }
396 else ix=1.0;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000397 PyFPE_END_PROTECT
Guido van Rossum39739ea1996-01-12 01:22:56 +0000398 return newfloatobject(ix);
Guido van Rossum70d93461991-05-28 21:57:39 +0000399 }
Guido van Rossum86c04c21996-08-09 20:50:14 +0000400 errno = 0;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000401 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000402 if (intw > 0)
403 ix = powu(iv, intw);
404 else
405 ix = 1./powu(iv, -intw);
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000406 PyFPE_END_PROTECT
Guido van Rossum86c04c21996-08-09 20:50:14 +0000407 }
408 else {
409 /* Sort out special cases here instead of relying on pow() */
Guido van Rossum39739ea1996-01-12 01:22:56 +0000410 if (iv == 0.0) {
411 if (iw < 0.0) {
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000412 err_setstr(ValueError,
413 "0.0 to a negative power");
Guido van Rossum39739ea1996-01-12 01:22:56 +0000414 return NULL;
415 }
416 return newfloatobject(0.0);
417 }
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000418 if (iv < 0.0) {
419 err_setstr(ValueError,
420 "negative number to a float power");
421 return NULL;
422 }
Guido van Rossum39739ea1996-01-12 01:22:56 +0000423 errno = 0;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000424 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossum39739ea1996-01-12 01:22:56 +0000425 ix = pow(iv, iw);
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000426 PyFPE_END_PROTECT
Guido van Rossum70d93461991-05-28 21:57:39 +0000427 }
Guido van Rossum7fa52f81991-12-16 15:43:14 +0000428 CHECK(ix);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000429 if (errno != 0) {
430 /* XXX could it be another type of error? */
431 err_errno(OverflowError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000432 return NULL;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000433 }
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000434 if ((object *)z!=None) {
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000435 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000436 ix=fmod(ix, z->ob_fval); /* XXX To Be Rewritten */
437 if ( ix!=0 &&
438 ((iv<0 && z->ob_fval>0) || (iv>0 && z->ob_fval<0) )) {
439 ix+=z->ob_fval;
440 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000441 PyFPE_END_PROTECT
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000442 }
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000443 return newfloatobject(ix);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000444}
445
446static object *
447float_neg(v)
448 floatobject *v;
449{
450 return newfloatobject(-v->ob_fval);
451}
452
453static object *
454float_pos(v)
455 floatobject *v;
456{
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000457 INCREF(v);
458 return (object *)v;
459}
460
461static object *
462float_abs(v)
463 floatobject *v;
464{
465 if (v->ob_fval < 0)
466 return float_neg(v);
467 else
468 return float_pos(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000469}
470
Guido van Rossum50b4ef61991-05-14 11:57:01 +0000471static int
472float_nonzero(v)
473 floatobject *v;
474{
475 return v->ob_fval != 0.0;
476}
477
Guido van Rossum234f9421993-06-17 12:35:49 +0000478static int
Guido van Rossume6eefc21992-08-14 12:06:52 +0000479float_coerce(pv, pw)
480 object **pv;
481 object **pw;
482{
483 if (is_intobject(*pw)) {
484 long x = getintvalue(*pw);
485 *pw = newfloatobject((double)x);
486 INCREF(*pv);
487 return 0;
488 }
489 else if (is_longobject(*pw)) {
490 *pw = newfloatobject(dgetlongvalue(*pw));
491 INCREF(*pv);
492 return 0;
493 }
494 return 1; /* Can't do it */
495}
496
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000497static object *
498float_int(v)
499 object *v;
500{
501 double x = getfloatvalue(v);
Guido van Rossum03093a21994-09-28 15:51:32 +0000502 if (x < 0 ? (x = ceil(x)) < (double)LONG_MIN
503 : (x = floor(x)) > (double)LONG_MAX) {
Guido van Rossum67ca7011995-02-13 16:38:41 +0000504 err_setstr(OverflowError, "float too large to convert");
Guido van Rossum03093a21994-09-28 15:51:32 +0000505 return NULL;
506 }
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000507 return newintobject((long)x);
508}
509
510static object *
511float_long(v)
512 object *v;
513{
514 double x = getfloatvalue(v);
515 return dnewlongobject(x);
516}
517
518static object *
519float_float(v)
520 object *v;
521{
522 INCREF(v);
523 return v;
524}
525
526
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000527static number_methods float_as_number = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000528 (binaryfunc)float_add, /*nb_add*/
529 (binaryfunc)float_sub, /*nb_subtract*/
530 (binaryfunc)float_mul, /*nb_multiply*/
531 (binaryfunc)float_div, /*nb_divide*/
532 (binaryfunc)float_rem, /*nb_remainder*/
533 (binaryfunc)float_divmod, /*nb_divmod*/
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000534 (ternaryfunc)float_pow, /*nb_power*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000535 (unaryfunc)float_neg, /*nb_negative*/
536 (unaryfunc)float_pos, /*nb_positive*/
537 (unaryfunc)float_abs, /*nb_absolute*/
538 (inquiry)float_nonzero, /*nb_nonzero*/
Guido van Rossum27acb331991-10-24 14:55:28 +0000539 0, /*nb_invert*/
540 0, /*nb_lshift*/
541 0, /*nb_rshift*/
542 0, /*nb_and*/
543 0, /*nb_xor*/
544 0, /*nb_or*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000545 (coercion)float_coerce, /*nb_coerce*/
546 (unaryfunc)float_int, /*nb_int*/
547 (unaryfunc)float_long, /*nb_long*/
548 (unaryfunc)float_float, /*nb_float*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000549 0, /*nb_oct*/
550 0, /*nb_hex*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000551};
552
553typeobject Floattype = {
554 OB_HEAD_INIT(&Typetype)
555 0,
556 "float",
557 sizeof(floatobject),
558 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000559 (destructor)float_dealloc, /*tp_dealloc*/
560 (printfunc)float_print, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000561 0, /*tp_getattr*/
562 0, /*tp_setattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000563 (cmpfunc)float_compare, /*tp_compare*/
564 (reprfunc)float_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000565 &float_as_number, /*tp_as_number*/
566 0, /*tp_as_sequence*/
567 0, /*tp_as_mapping*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000568 (hashfunc)float_hash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000569};