source: branches/0.15.x/abcl/src/org/armedbear/lisp/Bignum.java

Last change on this file was 11754, checked in by vvoutilainen, 16 years ago

Convert using ClassCastException? to checking instanceof.
Performance tests show this approach to be faster.
Patch by Douglas R. Miles. I modified the patch to
remove tabs, so indentation may be slightly off in places.
That's something that we need to handle separately, abcl
doesn't have a clear indentation policy.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 22.1 KB
Line 
1/*
2 * Bignum.java
3 *
4 * Copyright (C) 2003-2007 Peter Graves
5 * $Id: Bignum.java 11754 2009-04-12 10:53:39Z vvoutilainen $
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 *
21 * As a special exception, the copyright holders of this library give you
22 * permission to link this library with independent modules to produce an
23 * executable, regardless of the license terms of these independent
24 * modules, and to copy and distribute the resulting executable under
25 * terms of your choice, provided that you also meet, for each linked
26 * independent module, the terms and conditions of the license of that
27 * module.  An independent module is a module which is not derived from
28 * or based on this library.  If you modify this library, you may extend
29 * this exception to your version of the library, but you are not
30 * obligated to do so.  If you do not wish to do so, delete this
31 * exception statement from your version.
32 */
33
34package org.armedbear.lisp;
35
36import java.math.BigInteger;
37
38public final class Bignum extends LispInteger
39{
40  public final BigInteger value;
41
42  private static BigInteger MOST_NEGATIVE_FIXNUM =
43          BigInteger.valueOf(Integer.MIN_VALUE);
44  private static BigInteger MOST_POSITIVE_FIXNUM =
45          BigInteger.valueOf(Integer.MAX_VALUE);
46
47  public static LispInteger getInstance(long l) {
48      if (Integer.MIN_VALUE <= l && l <= Integer.MAX_VALUE)
49          return Fixnum.getInstance(l);
50      else
51          return new Bignum(l);
52  }
53
54  public static LispInteger getInstance(BigInteger n) {
55      if (MOST_NEGATIVE_FIXNUM.compareTo(n) < 0 ||
56              MOST_POSITIVE_FIXNUM.compareTo(n) > 0)
57          return new Bignum(n);
58      else
59          return Fixnum.getInstance(n.intValue());
60  }
61
62  public static LispInteger getInstance(String s, int radix) {
63      BigInteger value = new BigInteger(s, radix);
64
65      return Bignum.getInstance(value);
66  }
67
68  private Bignum(long l)
69  {
70    value = BigInteger.valueOf(l);
71  }
72
73  private Bignum(BigInteger n)
74  {
75    value = n;
76  }
77
78  @Override
79  public Object javaInstance()
80  {
81    return value;
82  }
83
84  @Override
85  public Object javaInstance(Class c) {
86    String cn = c.getName();
87    if (cn.equals("java.lang.Byte") || cn.equals("byte"))
88      return Byte.valueOf((byte)value.intValue());
89    if (cn.equals("java.lang.Short") || cn.equals("short"))
90      return Short.valueOf((short)value.intValue());
91    if (cn.equals("java.lang.Integer") || cn.equals("int"))
92      return Integer.valueOf(value.intValue());
93    if (cn.equals("java.lang.Long") || cn.equals("long"))
94      return Long.valueOf((long)value.longValue());
95    return javaInstance();
96  }
97
98
99  @Override
100  public LispObject typeOf()
101  {
102    if (value.signum() > 0)
103      return list(Symbol.INTEGER,
104                   new Bignum((long)Integer.MAX_VALUE + 1));
105    return Symbol.BIGNUM;
106  }
107
108  @Override
109  public LispObject classOf()
110  {
111    return BuiltInClass.BIGNUM;
112  }
113
114  @Override
115  public LispObject typep(LispObject type) throws ConditionThrowable
116  {
117    if (type instanceof Symbol)
118      {
119        if (type == Symbol.BIGNUM)
120          return T;
121        if (type == Symbol.INTEGER)
122          return T;
123        if (type == Symbol.RATIONAL)
124          return T;
125        if (type == Symbol.REAL)
126          return T;
127        if (type == Symbol.NUMBER)
128          return T;
129        if (type == Symbol.SIGNED_BYTE)
130          return T;
131        if (type == Symbol.UNSIGNED_BYTE)
132          return value.signum() >= 0 ? T : NIL;
133      }
134    else if (type instanceof LispClass)
135      {
136        if (type == BuiltInClass.BIGNUM)
137          return T;
138        if (type == BuiltInClass.INTEGER)
139          return T;
140        if (type == BuiltInClass.RATIONAL)
141          return T;
142        if (type == BuiltInClass.REAL)
143          return T;
144        if (type == BuiltInClass.NUMBER)
145          return T;
146      }
147    else if (type instanceof Cons)
148      {
149        if (type.equal(UNSIGNED_BYTE_8))
150          return NIL;
151        if (type.equal(UNSIGNED_BYTE_32))
152          {
153            if (minusp())
154              return NIL;
155            return isLessThan(UNSIGNED_BYTE_32_MAX_VALUE) ? T : NIL;
156          }
157      }
158    return super.typep(type);
159  }
160
161  @Override
162  public LispObject NUMBERP()
163  {
164    return T;
165  }
166
167  @Override
168  public boolean numberp()
169  {
170    return true;
171  }
172
173  @Override
174  public LispObject INTEGERP()
175  {
176    return T;
177  }
178
179  @Override
180  public boolean integerp()
181  {
182    return true;
183  }
184
185  @Override
186  public boolean rationalp()
187  {
188    return true;
189  }
190
191  @Override
192  public boolean realp()
193  {
194    return true;
195  }
196
197  @Override
198  public boolean eql(LispObject obj)
199  {
200    if (this == obj)
201      return true;
202    if (obj instanceof Bignum)
203      {
204        if (value.equals(((Bignum)obj).value))
205          return true;
206      }
207    return false;
208  }
209
210  @Override
211  public boolean equal(LispObject obj)
212  {
213    if (this == obj)
214      return true;
215    if (obj instanceof Bignum)
216      {
217        if (value.equals(((Bignum)obj).value))
218          return true;
219      }
220    return false;
221  }
222
223  @Override
224  public boolean equalp(LispObject obj) throws ConditionThrowable
225  {
226    if (obj instanceof Bignum)
227      return value.equals(((Bignum)obj).value);
228    if (obj instanceof SingleFloat)
229      return floatValue() == ((SingleFloat)obj).value;
230    if (obj instanceof DoubleFloat)
231      return doubleValue() == ((DoubleFloat)obj).value;
232    return false;
233  }
234
235  @Override
236  public LispObject ABS()
237  {
238    if (value.signum() >= 0)
239      return this;
240    return new Bignum(value.negate());
241  }
242
243  @Override
244  public LispObject NUMERATOR()
245  {
246    return this;
247  }
248
249  @Override
250  public LispObject DENOMINATOR()
251  {
252    return Fixnum.ONE;
253  }
254
255  @Override
256  public boolean evenp() throws ConditionThrowable
257  {
258    return !value.testBit(0);
259  }
260
261  @Override
262  public boolean oddp() throws ConditionThrowable
263  {
264    return value.testBit(0);
265  }
266
267  @Override
268  public boolean plusp()
269  {
270    return value.signum() > 0;
271  }
272
273  @Override
274  public boolean minusp()
275  {
276    return value.signum() < 0;
277  }
278
279  @Override
280  public boolean zerop()
281  {
282    return false;
283  }
284
285  @Override
286  public int intValue()
287  {
288    return value.intValue();
289  }
290
291  @Override
292  public long longValue()
293  {
294    return value.longValue();
295  }
296
297  @Override
298  public float floatValue() throws ConditionThrowable
299  {
300    float f = value.floatValue();
301    if (Float.isInfinite(f))
302      error(new TypeError("The value " + writeToString() +
303                           " is too large to be converted to a single float."));
304    return f;
305  }
306
307  @Override
308  public double doubleValue() throws ConditionThrowable
309  {
310    double d = value.doubleValue();
311    if (Double.isInfinite(d))
312      error(new TypeError("The value " + writeToString() +
313                           " is too large to be converted to a double float."));
314    return d;
315  }
316
317  public static BigInteger getValue(LispObject obj) throws ConditionThrowable
318  {
319         
320    if (obj instanceof Bignum)
321      {
322        return ((Bignum)obj).value;
323      }
324        type_error(obj, Symbol.BIGNUM);
325        // Not reached.
326        return null;
327  }
328
329  @Override
330  public final LispObject incr()
331  {
332    return number(value.add(BigInteger.ONE));
333  }
334
335  @Override
336  public final LispObject decr()
337  {
338    return number(value.subtract(BigInteger.ONE));
339  }
340
341  @Override
342  public LispObject add(int n) throws ConditionThrowable
343  {
344    return number(value.add(BigInteger.valueOf(n)));
345  }
346
347  @Override
348  public LispObject add(LispObject obj) throws ConditionThrowable
349  {
350    if (obj instanceof Fixnum)
351      return number(value.add(Fixnum.getBigInteger(obj)));
352    if (obj instanceof Bignum)
353      return number(value.add(((Bignum)obj).value));
354    if (obj instanceof Ratio)
355      {
356        BigInteger numerator = ((Ratio)obj).numerator();
357        BigInteger denominator = ((Ratio)obj).denominator();
358        return number(value.multiply(denominator).add(numerator),
359                      denominator);
360      }
361    if (obj instanceof SingleFloat)
362      return new SingleFloat(floatValue() + ((SingleFloat)obj).value);
363    if (obj instanceof DoubleFloat)
364      return new DoubleFloat(doubleValue() + ((DoubleFloat)obj).value);
365    if (obj instanceof Complex)
366      {
367        Complex c = (Complex) obj;
368        return Complex.getInstance(add(c.getRealPart()), c.getImaginaryPart());
369      }
370    return type_error(obj, Symbol.NUMBER);
371  }
372
373  @Override
374  public LispObject subtract(LispObject obj) throws ConditionThrowable
375  {
376    if (obj instanceof Fixnum)
377      return number(value.subtract(Fixnum.getBigInteger(obj)));
378    if (obj instanceof Bignum)
379      return number(value.subtract(((Bignum)obj).value));
380    if (obj instanceof Ratio)
381      {
382        BigInteger numerator = ((Ratio)obj).numerator();
383        BigInteger denominator = ((Ratio)obj).denominator();
384        return number(value.multiply(denominator).subtract(numerator),
385                      denominator);
386      }
387    if (obj instanceof SingleFloat)
388      return new SingleFloat(floatValue() - ((SingleFloat)obj).value);
389    if (obj instanceof DoubleFloat)
390      return new DoubleFloat(doubleValue() - ((DoubleFloat)obj).value);
391    if (obj instanceof Complex)
392      {
393        Complex c = (Complex) obj;
394        return Complex.getInstance(subtract(c.getRealPart()),
395                                   Fixnum.ZERO.subtract(c.getImaginaryPart()));
396      }
397    return type_error(obj, Symbol.NUMBER);
398  }
399
400  @Override
401  public LispObject multiplyBy(int n) throws ConditionThrowable
402  {
403    if (n == 0)
404      return Fixnum.ZERO;
405    if (n == 1)
406      return this;
407    return new Bignum(value.multiply(BigInteger.valueOf(n)));
408  }
409
410  @Override
411  public LispObject multiplyBy(LispObject obj) throws ConditionThrowable
412  {
413    if (obj instanceof Fixnum)
414      {
415        int n = ((Fixnum)obj).value;
416        if (n == 0)
417          return Fixnum.ZERO;
418        if (n == 1)
419          return this;
420        return new Bignum(value.multiply(BigInteger.valueOf(n)));
421      }
422    if (obj instanceof Bignum)
423      return new Bignum(value.multiply(((Bignum)obj).value));
424    if (obj instanceof Ratio)
425      {
426        BigInteger n = ((Ratio)obj).numerator();
427        return number(n.multiply(value), ((Ratio)obj).denominator());
428      }
429    if (obj instanceof SingleFloat)
430      return new SingleFloat(floatValue() * ((SingleFloat)obj).value);
431    if (obj instanceof DoubleFloat)
432      return new DoubleFloat(doubleValue() * ((DoubleFloat)obj).value);
433    if (obj instanceof Complex)
434      {
435        Complex c = (Complex) obj;
436        return Complex.getInstance(multiplyBy(c.getRealPart()),
437                                   multiplyBy(c.getImaginaryPart()));
438      }
439    return type_error(obj, Symbol.NUMBER);
440  }
441
442  @Override
443  public LispObject divideBy(LispObject obj) throws ConditionThrowable
444  {
445    if (obj instanceof Fixnum)
446      return number(value, Fixnum.getBigInteger(obj));
447    if (obj instanceof Bignum)
448      return number(value, ((Bignum)obj).value);
449    if (obj instanceof Ratio)
450      {
451        BigInteger d = ((Ratio)obj).denominator();
452        return number(d.multiply(value), ((Ratio)obj).numerator());
453      }
454    if (obj instanceof SingleFloat)
455      return new SingleFloat(floatValue() / ((SingleFloat)obj).value);
456    if (obj instanceof DoubleFloat)
457      return new DoubleFloat(doubleValue() / ((DoubleFloat)obj).value);
458    if (obj instanceof Complex)
459      {
460        Complex c = (Complex) obj;
461        LispObject realPart = c.getRealPart();
462        LispObject imagPart = c.getImaginaryPart();
463        LispObject denominator =
464          realPart.multiplyBy(realPart).add(imagPart.multiplyBy(imagPart));
465        return Complex.getInstance(multiplyBy(realPart).divideBy(denominator),
466                                   Fixnum.ZERO.subtract(multiplyBy(imagPart).divideBy(denominator)));
467      }
468    return type_error(obj, Symbol.NUMBER);
469  }
470
471  @Override
472  public boolean isEqualTo(LispObject obj) throws ConditionThrowable
473  {
474    if (obj instanceof Bignum)
475      return value.equals(((Bignum)obj).value);
476    if (obj instanceof SingleFloat)
477      return isEqualTo(((SingleFloat)obj).rational());
478    if (obj instanceof DoubleFloat)
479      return isEqualTo(((DoubleFloat)obj).rational());
480    if (obj.numberp())
481      return false;
482    type_error(obj, Symbol.NUMBER);
483    // Not reached.
484    return false;
485  }
486
487  @Override
488  public boolean isNotEqualTo(LispObject obj) throws ConditionThrowable
489  {
490    if (obj instanceof Bignum)
491      return !value.equals(((Bignum)obj).value);
492    if (obj instanceof SingleFloat)
493      return isNotEqualTo(((SingleFloat)obj).rational());
494    if (obj instanceof DoubleFloat)
495      return isNotEqualTo(((DoubleFloat)obj).rational());
496    if (obj.numberp())
497      return true;
498    type_error(obj, Symbol.NUMBER);
499    // Not reached.
500    return false;
501  }
502
503  @Override
504  public boolean isLessThan(LispObject obj) throws ConditionThrowable
505  {
506    if (obj instanceof Fixnum)
507      return value.compareTo(Fixnum.getBigInteger(obj)) < 0;
508    if (obj instanceof Bignum)
509      return value.compareTo(((Bignum)obj).value) < 0;
510    if (obj instanceof Ratio)
511      {
512        BigInteger n = value.multiply(((Ratio)obj).denominator());
513        return n.compareTo(((Ratio)obj).numerator()) < 0;
514      }
515    if (obj instanceof SingleFloat)
516      return isLessThan(((SingleFloat)obj).rational());
517    if (obj instanceof DoubleFloat)
518      return isLessThan(((DoubleFloat)obj).rational());
519    type_error(obj, Symbol.REAL);
520    // Not reached.
521    return false;
522  }
523
524  @Override
525  public boolean isGreaterThan(LispObject obj) throws ConditionThrowable
526  {
527    if (obj instanceof Fixnum)
528      return value.compareTo(Fixnum.getBigInteger(obj)) > 0;
529    if (obj instanceof Bignum)
530      return value.compareTo(((Bignum)obj).value) > 0;
531    if (obj instanceof Ratio)
532      {
533        BigInteger n = value.multiply(((Ratio)obj).denominator());
534        return n.compareTo(((Ratio)obj).numerator()) > 0;
535      }
536    if (obj instanceof SingleFloat)
537      return isGreaterThan(((SingleFloat)obj).rational());
538    if (obj instanceof DoubleFloat)
539      return isGreaterThan(((DoubleFloat)obj).rational());
540    type_error(obj, Symbol.REAL);
541    // Not reached.
542    return false;
543  }
544
545  @Override
546  public boolean isLessThanOrEqualTo(LispObject obj) throws ConditionThrowable
547  {
548    if (obj instanceof Fixnum)
549      return value.compareTo(Fixnum.getBigInteger(obj)) <= 0;
550    if (obj instanceof Bignum)
551      return value.compareTo(((Bignum)obj).value) <= 0;
552    if (obj instanceof Ratio)
553      {
554        BigInteger n = value.multiply(((Ratio)obj).denominator());
555        return n.compareTo(((Ratio)obj).numerator()) <= 0;
556      }
557    if (obj instanceof SingleFloat)
558      return isLessThanOrEqualTo(((SingleFloat)obj).rational());
559    if (obj instanceof DoubleFloat)
560      return isLessThanOrEqualTo(((DoubleFloat)obj).rational());
561    type_error(obj, Symbol.REAL);
562    // Not reached.
563    return false;
564  }
565
566  @Override
567  public boolean isGreaterThanOrEqualTo(LispObject obj) throws ConditionThrowable
568  {
569    if (obj instanceof Fixnum)
570      return value.compareTo(Fixnum.getBigInteger(obj)) >= 0;
571    if (obj instanceof Bignum)
572      return value.compareTo(((Bignum)obj).value) >= 0;
573    if (obj instanceof Ratio)
574      {
575        BigInteger n = value.multiply(((Ratio)obj).denominator());
576        return n.compareTo(((Ratio)obj).numerator()) >= 0;
577      }
578    if (obj instanceof SingleFloat)
579      return isGreaterThanOrEqualTo(((SingleFloat)obj).rational());
580    if (obj instanceof DoubleFloat)
581      return isGreaterThanOrEqualTo(((DoubleFloat)obj).rational());
582    type_error(obj, Symbol.REAL);
583    // Not reached.
584    return false;
585  }
586
587  @Override
588  public LispObject truncate(LispObject obj) throws ConditionThrowable
589  {
590    final LispThread thread = LispThread.currentThread();
591    LispObject value1, value2;
592    try
593      {
594        if (obj instanceof Fixnum)
595          {
596            BigInteger divisor = ((Fixnum)obj).getBigInteger();
597            BigInteger[] results = value.divideAndRemainder(divisor);
598            BigInteger quotient = results[0];
599            BigInteger remainder = results[1];
600            value1 = number(quotient);
601            value2 = (remainder.signum() == 0) ? Fixnum.ZERO : number(remainder);
602          }
603        else if (obj instanceof Bignum)
604          {
605            BigInteger divisor = ((Bignum)obj).value;
606            BigInteger[] results = value.divideAndRemainder(divisor);
607            BigInteger quotient = results[0];
608            BigInteger remainder = results[1];
609            value1 = number(quotient);
610            value2 = (remainder.signum() == 0) ? Fixnum.ZERO : number(remainder);
611          }
612        else if (obj instanceof Ratio)
613          {
614            Ratio divisor = (Ratio) obj;
615            LispObject quotient =
616              multiplyBy(divisor.DENOMINATOR()).truncate(divisor.NUMERATOR());
617            LispObject remainder =
618              subtract(quotient.multiplyBy(divisor));
619            value1 = quotient;
620            value2 = remainder;
621          }
622        else if (obj instanceof SingleFloat)
623          {
624            // "When rationals and floats are combined by a numerical
625            // function, the rational is first converted to a float of the
626            // same format." 12.1.4.1
627            return new SingleFloat(floatValue()).truncate(obj);
628          }
629        else if (obj instanceof DoubleFloat)
630          {
631            // "When rationals and floats are combined by a numerical
632            // function, the rational is first converted to a float of the
633            // same format." 12.1.4.1
634            return new DoubleFloat(doubleValue()).truncate(obj);
635          }
636        else
637          return type_error(obj, Symbol.REAL);
638      }
639    catch (ArithmeticException e)
640      {
641        if (obj.zerop())
642          return error(new DivisionByZero());
643        else
644          return error(new ArithmeticError(e.getMessage()));
645      }
646    return thread.setValues(value1, value2);
647  }
648
649  @Override
650  public LispObject ash(LispObject obj) throws ConditionThrowable
651  {
652    BigInteger n = value;
653    if (obj instanceof Fixnum)
654      {
655        int count = ((Fixnum)obj).value;
656        if (count == 0)
657          return this;
658        // BigInteger.shiftLeft() succumbs to a stack overflow if count
659        // is Integer.MIN_VALUE, so...
660        if (count == Integer.MIN_VALUE)
661          return n.signum() >= 0 ? Fixnum.ZERO : Fixnum.MINUS_ONE;
662        return number(n.shiftLeft(count));
663      }
664    if (obj instanceof Bignum)
665      {
666        BigInteger count = ((Bignum)obj).value;
667        if (count.signum() > 0)
668          return error(new LispError("Can't represent result of left shift."));
669        if (count.signum() < 0)
670          return n.signum() >= 0 ? Fixnum.ZERO : Fixnum.MINUS_ONE;
671        Debug.bug(); // Shouldn't happen.
672      }
673    return type_error(obj, Symbol.INTEGER);
674  }
675
676  @Override
677  public LispObject LOGNOT()
678  {
679    return number(value.not());
680  }
681
682  @Override
683  public LispObject LOGAND(int n) throws ConditionThrowable
684  {
685    if (n >= 0)
686      return Fixnum.getInstance(value.intValue() & n);
687    else
688      return number(value.and(BigInteger.valueOf(n)));
689  }
690
691  @Override
692  public LispObject LOGAND(LispObject obj) throws ConditionThrowable
693  {
694    if (obj instanceof Fixnum)
695      {
696        int n = ((Fixnum)obj).value;
697        if (n >= 0)
698          return Fixnum.getInstance(value.intValue() & n);
699        else
700          return number(value.and(BigInteger.valueOf(n)));
701      }
702    else if (obj instanceof Bignum)
703      {
704        final BigInteger n = ((Bignum)obj).value;
705        return number(value.and(n));
706      }
707    else
708      return type_error(obj, Symbol.INTEGER);
709  }
710
711  @Override
712  public LispObject LOGIOR(int n) throws ConditionThrowable
713  {
714    return number(value.or(BigInteger.valueOf(n)));
715  }
716
717  @Override
718  public LispObject LOGIOR(LispObject obj) throws ConditionThrowable
719  {
720    if (obj instanceof Fixnum)
721      {
722        final BigInteger n = ((Fixnum)obj).getBigInteger();
723        return number(value.or(n));
724      }
725    else if (obj instanceof Bignum)
726      {
727        final BigInteger n = ((Bignum)obj).value;
728        return number(value.or(n));
729      }
730    else
731      return type_error(obj, Symbol.INTEGER);
732  }
733
734  @Override
735  public LispObject LOGXOR(int n) throws ConditionThrowable
736  {
737    return number(value.xor(BigInteger.valueOf(n)));
738  }
739
740  @Override
741  public LispObject LOGXOR(LispObject obj) throws ConditionThrowable
742  {
743    final BigInteger n;
744    if (obj instanceof Fixnum)
745      n = ((Fixnum)obj).getBigInteger();
746    else if (obj instanceof Bignum)
747      n = ((Bignum)obj).value;
748    else
749      return type_error(obj, Symbol.INTEGER);
750    return number(value.xor(n));
751  }
752
753  @Override
754  public LispObject LDB(int size, int position)
755  {
756    BigInteger n = value.shiftRight(position);
757    BigInteger mask = BigInteger.ONE.shiftLeft(size).subtract(BigInteger.ONE);
758    return number(n.and(mask));
759  }
760
761  @Override
762  public int hashCode()
763  {
764    return value.hashCode();
765  }
766
767  @Override
768  public String writeToString() throws ConditionThrowable
769  {
770    final LispThread thread = LispThread.currentThread();
771    final int base = Fixnum.getValue(Symbol.PRINT_BASE.symbolValue(thread));
772    String s = value.toString(base).toUpperCase();
773    if (Symbol.PRINT_RADIX.symbolValue(thread) != NIL)
774      {
775        StringBuffer sb = new StringBuffer();
776        switch (base)
777          {
778          case 2:
779            sb.append("#b");
780            sb.append(s);
781            break;
782          case 8:
783            sb.append("#o");
784            sb.append(s);
785            break;
786          case 10:
787            sb.append(s);
788            sb.append('.');
789            break;
790          case 16:
791            sb.append("#x");
792            sb.append(s);
793            break;
794          default:
795            sb.append('#');
796            sb.append(String.valueOf(base));
797            sb.append('r');
798            sb.append(s);
799            break;
800          }
801        s = sb.toString();
802      }
803    return s;
804  }
805}
Note: See TracBrowser for help on using the repository browser.