KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > lisp > LispFloat


1 /*
2  * LispFloat.java
3  *
4  * Copyright (C) 2003-2004 Peter Graves
5  * $Id: LispFloat.java,v 1.74 2004/09/21 18:12:14 piso Exp $
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
22 package org.armedbear.lisp;
23
24 import java.math.BigInteger JavaDoc;
25
26 public final class LispFloat extends LispObject
27 {
28     public static final LispFloat ZERO = new LispFloat(0);
29     public static final LispFloat ONE = new LispFloat(1);
30     public static final LispFloat MINUS_ONE = new LispFloat(-1);
31
32     public static final LispFloat PI =
33         new LispFloat((double)3.141592653589793);
34
35     public static final LispFloat DOUBLE_FLOAT_POSITIVE_INFINITY =
36         new LispFloat(Double.POSITIVE_INFINITY);
37
38     public static final LispFloat DOUBLE_FLOAT_NEGATIVE_INFINITY =
39         new LispFloat(Double.NEGATIVE_INFINITY);
40
41     static {
42         Symbol.DOUBLE_FLOAT_POSITIVE_INFINITY.setSymbolValue(DOUBLE_FLOAT_POSITIVE_INFINITY);
43         Symbol.DOUBLE_FLOAT_POSITIVE_INFINITY.setConstant(true);
44         Symbol.DOUBLE_FLOAT_NEGATIVE_INFINITY.setSymbolValue(DOUBLE_FLOAT_NEGATIVE_INFINITY);
45         Symbol.DOUBLE_FLOAT_NEGATIVE_INFINITY.setConstant(true);
46     }
47
48     public final double value;
49
50     public LispFloat(double value)
51     {
52         this.value = value;
53     }
54
55     public LispObject typeOf()
56     {
57         return Symbol.FLOAT;
58     }
59
60     public LispClass classOf()
61     {
62         return BuiltInClass.FLOAT;
63     }
64
65     public LispObject typep(LispObject typeSpecifier) throws ConditionThrowable
66     {
67         if (typeSpecifier == Symbol.FLOAT)
68             return T;
69         if (typeSpecifier == BuiltInClass.FLOAT)
70             return T;
71         if (typeSpecifier == Symbol.REAL)
72             return T;
73         if (typeSpecifier == Symbol.NUMBER)
74             return T;
75         if (typeSpecifier == Symbol.SINGLE_FLOAT)
76             return T;
77         if (typeSpecifier == Symbol.DOUBLE_FLOAT)
78             return T;
79         if (typeSpecifier == Symbol.SHORT_FLOAT)
80             return T;
81         if (typeSpecifier == Symbol.LONG_FLOAT)
82             return T;
83         return super.typep(typeSpecifier);
84     }
85
86     public LispObject NUMBERP()
87     {
88         return T;
89     }
90
91     public boolean numberp()
92     {
93         return true;
94     }
95
96     public boolean realp()
97     {
98         return true;
99     }
100
101     public boolean eql(LispObject obj)
102     {
103         if (this == obj)
104             return true;
105         if (obj instanceof LispFloat) {
106             if (value == ((LispFloat)obj).value)
107                 return true;
108         }
109         return false;
110     }
111
112     public boolean equal(LispObject obj)
113     {
114         if (this == obj)
115             return true;
116         if (obj instanceof LispFloat) {
117             if (value == ((LispFloat)obj).value)
118                 return true;
119         }
120         return false;
121     }
122
123     public boolean equalp(LispObject obj) throws ConditionThrowable
124     {
125         if (obj instanceof LispFloat)
126             return value == ((LispFloat)obj).value;
127         if (obj instanceof Fixnum)
128             return value == ((Fixnum)obj).getValue();
129         if (obj instanceof Bignum)
130             return value == ((Bignum)obj).floatValue();
131         if (obj instanceof Ratio)
132             return value == ((Ratio)obj).floatValue();
133         return false;
134     }
135
136     public LispObject ABS()
137     {
138         if (value > 0)
139             return this;
140         if (value == 0) // 0.0 or -0.0
141
return LispFloat.ZERO;
142         return new LispFloat(- value);
143     }
144
145     public boolean plusp()
146     {
147         return value > 0;
148     }
149
150     public boolean minusp()
151     {
152         return value < 0;
153     }
154
155     public boolean zerop()
156     {
157         return value == 0;
158     }
159
160     public LispObject FLOATP()
161     {
162         return T;
163     }
164
165     public boolean floatp()
166     {
167         return true;
168     }
169
170     public static double getValue(LispObject obj) throws ConditionThrowable
171     {
172         try {
173             return ((LispFloat)obj).value;
174         }
175         catch (ClassCastException JavaDoc e) {
176             signal(new TypeError(obj, Symbol.FLOAT));
177             // Not reached.
178
return 0;
179         }
180     }
181
182     public final double getValue()
183     {
184         return value;
185     }
186
187     public Object JavaDoc javaInstance()
188     {
189         return new Double JavaDoc(value);
190     }
191
192     public Object JavaDoc javaInstance(Class JavaDoc c)
193     {
194         String JavaDoc cn = c.getName();
195         if (cn.equals("java.lang.Float") || cn.equals("float"))
196             return new Float JavaDoc(value);
197         return javaInstance();
198     }
199
200     public final LispObject incr()
201     {
202         return new LispFloat(value + 1);
203     }
204
205     public final LispObject decr()
206     {
207         return new LispFloat(value - 1);
208     }
209
210     public LispObject add(LispObject obj) throws ConditionThrowable
211     {
212         if (obj instanceof LispFloat)
213             return new LispFloat(value + ((LispFloat)obj).value);
214         if (obj instanceof Fixnum)
215             return new LispFloat(value + ((Fixnum)obj).value);
216         if (obj instanceof Bignum)
217             return new LispFloat(value + ((Bignum)obj).floatValue());
218         if (obj instanceof Ratio)
219             return new LispFloat(value + ((Ratio)obj).floatValue());
220         if (obj instanceof Complex) {
221             Complex c = (Complex) obj;
222             return Complex.getInstance(add(c.getRealPart()), c.getImaginaryPart());
223         }
224         return signal(new TypeError(obj, Symbol.NUMBER));
225     }
226
227     public LispObject subtract(LispObject obj) throws ConditionThrowable
228     {
229         if (obj instanceof LispFloat)
230             return new LispFloat(value - ((LispFloat)obj).value);
231         if (obj instanceof Fixnum)
232             return new LispFloat(value - ((Fixnum)obj).value);
233         if (obj instanceof Bignum)
234             return new LispFloat(value - ((Bignum)obj).floatValue());
235         if (obj instanceof Ratio)
236             return new LispFloat(value - ((Ratio)obj).floatValue());
237         if (obj instanceof Complex) {
238             Complex c = (Complex) obj;
239             return Complex.getInstance(subtract(c.getRealPart()),
240                                        ZERO.subtract(c.getImaginaryPart()));
241         }
242         return signal(new TypeError(obj, Symbol.NUMBER));
243     }
244
245     public LispObject multiplyBy(LispObject obj) throws ConditionThrowable
246     {
247         if (obj instanceof LispFloat)
248             return new LispFloat(value * ((LispFloat)obj).value);
249         if (obj instanceof Fixnum)
250             return new LispFloat(value * ((Fixnum)obj).value);
251         if (obj instanceof Bignum)
252             return new LispFloat(value * ((Bignum)obj).floatValue());
253         if (obj instanceof Ratio)
254             return new LispFloat(value * ((Ratio)obj).floatValue());
255         if (obj instanceof Complex) {
256             Complex c = (Complex) obj;
257             return Complex.getInstance(multiplyBy(c.getRealPart()),
258                                        multiplyBy(c.getImaginaryPart()));
259         }
260         return signal(new TypeError(obj, Symbol.NUMBER));
261     }
262
263     public LispObject divideBy(LispObject obj) throws ConditionThrowable
264     {
265         if (obj instanceof LispFloat)
266             return new LispFloat(value / ((LispFloat)obj).value);
267         if (obj instanceof Fixnum)
268             return new LispFloat(value / ((Fixnum)obj).value);
269         if (obj instanceof Bignum)
270             return new LispFloat(value / ((Bignum)obj).floatValue());
271         if (obj instanceof Ratio)
272             return new LispFloat(value / ((Ratio)obj).floatValue());
273         if (obj instanceof Complex) {
274             Complex c = (Complex) obj;
275             LispObject re = c.getRealPart();
276             LispObject im = c.getImaginaryPart();
277             LispObject denom = re.multiplyBy(re).add(im.multiplyBy(im));
278             LispObject resX = multiplyBy(re).divideBy(denom);
279             LispObject resY =
280                 multiplyBy(Fixnum.MINUS_ONE).multiplyBy(im).divideBy(denom);
281             return Complex.getInstance(resX, resY);
282         }
283         return signal(new TypeError(obj, Symbol.NUMBER));
284     }
285
286     public boolean isEqualTo(LispObject obj) throws ConditionThrowable
287     {
288         if (obj instanceof LispFloat)
289             return value == ((LispFloat)obj).value;
290         if (obj instanceof Fixnum)
291             return value == ((Fixnum)obj).value;
292         if (obj instanceof Bignum)
293             return rational().isEqualTo(obj);
294         if (obj instanceof Ratio)
295             return rational().isEqualTo(obj);
296         if (obj instanceof Complex)
297             return obj.isEqualTo(this);
298         signal(new TypeError(obj, Symbol.NUMBER));
299         // Not reached.
300
return false;
301     }
302
303     public boolean isNotEqualTo(LispObject obj) throws ConditionThrowable
304     {
305         return !isEqualTo(obj);
306     }
307
308     public boolean isLessThan(LispObject obj) throws ConditionThrowable
309     {
310         if (obj instanceof LispFloat)
311             return value < ((LispFloat)obj).value;
312         if (obj instanceof Fixnum)
313             return value < ((Fixnum)obj).value;
314         if (obj instanceof Bignum)
315             return rational().isLessThan(obj);
316         if (obj instanceof Ratio)
317             return rational().isLessThan(obj);
318         signal(new TypeError(obj, Symbol.REAL));
319         // Not reached.
320
return false;
321     }
322
323     public boolean isGreaterThan(LispObject obj) throws ConditionThrowable
324     {
325         if (obj instanceof LispFloat)
326             return value > ((LispFloat)obj).value;
327         if (obj instanceof Fixnum)
328             return value > ((Fixnum)obj).value;
329         if (obj instanceof Bignum)
330             return rational().isGreaterThan(obj);
331         if (obj instanceof Ratio)
332             return rational().isGreaterThan(obj);
333         signal(new TypeError(obj, Symbol.REAL));
334         // Not reached.
335
return false;
336     }
337
338     public boolean isLessThanOrEqualTo(LispObject obj) throws ConditionThrowable
339     {
340         if (obj instanceof LispFloat)
341             return value <= ((LispFloat)obj).value;
342         if (obj instanceof Fixnum)
343             return value <= ((Fixnum)obj).value;
344         if (obj instanceof Bignum)
345             return rational().isLessThanOrEqualTo(obj);
346         if (obj instanceof Ratio)
347             return rational().isLessThanOrEqualTo(obj);
348         signal(new TypeError(obj, Symbol.REAL));
349         // Not reached.
350
return false;
351     }
352
353     public boolean isGreaterThanOrEqualTo(LispObject obj) throws ConditionThrowable
354     {
355         if (obj instanceof LispFloat)
356             return value >= ((LispFloat)obj).value;
357         if (obj instanceof Fixnum)
358             return value >= ((Fixnum)obj).value;
359         if (obj instanceof Bignum)
360             return rational().isGreaterThanOrEqualTo(obj);
361         if (obj instanceof Ratio)
362             return rational().isGreaterThanOrEqualTo(obj);
363         signal(new TypeError(obj, Symbol.REAL));
364         // Not reached.
365
return false;
366     }
367
368     public LispObject truncate(LispObject obj) throws ConditionThrowable
369     {
370         final LispThread thread = LispThread.currentThread();
371         if (obj instanceof Fixnum) {
372             LispObject rational = rational();
373             LispObject quotient = rational.truncate(obj);
374             thread._values[1] = subtract(quotient); // Remainder.
375
return quotient;
376         }
377         if (obj instanceof LispFloat) {
378             double divisor = ((LispFloat)obj).value;
379             double quotient = value / divisor;
380             if (quotient >= Integer.MIN_VALUE && quotient <= Integer.MAX_VALUE) {
381                 int q = (int) quotient;
382                 return thread.setValues(new Fixnum(q),
383                                         new LispFloat(value - q * divisor));
384             }
385             // We need to convert the quotient to a bignum.
386
long bits = Double.doubleToRawLongBits((double)quotient);
387             int s = ((bits >> 63) == 0) ? 1 : -1;
388             int e = (int) ((bits >> 52) & 0x7ffL);
389             long m;
390             if (e == 0)
391                 m = (bits & 0xfffffffffffffL) << 1;
392             else
393                 m = (bits & 0xfffffffffffffL) | 0x10000000000000L;
394             LispObject significand = number(m);
395             Fixnum exponent = new Fixnum(e - 1075);
396             Fixnum sign = new Fixnum(s);
397             LispObject result = significand;
398             result =
399                 result.multiplyBy(Primitives.EXPT.execute(Fixnum.TWO, exponent));
400             result = result.multiplyBy(sign);
401             // Calculate remainder.
402
LispObject product = result.multiplyBy(obj);
403             LispObject remainder = subtract(product);
404             return thread.setValues(result, remainder);
405         }
406         return signal(new LispError("LispFloat.truncate(): not implemented: " +
407                                     obj.typeOf().writeToString()));
408     }
409
410     public LispObject ftruncate(LispObject obj) throws ConditionThrowable
411     {
412         final LispThread thread = LispThread.currentThread();
413         double divisor, quotient, remainder;
414         if (obj instanceof Fixnum) {
415             divisor = ((Fixnum)obj).value;
416         } else if (obj instanceof LispFloat) {
417             divisor = ((LispFloat)obj).value;
418         } else {
419             return signal(new LispError("LispFloat.ftruncate(): not implemented: " +
420                                         obj.typeOf().writeToString()));
421         }
422         quotient = value / divisor;
423         remainder = value % divisor;
424         if (quotient == 0 ||
425             quotient == Double.POSITIVE_INFINITY ||
426             quotient == Double.NEGATIVE_INFINITY)
427         {
428             return thread.setValues(new LispFloat(quotient),
429                                     new LispFloat(remainder));
430         }
431         if (quotient == remainder) {
432             // "The quotient represents the mathematical integer of the
433
// same sign as the mathematical quotient, and that has the
434
// greatest integral magnitude not greater than that of the
435
// mathematical quotient."
436
return thread.setValues(new LispFloat(quotient < 0 ? -0.0 : 0.0),
437                                     new LispFloat(remainder));
438         }
439         return thread.setValues(new LispFloat(quotient - remainder),
440                                 new LispFloat(remainder));
441     }
442
443     public int hashCode()
444     {
445         long bits = Double.doubleToLongBits(value);
446         return (int) (bits ^ (bits >>> 32));
447     }
448
449     public int psxhash() throws ConditionThrowable
450     {
451         if ((value % 1) == 0)
452             return (((int)value) & 0x7fffffff);
453         else
454             return (hashCode() & 0x7fffffff);
455     }
456
457     public String JavaDoc writeToString() throws ConditionThrowable
458     {
459         if (value == Double.POSITIVE_INFINITY) {
460             StringBuffer JavaDoc sb = new StringBuffer JavaDoc("#.");
461             sb.append(Symbol.DOUBLE_FLOAT_POSITIVE_INFINITY.writeToString());
462             return sb.toString();
463         }
464         if (value == Double.NEGATIVE_INFINITY) {
465             StringBuffer JavaDoc sb = new StringBuffer JavaDoc("#.");
466             sb.append(Symbol.DOUBLE_FLOAT_NEGATIVE_INFINITY.writeToString());
467             return sb.toString();
468         }
469         if (value != value)
470             return "#<DOUBLE-FLOAT NaN>";
471         String JavaDoc s1 = String.valueOf(value);
472         String JavaDoc s2 = s1.replace('E', 'd');
473         if (s1 != s2 || _PRINT_READABLY_.symbolValue() == NIL)
474             return s2;
475         return s2.concat("d0");
476     }
477
478     // ### integer-decode-float
479
// integer-decode-float float => significand, exponent, integer-sign
480
private static final Primitive1 INTEGER_DECODE_FLOAT =
481         new Primitive1("integer-decode-float", "float")
482     {
483         public LispObject execute(LispObject arg) throws ConditionThrowable
484         {
485             if (arg instanceof LispFloat) {
486                 LispObject[] values = new LispObject[3];
487                 long bits =
488                     Double.doubleToRawLongBits((double)((LispFloat)arg).value);
489                 int s = ((bits >> 63) == 0) ? 1 : -1;
490                 int e = (int) ((bits >> 52) & 0x7ffL);
491                 long m;
492                 if (e == 0)
493                     m = (bits & 0xfffffffffffffL) << 1;
494                 else
495                     m = (bits & 0xfffffffffffffL) | 0x10000000000000L;
496                 LispObject significand = number(m);
497                 Fixnum exponent = new Fixnum(e - 1075);
498                 Fixnum sign = new Fixnum(s);
499                 return LispThread.currentThread().setValues(significand,
500                                                             exponent,
501                                                             sign);
502             }
503             return signal(new TypeError(arg, Symbol.FLOAT));
504         }
505     };
506
507     public LispObject rational() throws ConditionThrowable
508     {
509         final long bits = Double.doubleToRawLongBits(value);
510         int sign = ((bits >> 63) == 0) ? 1 : -1;
511         int storedExponent = (int) ((bits >> 52) & 0x7ffL);
512         long mantissa;
513         if (storedExponent == 0)
514             mantissa = (bits & 0xfffffffffffffL) << 1;
515         else
516             mantissa = (bits & 0xfffffffffffffL) | 0x10000000000000L;
517         if (mantissa == 0)
518             return Fixnum.ZERO;
519         if (sign < 0)
520             mantissa = -mantissa;
521         // Subtract bias.
522
final int exponent = storedExponent - 1023;
523         BigInteger JavaDoc numerator, denominator;
524         if (exponent < 0) {
525             numerator = BigInteger.valueOf(mantissa);
526             denominator = BigInteger.valueOf(1).shiftLeft(52 - exponent);
527         } else {
528             numerator = BigInteger.valueOf(mantissa).shiftLeft(exponent);
529             denominator = BigInteger.valueOf(0x10000000000000L); // (ash 1 52)
530
}
531         return number(numerator, denominator);
532     }
533
534     // ### rational
535
private static final Primitive1 RATIONAL =
536         new Primitive1("rational", "number")
537     {
538         public LispObject execute(LispObject arg) throws ConditionThrowable
539         {
540             if (arg instanceof LispFloat)
541                 return ((LispFloat)arg).rational();
542             if (arg.rationalp())
543                 return arg;
544             return signal(new TypeError(arg, Symbol.REAL));
545         }
546     };
547
548     // ### float-radix
549
// float-radix float => float-radix
550
private static final Primitive1 FLOAT_RADIX =
551         new Primitive1("float-radix", "float")
552     {
553         public LispObject execute(LispObject arg) throws ConditionThrowable
554         {
555             if (arg instanceof LispFloat)
556                 return Fixnum.TWO;
557             return signal(new TypeError(arg, Symbol.FLOAT));
558         }
559     };
560
561     private static final Fixnum FIXNUM_53 = new Fixnum(53);
562
563     // ### float-digits
564
// float-digits float => float-digits
565
private static final Primitive1 FLOAT_DIGITS =
566         new Primitive1("float-digits", "float")
567     {
568         public LispObject execute(LispObject arg) throws ConditionThrowable
569         {
570             if (arg instanceof LispFloat)
571                 return FIXNUM_53;
572             return signal(new TypeError(arg, Symbol.FLOAT));
573         }
574     };
575
576     // ### scale-float float integer => scaled-float
577
private static final Primitive2 SCALE_FLOAT =
578         new Primitive2("scale-float", "float integer")
579     {
580         public LispObject execute(LispObject first, LispObject second)
581             throws ConditionThrowable
582         {
583             double f = getValue(first);
584             int n = Fixnum.getValue(second);
585             return new LispFloat(f * Math.pow(2, n));
586         }
587     };
588
589     public static LispFloat coerceToFloat(LispObject obj) throws ConditionThrowable
590     {
591         if (obj instanceof LispFloat)
592             return (LispFloat) obj;
593         if (obj instanceof Fixnum)
594             return new LispFloat(((Fixnum)obj).value);
595         if (obj instanceof Bignum)
596             return new LispFloat(((Bignum)obj).floatValue());
597         if (obj instanceof Ratio)
598             return new LispFloat(((Ratio)obj).floatValue());
599         signal(new TypeError(obj.writeToString() +
600                              " cannot be converted to type FLOAT."));
601         // Not reached.
602
return null;
603     }
604
605     // ### coerce-to-float
606
private static final Primitive1 COERCE_TO_FLOAT =
607         new Primitive1("coerce-to-float", PACKAGE_SYS, false)
608     {
609         public LispObject execute(LispObject arg) throws ConditionThrowable
610         {
611             return coerceToFloat(arg);
612         }
613     };
614
615     // ### float
616
// float number &optional prototype => float
617
private static final Primitive FLOAT =
618         new Primitive("float", "number &optional prototype")
619     {
620         public LispObject execute(LispObject[] args) throws ConditionThrowable
621         {
622             final int length = args.length;
623             if (length < 1 || length > 2)
624                 return signal(new WrongNumberOfArgumentsException(this));
625             // FIXME Ignore prototype (args[1] if present).
626
return coerceToFloat(args[0]);
627         }
628     };
629
630     // ### floatp
631
// floatp object => generalized-boolean
632
private static final Primitive1 FLOATP = new Primitive1("floatp", "object")
633     {
634         public LispObject execute(LispObject arg) throws ConditionThrowable
635         {
636             return arg instanceof LispFloat ? T : NIL;
637         }
638     };
639
640     // ### double-float-high-bits
641
private static final Primitive1 DOUBLE_FLOAT_HIGH_BITS =
642         new Primitive1("double-float-high-bits", PACKAGE_SYS, false, "float")
643     {
644         public LispObject execute(LispObject arg) throws ConditionThrowable
645         {
646             if (arg instanceof LispFloat) {
647                 LispFloat f = (LispFloat) arg;
648                 return number(Double.doubleToLongBits(f.value) >>> 32);
649             }
650             return signal(new TypeError(arg, Symbol.FLOAT));
651         }
652     };
653
654     // ### double-float-low-bits
655
private static final Primitive1 DOUBLE_FLOAT_LOW_BITS =
656         new Primitive1("double-float-low-bits", PACKAGE_SYS, false, "float")
657     {
658         public LispObject execute(LispObject arg) throws ConditionThrowable
659         {
660             if (arg instanceof LispFloat) {
661                 LispFloat f = (LispFloat) arg;
662                 return number(Double.doubleToLongBits(f.value) & 0xffffffffL);
663             }
664             return signal(new TypeError(arg, Symbol.FLOAT));
665         }
666     };
667
668     // ### make-double-float bits => float
669
private static final Primitive MAKE_DOUBLE_FLOAT =
670         new Primitive("make-double-float", PACKAGE_SYS, false, "bits")
671     {
672         public LispObject execute(LispObject arg)
673             throws ConditionThrowable
674         {
675             if (arg instanceof Fixnum) {
676                 long bits = (long) ((Fixnum)arg).value;
677                 return new LispFloat(Double.longBitsToDouble(bits));
678             }
679             if (arg instanceof Bignum) {
680                 long bits = ((Bignum)arg).value.longValue();
681                 return new LispFloat(Double.longBitsToDouble(bits));
682             }
683             return signal(new TypeError());
684         }
685     };
686
687     private static final Primitive1 FLOAT_INFINITY_P =
688         new Primitive1("float-infinity-p", PACKAGE_SYS, false)
689     {
690         public LispObject execute(LispObject arg)
691             throws ConditionThrowable
692         {
693             if (arg instanceof LispFloat)
694                 return Double.isInfinite(((LispFloat)arg).value) ? T : NIL;
695             return signal(new TypeError(arg, Symbol.FLOAT));
696         }
697     };
698
699     private static final Primitive1 FLOAT_NAN_P =
700         new Primitive1("float-nan-p", PACKAGE_SYS, false)
701     {
702         public LispObject execute(LispObject arg)
703             throws ConditionThrowable
704         {
705             if (arg instanceof LispFloat)
706                 return Double.isNaN(((LispFloat)arg).value) ? T : NIL;
707             return signal(new TypeError(arg, Symbol.FLOAT));
708         }
709     };
710 }
711
Popular Tags