Added dnewlongobject(), function to convert double to long int.
This commit is contained in:
parent
ad40531aa1
commit
149e9ea24c
|
@ -28,8 +28,14 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
#include "allobjects.h"
|
||||
#include "longintrepr.h"
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* Forward: */
|
||||
extern object *long_mul PROTO((longobject *, object *));
|
||||
extern object *long_add PROTO((longobject *, object *));
|
||||
extern object *long_neg PROTO((longobject *));
|
||||
|
||||
static int ticker; /* XXX Could be shared with ceval? */
|
||||
|
||||
#define INTRCHECK(block) \
|
||||
|
@ -87,6 +93,39 @@ newlongobject(ival)
|
|||
return (object *)v;
|
||||
}
|
||||
|
||||
/* Create a new long int object from a C double */
|
||||
|
||||
object *
|
||||
dnewlongobject(dval)
|
||||
double dval;
|
||||
{
|
||||
longobject *v;
|
||||
double frac;
|
||||
int i, ndig, expo, neg;
|
||||
neg = 0;
|
||||
if (dval < 0.0) {
|
||||
neg = 1;
|
||||
dval = -dval;
|
||||
}
|
||||
frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
|
||||
if (expo <= 0)
|
||||
return newlongobject(0L);
|
||||
ndig = (expo-1) / SHIFT + 1; /* Number of 'digits' in result */
|
||||
v = alloclongobject(ndig);
|
||||
if (v == NULL)
|
||||
return NULL;
|
||||
frac = ldexp(frac, (expo-1) % SHIFT + 1);
|
||||
for (i = ndig; --i >= 0; ) {
|
||||
long bits = (long)frac;
|
||||
v->ob_digit[i] = bits;
|
||||
frac = frac - (double)bits;
|
||||
frac = ldexp(frac, SHIFT);
|
||||
}
|
||||
if (neg)
|
||||
v->ob_size = -v->ob_size;
|
||||
return (object *)v;
|
||||
}
|
||||
|
||||
/* Get a C long int from a long int object.
|
||||
Returns -1 and sets an error condition if overflow occurs. */
|
||||
|
||||
|
|
Loading…
Reference in New Issue