--- gforth/engine/dblsub.c 2003/03/09 15:17:02 1.3 +++ gforth/engine/dblsub.c 2006/10/22 20:45:34 1.6 @@ -1,7 +1,7 @@ /* some routines for double-cell arithmetic only used if BUGGY_LONG_LONG - Copyright (C) 1996,2000 Free Software Foundation, Inc. + Copyright (C) 1996,2000,2003 Free Software Foundation, Inc. * Copyright (C) 1995 Dirk Uwe Zoller * * This library is free software; you can redistribute it and/or @@ -81,6 +81,10 @@ UDCell umdiv (UDCell u, UCell v) UCell q = 0, h = u.hi, l = u.lo; UDCell res; + if (v==0) + throw(BALL_DIVZERO); + if (h>=v) + throw(BALL_RESULTRANGE); for (;;) { if (c || h >= v) @@ -112,8 +116,14 @@ DCell smdiv (DCell num, Cell denom) /* s if (denomsign < 0) denom = -denom; res = UD2D(umdiv (D2UD(num), denom)); - if ((numsign^denomsign)<0) + if (res.lo > (UCell)CELL_MIN) + throw(BALL_RESULTRANGE); + if ((numsign^denomsign)<0) { res.lo = -res.lo; + } else { + if (res.lo == CELL_MIN) + throw(BALL_RESULTRANGE); + } if (numsign<0) res.hi = -res.hi; return res; @@ -124,14 +134,23 @@ DCell fmdiv (DCell num, Cell denom) /* f /* I have this technique from Andrew Haley */ DCell res; Cell denomsign=denom; + Cell numsign; if (denom < 0) { denom = -denom; num = dnegate(num); } - if (num.hi < 0) + numsign = num.hi; + if (numsign < 0) num.hi += denom; res = UD2D(umdiv(D2UD(num),denom)); + if (numsign < 0) { + if (res.lo < (UCell)CELL_MIN) + throw(BALL_RESULTRANGE); + } else { + if (res.lo >= (UCell)CELL_MIN) + throw(BALL_RESULTRANGE); + } if (denomsign<0) res.hi = -res.hi; return res;