Diff for /gforth/engine/dblsub.c between versions 1.5 and 1.11

version 1.5, 2006/10/22 16:54:00 version 1.11, 2007/12/31 20:35:21
Line 1 Line 1
 /* some routines for double-cell arithmetic  /* some routines for double-cell arithmetic
    only used if BUGGY_LONG_LONG     only used if BUGGY_LONG_LONG
   
    Copyright (C) 1996,2000,2003 Free Software Foundation, Inc.     Copyright (C) 1996,2000,2003,2006,2007 Free Software Foundation, Inc.
  * Copyright (C) 1995  Dirk Uwe Zoller   * Copyright (C) 1995  Dirk Uwe Zoller
  *   *
  * This library is free software; you can redistribute it and/or   * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public   * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either   * License as published by the Free Software Foundation; either
  * version 2 of the License, or (at your option) any later version.   * version 3 of the License, or (at your option) any later version.
  *   *
  * This library is distributed in the hope that it will be useful,   * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU Library General Public License for more details.   * See the GNU Lesser General Public License for more details.
  *   *
  * You should have received a copy of the GNU Library General Public   * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free   * License along with this library; if not, write to the Free
  * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.   * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
   
Line 24 Line 24
 #include "config.h"  #include "config.h"
 #include "forth.h"  #include "forth.h"
   
 /* !! a bit machine dependent */  
 #define HALFCELL_BITS   (CELL_BITS/2)  
 #define UH(x)           (((UCell)(x))>>HALFCELL_BITS)  
 #define LH(x)           ((x)&((~(UCell)0)>>HALFCELL_BITS))  
 #define L2U(x)          (((UCell)(x))<<HALFCELL_BITS)  
 #define HIGHBIT(x)      (((UCell)(x))>>(CELL_BITS-1))  
 #define UD2D(ud)        ({UDCell _ud=(ud); (DCell){_ud.hi,_ud.lo};})  
 #define D2UD(d)         ({DCell _d=(d); (UDCell){_d.hi,_d.lo};})  
   
 DCell dnegate(DCell d1)  DCell dnegate(DCell d1)
 {  {
   DCell res;    DCell res;
Line 72  DCell mmul (Cell a, Cell b)  /* signed m Line 63  DCell mmul (Cell a, Cell b)  /* signed m
     res.hi -= a;      res.hi -= a;
   return res;    return res;
 }  }
   
 UDCell umdiv (UDCell u, UCell v)  
 /* Divide unsigned double by single precision using shifts and subtracts.  
    Return quotient in lo, remainder in hi. */  
 {  
   int i = CELL_BITS, c = 0;  
   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)  
         {  
           q++;  
           h -= v;  
         }  
       if (--i < 0)  
         break;  
       c = HIGHBIT (h);  
       h <<= 1;  
       h += HIGHBIT (l);  
       l <<= 1;  
       q <<= 1;  
     }  
   res.hi = h;  
   res.lo = q;  
   return res;  
 }  
   
 DCell smdiv (DCell num, Cell denom)     /* symmetric divide procedure, mixed prec */  
 {  
   DCell res;  
   Cell numsign=num.hi;  
   Cell denomsign=denom;  
   
   if (numsign < 0)  
     num = dnegate (num);  
   if (denomsign < 0)  
     denom = -denom;  
   res = UD2D(umdiv (D2UD(num), denom));  
   if (res.lo >= (UCell)CELL_MIN)  
     throw(BALL_RESULTRANGE);  
   if ((numsign^denomsign)<0) {  
     if (res.lo == CELL_MIN)  
       throw(BALL_RESULTRANGE);  
     res.lo = -res.lo;  
   }  
   if (numsign<0)  
     res.hi = -res.hi;  
   return res;  
 }  
   
 DCell fmdiv (DCell num, Cell denom)     /* floored divide procedure, mixed prec */  
 {  
   /* I have this technique from Andrew Haley */  
   DCell res;  
   Cell denomsign=denom;  
   
   if (denom < 0) {  
     denom = -denom;  
     num = dnegate(num);  
   }  
   if (num.hi < 0)  
     num.hi += denom;  
   res = UD2D(umdiv(D2UD(num),denom));  
   if (res.lo >= (UCell)CELL_MIN)  
     throw(BALL_RESULTRANGE);  
   if (denomsign<0)  
     res.hi = -res.hi;  
   return res;  
 }  

Removed from v.1.5  
changed lines
  Added in v.1.11


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>