Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

automatic conversion to floating-point on integer overflow

56 views
Skip to first unread message

luserdroog

unread,
Jun 2, 2014, 1:40:48 AM6/2/14
to
Before adding more types or re-implementing inca "1"'s functions,
I've been trying to give lots of thought to what other features
are best incorporated early. Handing integer overflow seems like
a good candidate.

The interesting question that grabs my attention is:
if you're in the middle of performing the iterations
of a function upon the ravel of an array, and detect
an integer overflow, do you restart the loop?

Or, do you stop and convert the existing results
and then continue with floating-point on the remaining
members? This method would have a quirk with division,
that results lower in the ravel than the first overflow
would be missing their fractional parts.

Now that I write it out, Meh. Restarting is simpler.

...

For some goodies, here are the C functions for overflow
detection that I use in xpost, mostly derived from the
examples in the C FAQ.

http://code.google.com/p/xpost/source/browse/src/bin/xpost_op_math.c

static
int subwillunder(long x, long y);

static
int addwillover(long x,
long y)
{
if (y < 0) return subwillunder(x, -y);
if (x > LONG_MAX - y) return 1;
if (y == LONG_MIN) return 1;
return 0;
}

static
int subwillunder(long x,
long y)
{
if (y < 0) return addwillover(x, -y);
if (x < LONG_MIN + y) return 1;
if (y == LONG_MIN) return 1;
return 0;
}

static
int mulwillover(long x,
long y)
{
if (x == 0||y == 0) return 0;
if (x < 0) x = -x;
if (y < 0) y = -y;
if (x > LONG_MAX / y) return 1;
return 0;
}



And here's the integer addition function
that uses them.

/* num1 num2 add sum
num1 plus num2 */
static
int Iadd (Xpost_Context *ctx,
Xpost_Object x,
Xpost_Object y)
{
if (addwillover(x.int_.val, y.int_.val))
xpost_stack_push(ctx->lo, ctx->os, xpost_real_cons((real)x.int_.val + y.int_.val));
else
xpost_stack_push(ctx->lo, ctx->os, xpost_int_cons(x.int_.val + y.int_.val));
return 0;
}



Inca 2 currently has this for its addition
function.


#define MATHOP(op) \
I r=AR(w),*d=AD(w),n=AN(w); ARC z; \
switch(AT(a)){ \
case INT: switch(AT(w)){ \
case INT: z=ga(INT,r,d); DO(n,AV(z)[i]=AV(a)[i] op AV(w)[i]); break; \
case DBL: z=ga(DBL,r,d); DO(n,((D*)AV(z))[i]=AV(a)[i] op ((D*)AV(w))[i]); break; \
} break;\
case DBL: switch(AT(w)){ \
case INT: z=ga(INT,r,d); DO(n,AV(z)[i]=((D*)AV(a))[i] op AV(w)[i]); break; \
case DBL: z=ga(DBL,r,d); DO(n,((D*)AV(z))[i]=((D*)AV(a))[i] op ((D*)AV(w))[i]); break; \
} break; \
} \
R z;

#define V2(f) ARC f(ARC a,ARC w)
V2(plus){ MATHOP(+) }


Looking at it now, I think I'll need to jump back to the
beginning of the function and either convert one of the
argument arrays so it falls through to one of the existing
promotion cases, or do it as a completely separate
"error" branch and cast both args to D (double) to
coerce a double result.
0 new messages