EMMA Coverage Report (generated Fri Jul 01 07:36:49 EDT 2005)
[all classes][rossi.dfp]

COVERAGE SUMMARY FOR SOURCE FILE [dfpdec.java]

nameclass, %method, %block, %line, %
dfpdec.java100% (1/1)67%  (6/9)95%  (494/520)94%  (104/111)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class dfpdec100% (1/1)67%  (6/9)95%  (494/520)94%  (104/111)
dfpdec (): void 0%   (0/1)0%   (0/3)0%   (0/2)
newInstance (): dfp 0%   (0/1)0%   (0/4)0%   (0/1)
newInstance (String): dfp 0%   (0/1)0%   (0/5)0%   (0/1)
nextAfter (dfp): dfp 100% (1/1)96%  (152/159)97%  (31/32)
round (int): int 100% (1/1)98%  (319/326)97%  (65/67)
dfpdec (String): void 100% (1/1)100% (8/8)100% (3/3)
dfpdec (dfp): void 100% (1/1)100% (8/8)100% (3/3)
getDecimalDigits (): int 100% (1/1)100% (2/2)100% (1/1)
newInstance (dfp): dfp 100% (1/1)100% (5/5)100% (1/1)

1 
2package rossi.dfp;
3 
4/** Subclass of dfp which hides the radix-10000 artifacts of the superclass.  This
5 *  should give outward apperances of being a decimal number with DIGITS*4-3 decimal 
6 *  digits.   This class can be subclassed to appear to be an arbitrary number of
7 *  decimal digits less than DIGITS*4-3.
8 */
9public class dfpdec extends dfp
10{
11  protected final static int maxdigits = DIGITS*4-3;
12 
13  public dfpdec()
14  {
15    super();
16  }
17 
18  public dfpdec(dfp d)
19  {
20    super(d);
21    round(0);
22  }
23 
24  public dfpdec(String s)
25  {
26    super(s);
27    round(0);
28  }
29 
30  public dfp newInstance()
31  {
32    return new dfpdec();
33  }
34 
35  public dfp newInstance(dfp d)
36  {
37    return new dfpdec(d);
38  }
39 
40  public dfp newInstance(String s)
41  {
42    return new dfpdec(s);
43  }
44 
45  /**
46   *  Return the number of decimal digits this class is going to 
47   *  represent.  Default implementation returns DIGITS*4-3.  Subclasses
48   *  can override this to return something less.
49   */
50  protected int getDecimalDigits()
51  {
52    return DIGITS*4-3;
53  }
54 
55  /** round this given the next digit n using the current rounding mode 
56   *  returns a flag if an exception occured
57   */
58  protected int round(int in)
59  {
60    int r, rh, rl;
61    boolean inc=false;
62    int n;
63    int digits = getDecimalDigits();
64    int lsbshift;
65    int lsbthreshold = 1000;
66    int lsb;
67    int cmaxdigits = DIGITS*4;
68    int msb = mant[DIGITS-1];
69    int lsd = 0;  // position of least sig radix 10k digit
70    int discarded = 0; 
71 
72    if (msb == 0) // special case -- this == zero
73      return 0;
74 
75    while (lsbthreshold > msb)
76    {
77      lsbthreshold /= 10;
78      cmaxdigits --;
79    }
80 
81 
82    lsbshift = cmaxdigits - digits;
83    lsd = lsbshift / 4;
84 
85    lsbthreshold = 1;
86    for (int i=0;i<(lsbshift%4); i++)
87      lsbthreshold *= 10;
88 
89    lsb = mant[lsd];
90 
91    //System.out.println("LSBShift = "+lsbshift);
92    //System.out.println("LSBThreshold = "+lsbthreshold);
93 
94    if (lsbthreshold <= 1 && digits == maxdigits)
95      return super.round(in);
96 
97    discarded |= in;  // not looking at this after this point
98 
99    if (lsbthreshold == 1)  // look to the next digit for rounding
100    {
101      n = (mant[lsd-1] / 1000) % 10;
102      mant[lsd-1] %= 1000;
103      discarded |= mant[lsd-1];
104    }
105    else
106    {
107      n = (lsb * 10 / lsbthreshold) % 10;
108      discarded |= (lsb % (lsbthreshold/10));
109    }
110    //System.out.println("discardedA = "+discarded);
111 
112    for (int i=0; i<lsd; i++)
113    {
114      discarded |= mant[i];    // need to know if thre are any discarded bits
115      mant[i] = 0;
116    }
117 
118    //System.out.println("N = "+n);
119    //System.out.println("discardedB = "+discarded);
120    //System.out.println("oddeven = "+(lsb/lsbthreshold));
121 
122    mant[lsd] = lsb / lsbthreshold * lsbthreshold;
123 
124    switch (rMode)
125    {
126      case ROUND_DOWN:
127        inc = false;
128        break;
129 
130      case ROUND_UP:
131        inc = (n!=0 || discarded != 0);       // round up if n!=0
132        break;
133 
134      case ROUND_HALF_UP:
135        inc = (n >= 5);  // round half up
136        break;
137 
138      case ROUND_HALF_DOWN:
139        inc = (n > 5);  // round half down
140        break;
141 
142      case ROUND_HALF_EVEN:
143        inc = (n > 5 || (n == 5 && discarded != 0) || (n == 5 && discarded == 0 && ((lsb/lsbthreshold)&1)==1));  // round half-even
144        break;
145 
146      case ROUND_HALF_ODD:
147        inc = (n > 5 || (n == 5 && discarded != 0) || (n == 5 && discarded == 0 && ((lsb/lsbthreshold)&1)==0));  // round half-odd
148        break;
149 
150      case ROUND_CEIL:
151        inc = (sign == 1 && (n != 0 || discarded != 0));  // round ceil
152        break;
153 
154      case ROUND_FLOOR:
155        inc = (sign == -1 && (n != 0 || discarded !=0));  // round floor
156        break;
157    }
158 
159    if (inc)  // increment if necessary 
160    {
161      rh = lsbthreshold;
162      for (int i=lsd; i<DIGITS; i++)
163      {
164        r = mant[i] + rh;
165        rh = r / radix;
166        rl = r % radix;
167        mant[i] = rl;
168      }
169 
170      if (rh != 0)
171      {
172        shiftRight();
173        mant[DIGITS-1]=rh;
174      }
175    }
176 
177    /* Check for exceptional cases and raise signals if necessary */
178    if (exp < minExp)  // Gradual Underflow
179    {
180      ieeeFlags |= FLAG_UNDERFLOW;
181      return FLAG_UNDERFLOW;
182    }
183 
184    if (exp > maxExp)  // Overflow
185    {
186      ieeeFlags |= FLAG_OVERFLOW;
187      return FLAG_OVERFLOW;
188    }
189 
190    if (n != 0 || discarded != 0)  // Inexact
191    {
192      ieeeFlags |= FLAG_INEXACT;
193      return FLAG_INEXACT;
194    }
195    return 0;
196  }
197 
198  /** Returns the next number greater than this one in the direction
199   *  of x.  If this==x then simply returns this. */
200 
201  public dfp nextAfter(dfp x)
202  {
203    boolean up = false;
204    dfp result, inc;
205 
206    // if this is greater than x
207    if (this.lessThan(x))
208      up = true;
209 
210    if (compare(this, x) == 0)
211      return newInstance(x);
212 
213    if (lessThan(zero))
214      up = !up;
215 
216    if (up)
217    {
218      inc = power10(log10() - getDecimalDigits() + 1);
219      inc = copysign(inc, this);
220 
221      if (this.equal(zero))
222        inc = power10K(minExp-DIGITS-1);
223 
224      if (inc.equal(zero))
225        result = copysign(newInstance(zero), this);
226      else
227        result = add(inc);
228    }
229    else
230    {
231      inc = power10(log10());
232      inc = copysign(inc, this);
233 
234      if (this.equal(inc))
235        inc = inc.divide(power10(getDecimalDigits()));
236      else
237        inc = inc.divide(power10(getDecimalDigits() - 1));
238 
239      if (this.equal(zero))
240        inc = power10K(minExp-DIGITS-1);
241 
242      if (inc.equal(zero))
243        result = copysign(newInstance(zero), this);
244      else
245        result = subtract(inc);
246    }
247    if (result.classify() == INFINITE && this.classify() != INFINITE)
248    {
249      ieeeFlags |= FLAG_INEXACT;
250      result = dotrap(FLAG_INEXACT, "nextAfter", x, result);
251    }
252  
253    if (result.equal(zero) && this.equal(zero) == false)
254    {
255      ieeeFlags |= FLAG_INEXACT;
256      result = dotrap(FLAG_INEXACT, "nextAfter", x, result);
257    }
258 
259    return result;
260  }
261}

[all classes][rossi.dfp]
EMMA 2.0.5312 (C) Vladimir Roubtsov