15dfecf96Smrg/* 25dfecf96Smrg * Copyright (c) 2001 by The XFree86 Project, Inc. 35dfecf96Smrg * 45dfecf96Smrg * Permission is hereby granted, free of charge, to any person obtaining a 55dfecf96Smrg * copy of this software and associated documentation files (the "Software"), 65dfecf96Smrg * to deal in the Software without restriction, including without limitation 75dfecf96Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 85dfecf96Smrg * and/or sell copies of the Software, and to permit persons to whom the 95dfecf96Smrg * Software is furnished to do so, subject to the following conditions: 105dfecf96Smrg * 115dfecf96Smrg * The above copyright notice and this permission notice shall be included in 125dfecf96Smrg * all copies or substantial portions of the Software. 135dfecf96Smrg * 145dfecf96Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 155dfecf96Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 165dfecf96Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 175dfecf96Smrg * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 185dfecf96Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 195dfecf96Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 205dfecf96Smrg * SOFTWARE. 215dfecf96Smrg * 225dfecf96Smrg * Except as contained in this notice, the name of the XFree86 Project shall 235dfecf96Smrg * not be used in advertising or otherwise to promote the sale, use or other 245dfecf96Smrg * dealings in this Software without prior written authorization from the 255dfecf96Smrg * XFree86 Project. 265dfecf96Smrg * 275dfecf96Smrg * Author: Paulo César Pereira de Andrade 285dfecf96Smrg */ 295dfecf96Smrg 305dfecf96Smrg/* $XFree86: xc/programs/xedit/lisp/math.c,v 1.23tsi Exp $ */ 315dfecf96Smrg 325dfecf96Smrg#include "lisp/math.h" 335dfecf96Smrg#include "lisp/private.h" 345dfecf96Smrg 35c2cbb186Smrg#ifdef __APPLE__ 365dfecf96Smrg# define finite(x) isfinite(x) 375dfecf96Smrg#endif 385dfecf96Smrg 395dfecf96Smrg/* 405dfecf96Smrg * Prototypes 415dfecf96Smrg */ 425dfecf96Smrgstatic LispObj *LispDivide(LispBuiltin*, int, int); 435dfecf96Smrg 445dfecf96Smrg/* 455dfecf96Smrg * Initialization 465dfecf96Smrg */ 475dfecf96Smrgstatic LispObj *obj_zero, *obj_one; 485dfecf96SmrgLispObj *Ocomplex, *Oequal_; 495dfecf96Smrg 505dfecf96SmrgLispObj *Oshort_float, *Osingle_float, *Odouble_float, *Olong_float; 515dfecf96Smrg 525dfecf96SmrgAtom_id Sdefault_float_format; 535dfecf96Smrg 545dfecf96Smrg/* 555dfecf96Smrg * Implementation 565dfecf96Smrg */ 575dfecf96Smrg#include "lisp/mathimp.c" 585dfecf96Smrg 595dfecf96Smrgvoid 605dfecf96SmrgLispMathInit(void) 615dfecf96Smrg{ 625dfecf96Smrg LispObj *object, *result; 635dfecf96Smrg 645dfecf96Smrg mp_set_malloc(LispMalloc); 655dfecf96Smrg mp_set_calloc(LispCalloc); 665dfecf96Smrg mp_set_realloc(LispRealloc); 675dfecf96Smrg mp_set_free(LispFree); 685dfecf96Smrg 695dfecf96Smrg number_init(); 705dfecf96Smrg obj_zero = FIXNUM(0); 715dfecf96Smrg obj_one = FIXNUM(1); 725dfecf96Smrg 735dfecf96Smrg Oequal_ = STATIC_ATOM("="); 74f14f4646Smrg Ocomplex = STATIC_ATOM(Scomplex->value); 755dfecf96Smrg Oshort_float = STATIC_ATOM("SHORT-FLOAT"); 765dfecf96Smrg LispExportSymbol(Oshort_float); 775dfecf96Smrg Osingle_float = STATIC_ATOM("SINGLE-FLOAT"); 785dfecf96Smrg LispExportSymbol(Osingle_float); 795dfecf96Smrg Odouble_float = STATIC_ATOM("DOUBLE-FLOAT"); 805dfecf96Smrg LispExportSymbol(Odouble_float); 815dfecf96Smrg Olong_float = STATIC_ATOM("LONG-FLOAT"); 825dfecf96Smrg LispExportSymbol(Olong_float); 835dfecf96Smrg 845dfecf96Smrg object = STATIC_ATOM("*DEFAULT-FLOAT-FORMAT*"); 855dfecf96Smrg LispProclaimSpecial(object, Odouble_float, NIL); 865dfecf96Smrg LispExportSymbol(object); 875dfecf96Smrg Sdefault_float_format = ATOMID(object); 885dfecf96Smrg 895dfecf96Smrg object = STATIC_ATOM("PI"); 905dfecf96Smrg result = number_pi(); 915dfecf96Smrg LispProclaimSpecial(object, result, NIL); 925dfecf96Smrg LispExportSymbol(object); 935dfecf96Smrg 945dfecf96Smrg object = STATIC_ATOM("MOST-POSITIVE-FIXNUM"); 955dfecf96Smrg LispDefconstant(object, FIXNUM(MOST_POSITIVE_FIXNUM), NIL); 965dfecf96Smrg LispExportSymbol(object); 975dfecf96Smrg 985dfecf96Smrg object = STATIC_ATOM("MOST-NEGATIVE-FIXNUM"); 995dfecf96Smrg LispDefconstant(object, FIXNUM(MOST_NEGATIVE_FIXNUM), NIL); 1005dfecf96Smrg LispExportSymbol(object); 1015dfecf96Smrg} 1025dfecf96Smrg 1035dfecf96SmrgLispObj * 1045dfecf96SmrgLisp_Mul(LispBuiltin *builtin) 1055dfecf96Smrg/* 1065dfecf96Smrg * &rest numbers 1075dfecf96Smrg */ 1085dfecf96Smrg{ 1095dfecf96Smrg n_number num; 1105dfecf96Smrg LispObj *number, *numbers; 1115dfecf96Smrg 1125dfecf96Smrg numbers = ARGUMENT(0); 1135dfecf96Smrg 1145dfecf96Smrg if (CONSP(numbers)) { 1155dfecf96Smrg number = CAR(numbers); 1165dfecf96Smrg 1175dfecf96Smrg numbers = CDR(numbers); 1185dfecf96Smrg if (!CONSP(numbers)) { 1195dfecf96Smrg CHECK_NUMBER(number); 1205dfecf96Smrg return (number); 1215dfecf96Smrg } 1225dfecf96Smrg } 1235dfecf96Smrg else 1245dfecf96Smrg return (FIXNUM(1)); 1255dfecf96Smrg 1265dfecf96Smrg set_number_object(&num, number); 1275dfecf96Smrg do { 1285dfecf96Smrg mul_number_object(&num, CAR(numbers)); 1295dfecf96Smrg numbers = CDR(numbers); 1305dfecf96Smrg } while (CONSP(numbers)); 1315dfecf96Smrg 1325dfecf96Smrg return (make_number_object(&num)); 1335dfecf96Smrg} 1345dfecf96Smrg 1355dfecf96SmrgLispObj * 1365dfecf96SmrgLisp_Plus(LispBuiltin *builtin) 1375dfecf96Smrg/* 1385dfecf96Smrg + &rest numbers 1395dfecf96Smrg */ 1405dfecf96Smrg{ 1415dfecf96Smrg n_number num; 1425dfecf96Smrg LispObj *number, *numbers; 1435dfecf96Smrg 1445dfecf96Smrg numbers = ARGUMENT(0); 1455dfecf96Smrg 1465dfecf96Smrg if (CONSP(numbers)) { 1475dfecf96Smrg number = CAR(numbers); 1485dfecf96Smrg 1495dfecf96Smrg numbers = CDR(numbers); 1505dfecf96Smrg if (!CONSP(numbers)) { 1515dfecf96Smrg CHECK_NUMBER(number); 1525dfecf96Smrg return (number); 1535dfecf96Smrg } 1545dfecf96Smrg } 1555dfecf96Smrg else 1565dfecf96Smrg return (FIXNUM(0)); 1575dfecf96Smrg 1585dfecf96Smrg set_number_object(&num, number); 1595dfecf96Smrg do { 1605dfecf96Smrg add_number_object(&num, CAR(numbers)); 1615dfecf96Smrg numbers = CDR(numbers); 1625dfecf96Smrg } while (CONSP(numbers)); 1635dfecf96Smrg 1645dfecf96Smrg return (make_number_object(&num)); 1655dfecf96Smrg} 1665dfecf96Smrg 1675dfecf96SmrgLispObj * 1685dfecf96SmrgLisp_Minus(LispBuiltin *builtin) 1695dfecf96Smrg/* 1705dfecf96Smrg - number &rest more_numbers 1715dfecf96Smrg */ 1725dfecf96Smrg{ 1735dfecf96Smrg n_number num; 1745dfecf96Smrg LispObj *number, *more_numbers; 1755dfecf96Smrg 1765dfecf96Smrg more_numbers = ARGUMENT(1); 1775dfecf96Smrg number = ARGUMENT(0); 1785dfecf96Smrg 1795dfecf96Smrg set_number_object(&num, number); 1805dfecf96Smrg if (!CONSP(more_numbers)) { 1815dfecf96Smrg neg_number(&num); 1825dfecf96Smrg 1835dfecf96Smrg return (make_number_object(&num)); 1845dfecf96Smrg } 1855dfecf96Smrg do { 1865dfecf96Smrg sub_number_object(&num, CAR(more_numbers)); 1875dfecf96Smrg more_numbers = CDR(more_numbers); 1885dfecf96Smrg } while (CONSP(more_numbers)); 1895dfecf96Smrg 1905dfecf96Smrg return (make_number_object(&num)); 1915dfecf96Smrg} 1925dfecf96Smrg 1935dfecf96SmrgLispObj * 1945dfecf96SmrgLisp_Div(LispBuiltin *builtin) 1955dfecf96Smrg/* 1965dfecf96Smrg / number &rest more_numbers 1975dfecf96Smrg */ 1985dfecf96Smrg{ 1995dfecf96Smrg n_number num; 2005dfecf96Smrg LispObj *number, *more_numbers; 2015dfecf96Smrg 2025dfecf96Smrg more_numbers = ARGUMENT(1); 2035dfecf96Smrg number = ARGUMENT(0); 2045dfecf96Smrg 2055dfecf96Smrg if (CONSP(more_numbers)) 2065dfecf96Smrg set_number_object(&num, number); 2075dfecf96Smrg else { 2085dfecf96Smrg num.complex = 0; 2095dfecf96Smrg num.real.type = N_FIXNUM; 2105dfecf96Smrg num.real.data.fixnum = 1; 2115dfecf96Smrg goto div_one_argument; 2125dfecf96Smrg } 2135dfecf96Smrg 2145dfecf96Smrg for (;;) { 2155dfecf96Smrg number = CAR(more_numbers); 2165dfecf96Smrg more_numbers = CDR(more_numbers); 2175dfecf96Smrg 2185dfecf96Smrgdiv_one_argument: 2195dfecf96Smrg div_number_object(&num, number); 2205dfecf96Smrg if (!CONSP(more_numbers)) 2215dfecf96Smrg break; 2225dfecf96Smrg } 2235dfecf96Smrg 2245dfecf96Smrg return (make_number_object(&num)); 2255dfecf96Smrg} 2265dfecf96Smrg 2275dfecf96SmrgLispObj * 2285dfecf96SmrgLisp_OnePlus(LispBuiltin *builtin) 2295dfecf96Smrg/* 2305dfecf96Smrg 1+ number 2315dfecf96Smrg */ 2325dfecf96Smrg{ 2335dfecf96Smrg n_number num; 2345dfecf96Smrg LispObj *number; 2355dfecf96Smrg 2365dfecf96Smrg number = ARGUMENT(0); 2375dfecf96Smrg num.complex = 0; 2385dfecf96Smrg num.real.type = N_FIXNUM; 2395dfecf96Smrg num.real.data.fixnum = 1; 2405dfecf96Smrg add_number_object(&num, number); 2415dfecf96Smrg 2425dfecf96Smrg return (make_number_object(&num)); 2435dfecf96Smrg} 2445dfecf96Smrg 2455dfecf96SmrgLispObj * 2465dfecf96SmrgLisp_OneMinus(LispBuiltin *builtin) 2475dfecf96Smrg/* 2485dfecf96Smrg 1- number 2495dfecf96Smrg */ 2505dfecf96Smrg{ 2515dfecf96Smrg n_number num; 2525dfecf96Smrg LispObj *number; 2535dfecf96Smrg 2545dfecf96Smrg number = ARGUMENT(0); 2555dfecf96Smrg num.complex = 0; 2565dfecf96Smrg num.real.type = N_FIXNUM; 2575dfecf96Smrg num.real.data.fixnum = -1; 2585dfecf96Smrg add_number_object(&num, number); 2595dfecf96Smrg 2605dfecf96Smrg return (make_number_object(&num)); 2615dfecf96Smrg} 2625dfecf96Smrg 2635dfecf96SmrgLispObj * 2645dfecf96SmrgLisp_Less(LispBuiltin *builtin) 2655dfecf96Smrg/* 2665dfecf96Smrg < number &rest more-numbers 2675dfecf96Smrg */ 2685dfecf96Smrg{ 2695dfecf96Smrg LispObj *compare, *number, *more_numbers; 2705dfecf96Smrg 2715dfecf96Smrg more_numbers = ARGUMENT(1); 2725dfecf96Smrg compare = ARGUMENT(0); 2735dfecf96Smrg 2745dfecf96Smrg if (CONSP(more_numbers)) { 2755dfecf96Smrg do { 2765dfecf96Smrg number = CAR(more_numbers); 2775dfecf96Smrg if (cmp_object_object(compare, number, 1) >= 0) 2785dfecf96Smrg return (NIL); 2795dfecf96Smrg compare = number; 2805dfecf96Smrg more_numbers = CDR(more_numbers); 2815dfecf96Smrg } while (CONSP(more_numbers)); 2825dfecf96Smrg } 2835dfecf96Smrg else { 2845dfecf96Smrg CHECK_REAL(compare); 2855dfecf96Smrg } 2865dfecf96Smrg 2875dfecf96Smrg return (T); 2885dfecf96Smrg} 2895dfecf96Smrg 2905dfecf96SmrgLispObj * 2915dfecf96SmrgLisp_LessEqual(LispBuiltin *builtin) 2925dfecf96Smrg/* 2935dfecf96Smrg <= number &rest more-numbers 2945dfecf96Smrg */ 2955dfecf96Smrg{ 2965dfecf96Smrg LispObj *compare, *number, *more_numbers; 2975dfecf96Smrg 2985dfecf96Smrg more_numbers = ARGUMENT(1); 2995dfecf96Smrg compare = ARGUMENT(0); 3005dfecf96Smrg 3015dfecf96Smrg if (CONSP(more_numbers)) { 3025dfecf96Smrg do { 3035dfecf96Smrg number = CAR(more_numbers); 3045dfecf96Smrg if (cmp_object_object(compare, number, 1) > 0) 3055dfecf96Smrg return (NIL); 3065dfecf96Smrg compare = number; 3075dfecf96Smrg more_numbers = CDR(more_numbers); 3085dfecf96Smrg } while (CONSP(more_numbers)); 3095dfecf96Smrg } 3105dfecf96Smrg else { 3115dfecf96Smrg CHECK_REAL(compare); 3125dfecf96Smrg } 3135dfecf96Smrg 3145dfecf96Smrg return (T); 3155dfecf96Smrg} 3165dfecf96Smrg 3175dfecf96SmrgLispObj * 3185dfecf96SmrgLisp_Equal_(LispBuiltin *builtin) 3195dfecf96Smrg/* 3205dfecf96Smrg = number &rest more-numbers 3215dfecf96Smrg */ 3225dfecf96Smrg{ 3235dfecf96Smrg LispObj *compare, *number, *more_numbers; 3245dfecf96Smrg 3255dfecf96Smrg more_numbers = ARGUMENT(1); 3265dfecf96Smrg compare = ARGUMENT(0); 3275dfecf96Smrg 3285dfecf96Smrg if (CONSP(more_numbers)) { 3295dfecf96Smrg do { 3305dfecf96Smrg number = CAR(more_numbers); 3315dfecf96Smrg if (cmp_object_object(compare, number, 0) != 0) 3325dfecf96Smrg return (NIL); 3335dfecf96Smrg compare = number; 3345dfecf96Smrg more_numbers = CDR(more_numbers); 3355dfecf96Smrg } while (CONSP(more_numbers)); 3365dfecf96Smrg } 3375dfecf96Smrg else { 3385dfecf96Smrg CHECK_REAL(compare); 3395dfecf96Smrg } 3405dfecf96Smrg 3415dfecf96Smrg return (T); 3425dfecf96Smrg} 3435dfecf96Smrg 3445dfecf96SmrgLispObj * 3455dfecf96SmrgLisp_Greater(LispBuiltin *builtin) 3465dfecf96Smrg/* 3475dfecf96Smrg > number &rest more-numbers 3485dfecf96Smrg */ 3495dfecf96Smrg{ 3505dfecf96Smrg LispObj *compare, *number, *more_numbers; 3515dfecf96Smrg 3525dfecf96Smrg more_numbers = ARGUMENT(1); 3535dfecf96Smrg compare = ARGUMENT(0); 3545dfecf96Smrg 3555dfecf96Smrg if (CONSP(more_numbers)) { 3565dfecf96Smrg do { 3575dfecf96Smrg number = CAR(more_numbers); 3585dfecf96Smrg if (cmp_object_object(compare, number, 1) <= 0) 3595dfecf96Smrg return (NIL); 3605dfecf96Smrg compare = number; 3615dfecf96Smrg more_numbers = CDR(more_numbers); 3625dfecf96Smrg } while (CONSP(more_numbers)); 3635dfecf96Smrg } 3645dfecf96Smrg else { 3655dfecf96Smrg CHECK_REAL(compare); 3665dfecf96Smrg } 3675dfecf96Smrg 3685dfecf96Smrg return (T); 3695dfecf96Smrg} 3705dfecf96Smrg 3715dfecf96SmrgLispObj * 3725dfecf96SmrgLisp_GreaterEqual(LispBuiltin *builtin) 3735dfecf96Smrg/* 3745dfecf96Smrg >= number &rest more-numbers 3755dfecf96Smrg */ 3765dfecf96Smrg{ 3775dfecf96Smrg LispObj *compare, *number, *more_numbers; 3785dfecf96Smrg 3795dfecf96Smrg more_numbers = ARGUMENT(1); 3805dfecf96Smrg compare = ARGUMENT(0); 3815dfecf96Smrg 3825dfecf96Smrg if (CONSP(more_numbers)) { 3835dfecf96Smrg do { 3845dfecf96Smrg number = CAR(more_numbers); 3855dfecf96Smrg if (cmp_object_object(compare, number, 1) < 0) 3865dfecf96Smrg return (NIL); 3875dfecf96Smrg compare = number; 3885dfecf96Smrg more_numbers = CDR(more_numbers); 3895dfecf96Smrg } while (CONSP(more_numbers)); 3905dfecf96Smrg } 3915dfecf96Smrg else { 3925dfecf96Smrg CHECK_REAL(compare); 3935dfecf96Smrg } 3945dfecf96Smrg 3955dfecf96Smrg return (T); 3965dfecf96Smrg} 3975dfecf96Smrg 3985dfecf96SmrgLispObj * 3995dfecf96SmrgLisp_NotEqual(LispBuiltin *builtin) 4005dfecf96Smrg/* 4015dfecf96Smrg /= number &rest more-numbers 4025dfecf96Smrg */ 4035dfecf96Smrg{ 4045dfecf96Smrg LispObj *object, *compare, *number, *more_numbers; 4055dfecf96Smrg 4065dfecf96Smrg more_numbers = ARGUMENT(1); 4075dfecf96Smrg number = ARGUMENT(0); 4085dfecf96Smrg 4095dfecf96Smrg if (!CONSP(more_numbers)) { 4105dfecf96Smrg CHECK_REAL(number); 4115dfecf96Smrg 4125dfecf96Smrg return (T); 4135dfecf96Smrg } 4145dfecf96Smrg 4155dfecf96Smrg /* compare all numbers */ 4165dfecf96Smrg while (1) { 4175dfecf96Smrg compare = number; 4185dfecf96Smrg for (object = more_numbers; CONSP(object); object = CDR(object)) { 4195dfecf96Smrg number = CAR(object); 4205dfecf96Smrg 4215dfecf96Smrg if (cmp_object_object(compare, number, 0) == 0) 4225dfecf96Smrg return (NIL); 4235dfecf96Smrg } 4245dfecf96Smrg if (CONSP(more_numbers)) { 4255dfecf96Smrg number = CAR(more_numbers); 4265dfecf96Smrg more_numbers = CDR(more_numbers); 4275dfecf96Smrg } 4285dfecf96Smrg else 4295dfecf96Smrg break; 4305dfecf96Smrg } 4315dfecf96Smrg 4325dfecf96Smrg return (T); 4335dfecf96Smrg} 4345dfecf96Smrg 4355dfecf96SmrgLispObj * 4365dfecf96SmrgLisp_Min(LispBuiltin *builtin) 4375dfecf96Smrg/* 4385dfecf96Smrg min number &rest more-numbers 4395dfecf96Smrg */ 4405dfecf96Smrg{ 4415dfecf96Smrg LispObj *result, *number, *more_numbers; 4425dfecf96Smrg 4435dfecf96Smrg more_numbers = ARGUMENT(1); 4445dfecf96Smrg result = ARGUMENT(0); 4455dfecf96Smrg 4465dfecf96Smrg if (CONSP(more_numbers)) { 4475dfecf96Smrg do { 4485dfecf96Smrg number = CAR(more_numbers); 4495dfecf96Smrg if (cmp_object_object(result, number, 1) > 0) 4505dfecf96Smrg result = number; 4515dfecf96Smrg more_numbers = CDR(more_numbers); 4525dfecf96Smrg } while (CONSP(more_numbers)); 4535dfecf96Smrg } 4545dfecf96Smrg else { 4555dfecf96Smrg CHECK_REAL(result); 4565dfecf96Smrg } 4575dfecf96Smrg 4585dfecf96Smrg return (result); 4595dfecf96Smrg} 4605dfecf96Smrg 4615dfecf96SmrgLispObj * 4625dfecf96SmrgLisp_Max(LispBuiltin *builtin) 4635dfecf96Smrg/* 4645dfecf96Smrg max number &rest more-numbers 4655dfecf96Smrg */ 4665dfecf96Smrg{ 4675dfecf96Smrg LispObj *result, *number, *more_numbers; 4685dfecf96Smrg 4695dfecf96Smrg more_numbers = ARGUMENT(1); 4705dfecf96Smrg result = ARGUMENT(0); 4715dfecf96Smrg 4725dfecf96Smrg if (CONSP(more_numbers)) { 4735dfecf96Smrg do { 4745dfecf96Smrg number = CAR(more_numbers); 4755dfecf96Smrg if (cmp_object_object(result, number, 1) < 0) 4765dfecf96Smrg result = number; 4775dfecf96Smrg more_numbers = CDR(more_numbers); 4785dfecf96Smrg } while (CONSP(more_numbers)); 4795dfecf96Smrg } 4805dfecf96Smrg else { 4815dfecf96Smrg CHECK_REAL(result); 4825dfecf96Smrg } 4835dfecf96Smrg 4845dfecf96Smrg return (result); 4855dfecf96Smrg} 4865dfecf96Smrg 4875dfecf96SmrgLispObj * 4885dfecf96SmrgLisp_Abs(LispBuiltin *builtin) 4895dfecf96Smrg/* 4905dfecf96Smrg abs number 4915dfecf96Smrg */ 4925dfecf96Smrg{ 4935dfecf96Smrg LispObj *result, *number; 4945dfecf96Smrg 4955dfecf96Smrg result = number = ARGUMENT(0); 4965dfecf96Smrg 4975dfecf96Smrg switch (OBJECT_TYPE(number)) { 4985dfecf96Smrg case LispFixnum_t: 4995dfecf96Smrg case LispInteger_t: 5005dfecf96Smrg case LispBignum_t: 5015dfecf96Smrg case LispDFloat_t: 5025dfecf96Smrg case LispRatio_t: 5035dfecf96Smrg case LispBigratio_t: 5045dfecf96Smrg if (cmp_real_object(&zero, number) > 0) { 5055dfecf96Smrg n_real real; 5065dfecf96Smrg 5075dfecf96Smrg set_real_object(&real, number); 5085dfecf96Smrg neg_real(&real); 5095dfecf96Smrg result = make_real_object(&real); 5105dfecf96Smrg } 5115dfecf96Smrg break; 5125dfecf96Smrg case LispComplex_t: { 5135dfecf96Smrg n_number num; 5145dfecf96Smrg 5155dfecf96Smrg set_number_object(&num, number); 5165dfecf96Smrg abs_number(&num); 5175dfecf96Smrg result = make_number_object(&num); 5185dfecf96Smrg } break; 5195dfecf96Smrg default: 5205dfecf96Smrg fatal_builtin_object_error(builtin, number, NOT_A_NUMBER); 5215dfecf96Smrg break; 5225dfecf96Smrg } 5235dfecf96Smrg 5245dfecf96Smrg return (result); 5255dfecf96Smrg} 5265dfecf96Smrg 5275dfecf96SmrgLispObj * 5285dfecf96SmrgLisp_Complex(LispBuiltin *builtin) 5295dfecf96Smrg/* 5305dfecf96Smrg complex realpart &optional imagpart 5315dfecf96Smrg */ 5325dfecf96Smrg{ 5335dfecf96Smrg LispObj *realpart, *imagpart; 5345dfecf96Smrg 5355dfecf96Smrg imagpart = ARGUMENT(1); 5365dfecf96Smrg realpart = ARGUMENT(0); 5375dfecf96Smrg 5385dfecf96Smrg CHECK_REAL(realpart); 5395dfecf96Smrg 5405dfecf96Smrg if (imagpart == UNSPEC) 5415dfecf96Smrg return (realpart); 5425dfecf96Smrg else { 5435dfecf96Smrg CHECK_REAL(imagpart); 5445dfecf96Smrg } 5455dfecf96Smrg if (!FLOATP(imagpart) && cmp_real_object(&zero, imagpart) == 0) 5465dfecf96Smrg return (realpart); 5475dfecf96Smrg 5485dfecf96Smrg return (COMPLEX(realpart, imagpart)); 5495dfecf96Smrg} 5505dfecf96Smrg 5515dfecf96SmrgLispObj * 5525dfecf96SmrgLisp_Complexp(LispBuiltin *builtin) 5535dfecf96Smrg/* 5545dfecf96Smrg complexp object 5555dfecf96Smrg */ 5565dfecf96Smrg{ 5575dfecf96Smrg LispObj *object; 5585dfecf96Smrg 5595dfecf96Smrg object = ARGUMENT(0); 5605dfecf96Smrg 5615dfecf96Smrg return (COMPLEXP(object) ? T : NIL); 5625dfecf96Smrg} 5635dfecf96Smrg 5645dfecf96SmrgLispObj * 5655dfecf96SmrgLisp_Conjugate(LispBuiltin *builtin) 5665dfecf96Smrg/* 5675dfecf96Smrg conjugate number 5685dfecf96Smrg */ 5695dfecf96Smrg{ 5705dfecf96Smrg n_number num; 5715dfecf96Smrg LispObj *number, *realpart, *imagpart; 5725dfecf96Smrg 5735dfecf96Smrg number = ARGUMENT(0); 5745dfecf96Smrg 5755dfecf96Smrg CHECK_NUMBER(number); 5765dfecf96Smrg 5775dfecf96Smrg if (REALP(number)) 5785dfecf96Smrg return (number); 5795dfecf96Smrg 5805dfecf96Smrg realpart = OCXR(number); 5815dfecf96Smrg num.complex = 0; 5825dfecf96Smrg num.real.type = N_FIXNUM; 5835dfecf96Smrg num.real.data.fixnum = -1; 5845dfecf96Smrg mul_number_object(&num, OCXI(number)); 5855dfecf96Smrg imagpart = make_number_object(&num); 5865dfecf96Smrg 5875dfecf96Smrg return (COMPLEX(realpart, imagpart)); 5885dfecf96Smrg} 5895dfecf96Smrg 5905dfecf96SmrgLispObj * 5915dfecf96SmrgLisp_Decf(LispBuiltin *builtin) 5925dfecf96Smrg/* 5935dfecf96Smrg decf place &optional delta 5945dfecf96Smrg */ 5955dfecf96Smrg{ 5965dfecf96Smrg n_number num; 5975dfecf96Smrg LispObj *place, *delta, *number; 5985dfecf96Smrg 5995dfecf96Smrg delta = ARGUMENT(1); 6005dfecf96Smrg place = ARGUMENT(0); 6015dfecf96Smrg 6025dfecf96Smrg if (SYMBOLP(place)) { 6035dfecf96Smrg number = LispGetVar(place); 6045dfecf96Smrg if (number == NULL) 6055dfecf96Smrg LispDestroy("EVAL: the variable %s is unbound", STROBJ(place)); 6065dfecf96Smrg } 6075dfecf96Smrg else 6085dfecf96Smrg number = EVAL(place); 6095dfecf96Smrg 6105dfecf96Smrg if (delta != UNSPEC) { 6115dfecf96Smrg LispObj *operand; 6125dfecf96Smrg 6135dfecf96Smrg operand = EVAL(delta); 6145dfecf96Smrg set_number_object(&num, number); 6155dfecf96Smrg sub_number_object(&num, operand); 6165dfecf96Smrg number = make_number_object(&num); 6175dfecf96Smrg } 6185dfecf96Smrg else { 6195dfecf96Smrg num.complex = 0; 6205dfecf96Smrg num.real.type = N_FIXNUM; 6215dfecf96Smrg num.real.data.fixnum = -1; 6225dfecf96Smrg add_number_object(&num, number); 6235dfecf96Smrg number = make_number_object(&num); 6245dfecf96Smrg } 6255dfecf96Smrg 6265dfecf96Smrg if (SYMBOLP(place)) { 6275dfecf96Smrg CHECK_CONSTANT(place); 6285dfecf96Smrg LispSetVar(place, number); 6295dfecf96Smrg } 6305dfecf96Smrg else { 6315dfecf96Smrg GC_ENTER(); 6325dfecf96Smrg 6335dfecf96Smrg GC_PROTECT(number); 6345dfecf96Smrg (void)APPLY2(Osetf, place, number); 6355dfecf96Smrg GC_LEAVE(); 6365dfecf96Smrg } 6375dfecf96Smrg 6385dfecf96Smrg return (number); 6395dfecf96Smrg} 6405dfecf96Smrg 6415dfecf96SmrgLispObj * 6425dfecf96SmrgLisp_Denominator(LispBuiltin *builtin) 6435dfecf96Smrg/* 6445dfecf96Smrg denominator rational 6455dfecf96Smrg */ 6465dfecf96Smrg{ 6475dfecf96Smrg LispObj *result, *rational; 6485dfecf96Smrg 6495dfecf96Smrg rational = ARGUMENT(0); 6505dfecf96Smrg 6515dfecf96Smrg switch (OBJECT_TYPE(rational)) { 6525dfecf96Smrg case LispFixnum_t: 6535dfecf96Smrg case LispInteger_t: 6545dfecf96Smrg case LispBignum_t: 6555dfecf96Smrg result = FIXNUM(1); 6565dfecf96Smrg break; 6575dfecf96Smrg case LispRatio_t: 6585dfecf96Smrg result = INTEGER(OFRD(rational)); 6595dfecf96Smrg break; 6605dfecf96Smrg case LispBigratio_t: 6615dfecf96Smrg if (mpi_fiti(OBRD(rational))) 6625dfecf96Smrg result = INTEGER(mpi_geti(OBRD(rational))); 6635dfecf96Smrg else { 6645dfecf96Smrg mpi *den = XALLOC(mpi); 6655dfecf96Smrg 6665dfecf96Smrg mpi_init(den); 6675dfecf96Smrg mpi_set(den, OBRD(rational)); 6685dfecf96Smrg result = BIGNUM(den); 6695dfecf96Smrg } 6705dfecf96Smrg break; 6715dfecf96Smrg default: 6725dfecf96Smrg LispDestroy("%s: %s is not a rational number", 6735dfecf96Smrg STRFUN(builtin), STROBJ(rational)); 6745dfecf96Smrg /*NOTREACHED*/ 6755dfecf96Smrg result = NIL; 6765dfecf96Smrg } 6775dfecf96Smrg 6785dfecf96Smrg return (result); 6795dfecf96Smrg} 6805dfecf96Smrg 6815dfecf96SmrgLispObj * 6825dfecf96SmrgLisp_Evenp(LispBuiltin *builtin) 6835dfecf96Smrg/* 6845dfecf96Smrg evenp integer 6855dfecf96Smrg */ 6865dfecf96Smrg{ 6875dfecf96Smrg LispObj *result, *integer; 6885dfecf96Smrg 6895dfecf96Smrg integer = ARGUMENT(0); 6905dfecf96Smrg 6915dfecf96Smrg switch (OBJECT_TYPE(integer)) { 6925dfecf96Smrg case LispFixnum_t: 6935dfecf96Smrg result = FIXNUM_VALUE(integer) % 2 ? NIL : T; 6945dfecf96Smrg break; 6955dfecf96Smrg case LispInteger_t: 6965dfecf96Smrg result = INT_VALUE(integer) % 2 ? NIL : T; 6975dfecf96Smrg break; 6985dfecf96Smrg case LispBignum_t: 6995dfecf96Smrg result = mpi_remi(OBI(integer), 2) ? NIL : T; 7005dfecf96Smrg break; 7015dfecf96Smrg default: 7025dfecf96Smrg fatal_builtin_object_error(builtin, integer, NOT_AN_INTEGER); 7035dfecf96Smrg /*NOTREACHED*/ 7045dfecf96Smrg result = NIL; 7055dfecf96Smrg } 7065dfecf96Smrg 7075dfecf96Smrg return (result); 7085dfecf96Smrg} 7095dfecf96Smrg 7105dfecf96Smrg/* only one float format */ 7115dfecf96SmrgLispObj * 7125dfecf96SmrgLisp_Float(LispBuiltin *builtin) 7135dfecf96Smrg/* 7145dfecf96Smrg float number &optional other 7155dfecf96Smrg */ 7165dfecf96Smrg{ 7175dfecf96Smrg LispObj *number, *other; 7185dfecf96Smrg 7195dfecf96Smrg other = ARGUMENT(1); 7205dfecf96Smrg number = ARGUMENT(0); 7215dfecf96Smrg 7225dfecf96Smrg if (other != UNSPEC) { 7235dfecf96Smrg CHECK_DFLOAT(other); 7245dfecf96Smrg } 7255dfecf96Smrg 7265dfecf96Smrg return (LispFloatCoerce(builtin, number)); 7275dfecf96Smrg} 7285dfecf96Smrg 7295dfecf96SmrgLispObj * 7305dfecf96SmrgLispFloatCoerce(LispBuiltin *builtin, LispObj *number) 7315dfecf96Smrg{ 7325dfecf96Smrg double value; 7335dfecf96Smrg 7345dfecf96Smrg switch (OBJECT_TYPE(number)) { 7355dfecf96Smrg case LispFixnum_t: 7365dfecf96Smrg value = FIXNUM_VALUE(number); 7375dfecf96Smrg break; 7385dfecf96Smrg case LispInteger_t: 7395dfecf96Smrg value = INT_VALUE(number); 7405dfecf96Smrg break; 7415dfecf96Smrg case LispBignum_t: 7425dfecf96Smrg value = mpi_getd(OBI(number)); 7435dfecf96Smrg break; 7445dfecf96Smrg case LispDFloat_t: 7455dfecf96Smrg return (number); 7465dfecf96Smrg case LispRatio_t: 7475dfecf96Smrg value = (double)OFRN(number) / (double)OFRD(number); 7485dfecf96Smrg break; 7495dfecf96Smrg case LispBigratio_t: 7505dfecf96Smrg value = mpr_getd(OBR(number)); 7515dfecf96Smrg break; 7525dfecf96Smrg default: 7535dfecf96Smrg value = 0.0; 7545dfecf96Smrg fatal_builtin_object_error(builtin, number, NOT_A_REAL_NUMBER); 7555dfecf96Smrg break; 7565dfecf96Smrg } 7575dfecf96Smrg 7585dfecf96Smrg if (!finite(value)) 7595dfecf96Smrg fatal_error(FLOATING_POINT_OVERFLOW); 7605dfecf96Smrg 7615dfecf96Smrg return (DFLOAT(value)); 7625dfecf96Smrg} 7635dfecf96Smrg 7645dfecf96SmrgLispObj * 7655dfecf96SmrgLisp_Floatp(LispBuiltin *builtin) 7665dfecf96Smrg/* 7675dfecf96Smrg floatp object 7685dfecf96Smrg */ 7695dfecf96Smrg{ 7705dfecf96Smrg LispObj *object; 7715dfecf96Smrg 7725dfecf96Smrg object = ARGUMENT(0); 7735dfecf96Smrg 7745dfecf96Smrg return (FLOATP(object) ? T : NIL); 7755dfecf96Smrg} 7765dfecf96Smrg 7775dfecf96SmrgLispObj * 7785dfecf96SmrgLisp_Gcd(LispBuiltin *builtin) 7795dfecf96Smrg/* 7805dfecf96Smrg gcd &rest integers 7815dfecf96Smrg */ 7825dfecf96Smrg{ 7835dfecf96Smrg n_real real; 7845dfecf96Smrg LispObj *integers, *integer, *operand; 7855dfecf96Smrg 7865dfecf96Smrg integers = ARGUMENT(0); 7875dfecf96Smrg 7885dfecf96Smrg if (!CONSP(integers)) 7895dfecf96Smrg return (FIXNUM(0)); 7905dfecf96Smrg 7915dfecf96Smrg integer = CAR(integers); 7925dfecf96Smrg 7935dfecf96Smrg CHECK_INTEGER(integer); 7945dfecf96Smrg set_real_object(&real, integer); 7955dfecf96Smrg integers = CDR(integers); 7965dfecf96Smrg 7975dfecf96Smrg for (; CONSP(integers); integers = CDR(integers)) { 7985dfecf96Smrg operand = CAR(integers); 7995dfecf96Smrg gcd_real_object(&real, operand); 8005dfecf96Smrg } 8015dfecf96Smrg abs_real(&real); 8025dfecf96Smrg 8035dfecf96Smrg return (make_real_object(&real)); 8045dfecf96Smrg} 8055dfecf96Smrg 8065dfecf96SmrgLispObj * 8075dfecf96SmrgLisp_Imagpart(LispBuiltin *builtin) 8085dfecf96Smrg/* 8095dfecf96Smrg imagpart number 8105dfecf96Smrg */ 8115dfecf96Smrg{ 8125dfecf96Smrg LispObj *number; 8135dfecf96Smrg 8145dfecf96Smrg number = ARGUMENT(0); 8155dfecf96Smrg 8165dfecf96Smrg if (COMPLEXP(number)) 8175dfecf96Smrg return (OCXI(number)); 8185dfecf96Smrg else { 8195dfecf96Smrg CHECK_REAL(number); 8205dfecf96Smrg } 8215dfecf96Smrg 8225dfecf96Smrg return (FIXNUM(0)); 8235dfecf96Smrg} 8245dfecf96Smrg 8255dfecf96SmrgLispObj * 8265dfecf96SmrgLisp_Incf(LispBuiltin *builtin) 8275dfecf96Smrg/* 8285dfecf96Smrg incf place &optional delta 8295dfecf96Smrg */ 8305dfecf96Smrg{ 8315dfecf96Smrg n_number num; 8325dfecf96Smrg LispObj *place, *delta, *number; 8335dfecf96Smrg 8345dfecf96Smrg delta = ARGUMENT(1); 8355dfecf96Smrg place = ARGUMENT(0); 8365dfecf96Smrg 8375dfecf96Smrg if (SYMBOLP(place)) { 8385dfecf96Smrg number = LispGetVar(place); 8395dfecf96Smrg if (number == NULL) 8405dfecf96Smrg LispDestroy("EVAL: the variable %s is unbound", STROBJ(place)); 8415dfecf96Smrg } 8425dfecf96Smrg else 8435dfecf96Smrg number = EVAL(place); 8445dfecf96Smrg 8455dfecf96Smrg if (delta != UNSPEC) { 8465dfecf96Smrg LispObj *operand; 8475dfecf96Smrg 8485dfecf96Smrg operand = EVAL(delta); 8495dfecf96Smrg set_number_object(&num, number); 8505dfecf96Smrg add_number_object(&num, operand); 8515dfecf96Smrg number = make_number_object(&num); 8525dfecf96Smrg } 8535dfecf96Smrg else { 8545dfecf96Smrg num.complex = 0; 8555dfecf96Smrg num.real.type = N_FIXNUM; 8565dfecf96Smrg num.real.data.fixnum = 1; 8575dfecf96Smrg add_number_object(&num, number); 8585dfecf96Smrg number = make_number_object(&num); 8595dfecf96Smrg } 8605dfecf96Smrg 8615dfecf96Smrg if (SYMBOLP(place)) { 8625dfecf96Smrg CHECK_CONSTANT(place); 8635dfecf96Smrg LispSetVar(place, number); 8645dfecf96Smrg } 8655dfecf96Smrg else { 8665dfecf96Smrg GC_ENTER(); 8675dfecf96Smrg 8685dfecf96Smrg GC_PROTECT(number); 8695dfecf96Smrg (void)APPLY2(Osetf, place, number); 8705dfecf96Smrg GC_LEAVE(); 8715dfecf96Smrg } 8725dfecf96Smrg 8735dfecf96Smrg return (number); 8745dfecf96Smrg} 8755dfecf96Smrg 8765dfecf96SmrgLispObj * 8775dfecf96SmrgLisp_Integerp(LispBuiltin *builtin) 8785dfecf96Smrg/* 8795dfecf96Smrg integerp object 8805dfecf96Smrg */ 8815dfecf96Smrg{ 8825dfecf96Smrg LispObj *object; 8835dfecf96Smrg 8845dfecf96Smrg object = ARGUMENT(0); 8855dfecf96Smrg 8865dfecf96Smrg return (INTEGERP(object) ? T : NIL); 8875dfecf96Smrg} 8885dfecf96Smrg 8895dfecf96SmrgLispObj * 8905dfecf96SmrgLisp_Isqrt(LispBuiltin *builtin) 8915dfecf96Smrg/* 8925dfecf96Smrg isqrt natural 8935dfecf96Smrg */ 8945dfecf96Smrg{ 8955dfecf96Smrg LispObj *natural, *result; 8965dfecf96Smrg 8975dfecf96Smrg natural = ARGUMENT(0); 8985dfecf96Smrg 8995dfecf96Smrg if (cmp_object_object(natural, obj_zero, 1) < 0) 9005dfecf96Smrg goto not_a_natural_number; 9015dfecf96Smrg 9025dfecf96Smrg switch (OBJECT_TYPE(natural)) { 9035dfecf96Smrg case LispFixnum_t: 9045dfecf96Smrg result = FIXNUM((long)floor(sqrt(FIXNUM_VALUE(natural)))); 9055dfecf96Smrg break; 9065dfecf96Smrg case LispInteger_t: 9075dfecf96Smrg result = INTEGER((long)floor(sqrt(INT_VALUE(natural)))); 9085dfecf96Smrg break; 9095dfecf96Smrg case LispBignum_t: { 9105dfecf96Smrg mpi *bigi; 9115dfecf96Smrg 9125dfecf96Smrg bigi = XALLOC(mpi); 9135dfecf96Smrg mpi_init(bigi); 9145dfecf96Smrg mpi_sqrt(bigi, OBI(natural)); 9155dfecf96Smrg if (mpi_fiti(bigi)) { 9165dfecf96Smrg result = INTEGER(mpi_geti(bigi)); 9175dfecf96Smrg mpi_clear(bigi); 9185dfecf96Smrg XFREE(bigi); 9195dfecf96Smrg } 9205dfecf96Smrg else 9215dfecf96Smrg result = BIGNUM(bigi); 9225dfecf96Smrg } break; 9235dfecf96Smrg default: 9245dfecf96Smrg goto not_a_natural_number; 9255dfecf96Smrg } 9265dfecf96Smrg 9275dfecf96Smrg return (result); 9285dfecf96Smrg 9295dfecf96Smrgnot_a_natural_number: 9305dfecf96Smrg LispDestroy("%s: %s is not a natural number", 9315dfecf96Smrg STRFUN(builtin), STROBJ(natural)); 9325dfecf96Smrg /*NOTREACHED*/ 9335dfecf96Smrg return (NIL); 9345dfecf96Smrg} 9355dfecf96Smrg 9365dfecf96SmrgLispObj * 9375dfecf96SmrgLisp_Lcm(LispBuiltin *builtin) 9385dfecf96Smrg/* 9395dfecf96Smrg lcm &rest integers 9405dfecf96Smrg */ 9415dfecf96Smrg{ 9425dfecf96Smrg n_real real, gcd; 9435dfecf96Smrg LispObj *integers, *operand; 9445dfecf96Smrg 9455dfecf96Smrg integers = ARGUMENT(0); 9465dfecf96Smrg 9475dfecf96Smrg if (!CONSP(integers)) 9485dfecf96Smrg return (FIXNUM(1)); 9495dfecf96Smrg 9505dfecf96Smrg operand = CAR(integers); 9515dfecf96Smrg 9525dfecf96Smrg CHECK_INTEGER(operand); 9535dfecf96Smrg set_real_object(&real, operand); 9545dfecf96Smrg integers = CDR(integers); 9555dfecf96Smrg 9565dfecf96Smrg gcd.type = N_FIXNUM; 9575dfecf96Smrg gcd.data.fixnum = 0; 9585dfecf96Smrg 9595dfecf96Smrg for (; CONSP(integers); integers = CDR(integers)) { 9605dfecf96Smrg operand = CAR(integers); 9615dfecf96Smrg 9625dfecf96Smrg if (real.type == N_FIXNUM && real.data.fixnum == 0) 9635dfecf96Smrg break; 9645dfecf96Smrg 9655dfecf96Smrg /* calculate gcd before changing integer */ 9665dfecf96Smrg clear_real(&gcd); 9675dfecf96Smrg set_real_real(&gcd, &real); 9685dfecf96Smrg gcd_real_object(&gcd, operand); 9695dfecf96Smrg 9705dfecf96Smrg /* calculate lcm */ 9715dfecf96Smrg mul_real_object(&real, operand); 9725dfecf96Smrg div_real_real(&real, &gcd); 9735dfecf96Smrg } 9745dfecf96Smrg clear_real(&gcd); 9755dfecf96Smrg abs_real(&real); 9765dfecf96Smrg 9775dfecf96Smrg return (make_real_object(&real)); 9785dfecf96Smrg} 9795dfecf96Smrg 9805dfecf96SmrgLispObj * 9815dfecf96SmrgLisp_Logand(LispBuiltin *builtin) 9825dfecf96Smrg/* 9835dfecf96Smrg logand &rest integers 9845dfecf96Smrg */ 9855dfecf96Smrg{ 9865dfecf96Smrg n_real real; 9875dfecf96Smrg 9885dfecf96Smrg LispObj *integers; 9895dfecf96Smrg 9905dfecf96Smrg integers = ARGUMENT(0); 9915dfecf96Smrg 9925dfecf96Smrg real.type = N_FIXNUM; 9935dfecf96Smrg real.data.fixnum = -1; 9945dfecf96Smrg 9955dfecf96Smrg for (; CONSP(integers); integers = CDR(integers)) 9965dfecf96Smrg and_real_object(&real, CAR(integers)); 9975dfecf96Smrg 9985dfecf96Smrg return (make_real_object(&real)); 9995dfecf96Smrg} 10005dfecf96Smrg 10015dfecf96SmrgLispObj * 10025dfecf96SmrgLisp_Logeqv(LispBuiltin *builtin) 10035dfecf96Smrg/* 10045dfecf96Smrg logeqv &rest integers 10055dfecf96Smrg */ 10065dfecf96Smrg{ 10075dfecf96Smrg n_real real; 10085dfecf96Smrg 10095dfecf96Smrg LispObj *integers; 10105dfecf96Smrg 10115dfecf96Smrg integers = ARGUMENT(0); 10125dfecf96Smrg 10135dfecf96Smrg real.type = N_FIXNUM; 10145dfecf96Smrg real.data.fixnum = -1; 10155dfecf96Smrg 10165dfecf96Smrg for (; CONSP(integers); integers = CDR(integers)) 10175dfecf96Smrg eqv_real_object(&real, CAR(integers)); 10185dfecf96Smrg 10195dfecf96Smrg return (make_real_object(&real)); 10205dfecf96Smrg} 10215dfecf96Smrg 10225dfecf96SmrgLispObj * 10235dfecf96SmrgLisp_Logior(LispBuiltin *builtin) 10245dfecf96Smrg/* 10255dfecf96Smrg logior &rest integers 10265dfecf96Smrg */ 10275dfecf96Smrg{ 10285dfecf96Smrg n_real real; 10295dfecf96Smrg 10305dfecf96Smrg LispObj *integers; 10315dfecf96Smrg 10325dfecf96Smrg integers = ARGUMENT(0); 10335dfecf96Smrg 10345dfecf96Smrg real.type = N_FIXNUM; 10355dfecf96Smrg real.data.fixnum = 0; 10365dfecf96Smrg 10375dfecf96Smrg for (; CONSP(integers); integers = CDR(integers)) 10385dfecf96Smrg ior_real_object(&real, CAR(integers)); 10395dfecf96Smrg 10405dfecf96Smrg return (make_real_object(&real)); 10415dfecf96Smrg} 10425dfecf96Smrg 10435dfecf96SmrgLispObj * 10445dfecf96SmrgLisp_Lognot(LispBuiltin *builtin) 10455dfecf96Smrg/* 10465dfecf96Smrg lognot integer 10475dfecf96Smrg */ 10485dfecf96Smrg{ 10495dfecf96Smrg n_real real; 10505dfecf96Smrg 10515dfecf96Smrg LispObj *integer; 10525dfecf96Smrg 10535dfecf96Smrg integer = ARGUMENT(0); 10545dfecf96Smrg 10555dfecf96Smrg CHECK_INTEGER(integer); 10565dfecf96Smrg 10575dfecf96Smrg set_real_object(&real, integer); 10585dfecf96Smrg not_real(&real); 10595dfecf96Smrg 10605dfecf96Smrg return (make_real_object(&real)); 10615dfecf96Smrg} 10625dfecf96Smrg 10635dfecf96SmrgLispObj * 10645dfecf96SmrgLisp_Logxor(LispBuiltin *builtin) 10655dfecf96Smrg/* 10665dfecf96Smrg logxor &rest integers 10675dfecf96Smrg */ 10685dfecf96Smrg{ 10695dfecf96Smrg n_real real; 10705dfecf96Smrg 10715dfecf96Smrg LispObj *integers; 10725dfecf96Smrg 10735dfecf96Smrg integers = ARGUMENT(0); 10745dfecf96Smrg 10755dfecf96Smrg real.type = N_FIXNUM; 10765dfecf96Smrg real.data.fixnum = 0; 10775dfecf96Smrg 10785dfecf96Smrg for (; CONSP(integers); integers = CDR(integers)) 10795dfecf96Smrg xor_real_object(&real, CAR(integers)); 10805dfecf96Smrg 10815dfecf96Smrg return (make_real_object(&real)); 10825dfecf96Smrg} 10835dfecf96Smrg 10845dfecf96SmrgLispObj * 10855dfecf96SmrgLisp_Minusp(LispBuiltin *builtin) 10865dfecf96Smrg/* 10875dfecf96Smrg minusp number 10885dfecf96Smrg */ 10895dfecf96Smrg{ 10905dfecf96Smrg LispObj *number; 10915dfecf96Smrg 10925dfecf96Smrg number = ARGUMENT(0); 10935dfecf96Smrg 10945dfecf96Smrg CHECK_REAL(number); 10955dfecf96Smrg 10965dfecf96Smrg return (cmp_real_object(&zero, number) > 0 ? T : NIL); 10975dfecf96Smrg} 10985dfecf96Smrg 10995dfecf96SmrgLispObj * 11005dfecf96SmrgLisp_Mod(LispBuiltin *builtin) 11015dfecf96Smrg/* 11025dfecf96Smrg mod number divisor 11035dfecf96Smrg */ 11045dfecf96Smrg{ 11055dfecf96Smrg LispObj *result; 11065dfecf96Smrg 11075dfecf96Smrg LispObj *number, *divisor; 11085dfecf96Smrg 11095dfecf96Smrg divisor = ARGUMENT(1); 11105dfecf96Smrg number = ARGUMENT(0); 11115dfecf96Smrg 11125dfecf96Smrg if (INTEGERP(number) && INTEGERP(divisor)) { 11135dfecf96Smrg n_real real; 11145dfecf96Smrg 11155dfecf96Smrg set_real_object(&real, number); 11165dfecf96Smrg mod_real_object(&real, divisor); 11175dfecf96Smrg result = make_real_object(&real); 11185dfecf96Smrg } 11195dfecf96Smrg else { 11205dfecf96Smrg n_number num; 11215dfecf96Smrg 11225dfecf96Smrg set_number_object(&num, number); 11235dfecf96Smrg divide_number_object(&num, divisor, NDIVIDE_FLOOR, 0); 11245dfecf96Smrg result = make_real_object(&(num.imag)); 11255dfecf96Smrg clear_real(&(num.real)); 11265dfecf96Smrg } 11275dfecf96Smrg 11285dfecf96Smrg return (result); 11295dfecf96Smrg} 11305dfecf96Smrg 11315dfecf96SmrgLispObj * 11325dfecf96SmrgLisp_Numberp(LispBuiltin *builtin) 11335dfecf96Smrg/* 11345dfecf96Smrg numberp object 11355dfecf96Smrg */ 11365dfecf96Smrg{ 11375dfecf96Smrg LispObj *object; 11385dfecf96Smrg 11395dfecf96Smrg object = ARGUMENT(0); 11405dfecf96Smrg 11415dfecf96Smrg return (NUMBERP(object) ? T : NIL); 11425dfecf96Smrg} 11435dfecf96Smrg 11445dfecf96SmrgLispObj * 11455dfecf96SmrgLisp_Numerator(LispBuiltin *builtin) 11465dfecf96Smrg/* 11475dfecf96Smrg numerator rational 11485dfecf96Smrg */ 11495dfecf96Smrg{ 11505dfecf96Smrg LispObj *result, *rational; 11515dfecf96Smrg 11525dfecf96Smrg rational = ARGUMENT(0); 11535dfecf96Smrg 11545dfecf96Smrg switch (OBJECT_TYPE(rational)) { 11555dfecf96Smrg case LispFixnum_t: 11565dfecf96Smrg case LispInteger_t: 11575dfecf96Smrg case LispBignum_t: 11585dfecf96Smrg result = rational; 11595dfecf96Smrg break; 11605dfecf96Smrg case LispRatio_t: 11615dfecf96Smrg result = INTEGER(OFRN(rational)); 11625dfecf96Smrg break; 11635dfecf96Smrg case LispBigratio_t: 11645dfecf96Smrg if (mpi_fiti(OBRN(rational))) 11655dfecf96Smrg result = INTEGER(mpi_geti(OBRN(rational))); 11665dfecf96Smrg else { 11675dfecf96Smrg mpi *num = XALLOC(mpi); 11685dfecf96Smrg 11695dfecf96Smrg mpi_init(num); 11705dfecf96Smrg mpi_set(num, OBRN(rational)); 11715dfecf96Smrg result = BIGNUM(num); 11725dfecf96Smrg } 11735dfecf96Smrg break; 11745dfecf96Smrg default: 11755dfecf96Smrg LispDestroy("%s: %s is not a rational number", 11765dfecf96Smrg STRFUN(builtin), STROBJ(rational)); 11775dfecf96Smrg /*NOTREACHED*/ 11785dfecf96Smrg result = NIL; 11795dfecf96Smrg } 11805dfecf96Smrg 11815dfecf96Smrg return (result); 11825dfecf96Smrg} 11835dfecf96Smrg 11845dfecf96SmrgLispObj * 11855dfecf96SmrgLisp_Oddp(LispBuiltin *builtin) 11865dfecf96Smrg/* 11875dfecf96Smrg oddp integer 11885dfecf96Smrg */ 11895dfecf96Smrg{ 11905dfecf96Smrg LispObj *result, *integer; 11915dfecf96Smrg 11925dfecf96Smrg integer = ARGUMENT(0); 11935dfecf96Smrg 11945dfecf96Smrg switch (OBJECT_TYPE(integer)) { 11955dfecf96Smrg case LispFixnum_t: 11965dfecf96Smrg result = FIXNUM_VALUE(integer) % 2 ? T : NIL; 11975dfecf96Smrg break; 11985dfecf96Smrg case LispInteger_t: 11995dfecf96Smrg result = INT_VALUE(integer) % 2 ? T : NIL; 12005dfecf96Smrg break; 12015dfecf96Smrg case LispBignum_t: 12025dfecf96Smrg result = mpi_remi(OBI(integer), 2) ? T : NIL; 12035dfecf96Smrg break; 12045dfecf96Smrg default: 12055dfecf96Smrg fatal_builtin_object_error(builtin, integer, NOT_AN_INTEGER); 12065dfecf96Smrg /*NOTREACHED*/ 12075dfecf96Smrg result = NIL; 12085dfecf96Smrg } 12095dfecf96Smrg 12105dfecf96Smrg return (result); 12115dfecf96Smrg} 12125dfecf96Smrg 12135dfecf96SmrgLispObj * 12145dfecf96SmrgLisp_Plusp(LispBuiltin *builtin) 12155dfecf96Smrg/* 12165dfecf96Smrg plusp number 12175dfecf96Smrg */ 12185dfecf96Smrg{ 12195dfecf96Smrg LispObj *number; 12205dfecf96Smrg 12215dfecf96Smrg number = ARGUMENT(0); 12225dfecf96Smrg 12235dfecf96Smrg CHECK_REAL(number); 12245dfecf96Smrg 12255dfecf96Smrg return (cmp_real_object(&zero, number) < 0 ? T : NIL); 12265dfecf96Smrg} 12275dfecf96Smrg 12285dfecf96SmrgLispObj * 12295dfecf96SmrgLisp_Rational(LispBuiltin *builtin) 12305dfecf96Smrg/* 12315dfecf96Smrg rational number 12325dfecf96Smrg */ 12335dfecf96Smrg{ 12345dfecf96Smrg LispObj *number; 12355dfecf96Smrg 12365dfecf96Smrg number = ARGUMENT(0); 12375dfecf96Smrg 12385dfecf96Smrg if (DFLOATP(number)) { 12395dfecf96Smrg double numerator = ODF(number); 12405dfecf96Smrg 12415dfecf96Smrg if ((long)numerator == numerator) 12425dfecf96Smrg number = INTEGER(numerator); 12435dfecf96Smrg else { 12445dfecf96Smrg n_real real; 12455dfecf96Smrg mpr *bigr = XALLOC(mpr); 12465dfecf96Smrg 12475dfecf96Smrg mpr_init(bigr); 12485dfecf96Smrg mpr_setd(bigr, numerator); 12495dfecf96Smrg real.type = N_BIGRATIO; 12505dfecf96Smrg real.data.bigratio = bigr; 12515dfecf96Smrg rbr_canonicalize(&real); 12525dfecf96Smrg number = make_real_object(&real); 12535dfecf96Smrg } 12545dfecf96Smrg } 12555dfecf96Smrg else { 12565dfecf96Smrg CHECK_REAL(number); 12575dfecf96Smrg } 12585dfecf96Smrg 12595dfecf96Smrg return (number); 12605dfecf96Smrg} 12615dfecf96Smrg 12625dfecf96SmrgLispObj * 12635dfecf96SmrgLisp_Rationalp(LispBuiltin *builtin) 12645dfecf96Smrg/* 12655dfecf96Smrg rationalp object 12665dfecf96Smrg */ 12675dfecf96Smrg{ 12685dfecf96Smrg LispObj *object; 12695dfecf96Smrg 12705dfecf96Smrg object = ARGUMENT(0); 12715dfecf96Smrg 12725dfecf96Smrg return (RATIONALP(object) ? T : NIL); 12735dfecf96Smrg} 12745dfecf96Smrg 12755dfecf96SmrgLispObj * 12765dfecf96SmrgLisp_Realpart(LispBuiltin *builtin) 12775dfecf96Smrg/* 12785dfecf96Smrg realpart number 12795dfecf96Smrg */ 12805dfecf96Smrg{ 12815dfecf96Smrg LispObj *number; 12825dfecf96Smrg 12835dfecf96Smrg number = ARGUMENT(0); 12845dfecf96Smrg 12855dfecf96Smrg if (COMPLEXP(number)) 12865dfecf96Smrg return (OCXR(number)); 12875dfecf96Smrg else { 12885dfecf96Smrg CHECK_REAL(number); 12895dfecf96Smrg } 12905dfecf96Smrg 12915dfecf96Smrg return (number); 12925dfecf96Smrg} 12935dfecf96Smrg 12945dfecf96SmrgLispObj * 12955dfecf96SmrgLisp_Rem(LispBuiltin *builtin) 12965dfecf96Smrg/* 12975dfecf96Smrg rem number divisor 12985dfecf96Smrg */ 12995dfecf96Smrg{ 13005dfecf96Smrg LispObj *result; 13015dfecf96Smrg 13025dfecf96Smrg LispObj *number, *divisor; 13035dfecf96Smrg 13045dfecf96Smrg divisor = ARGUMENT(1); 13055dfecf96Smrg number = ARGUMENT(0); 13065dfecf96Smrg 13075dfecf96Smrg if (INTEGERP(number) && INTEGERP(divisor)) { 13085dfecf96Smrg n_real real; 13095dfecf96Smrg 13105dfecf96Smrg set_real_object(&real, number); 13115dfecf96Smrg rem_real_object(&real, divisor); 13125dfecf96Smrg result = make_real_object(&real); 13135dfecf96Smrg } 13145dfecf96Smrg else { 13155dfecf96Smrg n_number num; 13165dfecf96Smrg 13175dfecf96Smrg set_number_object(&num, number); 13185dfecf96Smrg divide_number_object(&num, divisor, NDIVIDE_TRUNC, 0); 13195dfecf96Smrg result = make_real_object(&(num.imag)); 13205dfecf96Smrg clear_real(&(num.real)); 13215dfecf96Smrg } 13225dfecf96Smrg 13235dfecf96Smrg return (result); 13245dfecf96Smrg} 13255dfecf96Smrg 13265dfecf96SmrgLispObj * 13275dfecf96SmrgLisp_Sqrt(LispBuiltin *builtin) 13285dfecf96Smrg/* 13295dfecf96Smrg sqrt number 13305dfecf96Smrg */ 13315dfecf96Smrg{ 13325dfecf96Smrg n_number num; 13335dfecf96Smrg LispObj *number; 13345dfecf96Smrg 13355dfecf96Smrg number = ARGUMENT(0); 13365dfecf96Smrg 13375dfecf96Smrg set_number_object(&num, number); 13385dfecf96Smrg sqrt_number(&num); 13395dfecf96Smrg 13405dfecf96Smrg return (make_number_object(&num)); 13415dfecf96Smrg} 13425dfecf96Smrg 13435dfecf96SmrgLispObj * 13445dfecf96SmrgLisp_Zerop(LispBuiltin *builtin) 13455dfecf96Smrg/* 13465dfecf96Smrg zerop number 13475dfecf96Smrg */ 13485dfecf96Smrg{ 13495dfecf96Smrg LispObj *result, *number; 13505dfecf96Smrg 13515dfecf96Smrg number = ARGUMENT(0); 13525dfecf96Smrg 13535dfecf96Smrg switch (OBJECT_TYPE(number)) { 13545dfecf96Smrg case LispFixnum_t: 13555dfecf96Smrg case LispInteger_t: 13565dfecf96Smrg case LispBignum_t: 13575dfecf96Smrg case LispDFloat_t: 13585dfecf96Smrg case LispRatio_t: 13595dfecf96Smrg case LispBigratio_t: 13605dfecf96Smrg result = cmp_real_object(&zero, number) == 0 ? T : NIL; 13615dfecf96Smrg break; 13625dfecf96Smrg case LispComplex_t: 13635dfecf96Smrg result = cmp_real_object(&zero, OCXR(number)) == 0 && 13645dfecf96Smrg cmp_real_object(&zero, OCXI(number)) == 0 ? T : NIL; 13655dfecf96Smrg break; 13665dfecf96Smrg default: 13675dfecf96Smrg fatal_builtin_object_error(builtin, number, NOT_A_NUMBER); 13685dfecf96Smrg /*NOTREACHED*/ 13695dfecf96Smrg result = NIL; 13705dfecf96Smrg } 13715dfecf96Smrg 13725dfecf96Smrg return (result); 13735dfecf96Smrg} 13745dfecf96Smrg 13755dfecf96Smrgstatic LispObj * 13765dfecf96SmrgLispDivide(LispBuiltin *builtin, int fun, int flo) 13775dfecf96Smrg{ 13785dfecf96Smrg n_number num; 13795dfecf96Smrg LispObj *number, *divisor; 13805dfecf96Smrg 13815dfecf96Smrg divisor = ARGUMENT(1); 13825dfecf96Smrg number = ARGUMENT(0); 13835dfecf96Smrg 13845dfecf96Smrg RETURN_COUNT = 1; 13855dfecf96Smrg 13865dfecf96Smrg if (cmp_real_object(&zero, number) == 0) { 13875dfecf96Smrg if (divisor != NIL) { 13885dfecf96Smrg CHECK_REAL(divisor); 13895dfecf96Smrg } 13905dfecf96Smrg 13915dfecf96Smrg return (RETURN(0) = obj_zero); 13925dfecf96Smrg } 13935dfecf96Smrg 13945dfecf96Smrg if (divisor == UNSPEC) 13955dfecf96Smrg divisor = obj_one; 13965dfecf96Smrg 13975dfecf96Smrg set_number_object(&num, number); 13985dfecf96Smrg if (num.complex) 13995dfecf96Smrg fatal_builtin_object_error(builtin, divisor, NOT_A_REAL_NUMBER); 14005dfecf96Smrg 14015dfecf96Smrg divide_number_object(&num, divisor, fun, flo); 14025dfecf96Smrg RETURN(0) = make_real_object(&(num.imag)); 14035dfecf96Smrg 14045dfecf96Smrg return (make_real_object(&(num.real))); 14055dfecf96Smrg} 14065dfecf96Smrg 14075dfecf96SmrgLispObj * 14085dfecf96SmrgLisp_Ceiling(LispBuiltin *builtin) 14095dfecf96Smrg/* 14105dfecf96Smrg ceiling number &optional divisor 14115dfecf96Smrg */ 14125dfecf96Smrg{ 14135dfecf96Smrg return (LispDivide(builtin, NDIVIDE_CEIL, 0)); 14145dfecf96Smrg} 14155dfecf96Smrg 14165dfecf96SmrgLispObj * 14175dfecf96SmrgLisp_Fceiling(LispBuiltin *builtin) 14185dfecf96Smrg/* 14195dfecf96Smrg fceiling number &optional divisor 14205dfecf96Smrg */ 14215dfecf96Smrg{ 14225dfecf96Smrg return (LispDivide(builtin, NDIVIDE_CEIL, 1)); 14235dfecf96Smrg} 14245dfecf96Smrg 14255dfecf96SmrgLispObj * 14265dfecf96SmrgLisp_Floor(LispBuiltin *builtin) 14275dfecf96Smrg/* 14285dfecf96Smrg floor number &optional divisor 14295dfecf96Smrg */ 14305dfecf96Smrg{ 14315dfecf96Smrg return (LispDivide(builtin, NDIVIDE_FLOOR, 0)); 14325dfecf96Smrg} 14335dfecf96Smrg 14345dfecf96SmrgLispObj * 14355dfecf96SmrgLisp_Ffloor(LispBuiltin *builtin) 14365dfecf96Smrg/* 14375dfecf96Smrg ffloor number &optional divisor 14385dfecf96Smrg */ 14395dfecf96Smrg{ 14405dfecf96Smrg return (LispDivide(builtin, NDIVIDE_FLOOR, 1)); 14415dfecf96Smrg} 14425dfecf96Smrg 14435dfecf96SmrgLispObj * 14445dfecf96SmrgLisp_Round(LispBuiltin *builtin) 14455dfecf96Smrg/* 14465dfecf96Smrg round number &optional divisor 14475dfecf96Smrg */ 14485dfecf96Smrg{ 14495dfecf96Smrg return (LispDivide(builtin, NDIVIDE_ROUND, 0)); 14505dfecf96Smrg} 14515dfecf96Smrg 14525dfecf96SmrgLispObj * 14535dfecf96SmrgLisp_Fround(LispBuiltin *builtin) 14545dfecf96Smrg/* 14555dfecf96Smrg fround number &optional divisor 14565dfecf96Smrg */ 14575dfecf96Smrg{ 14585dfecf96Smrg return (LispDivide(builtin, NDIVIDE_ROUND, 1)); 14595dfecf96Smrg} 14605dfecf96Smrg 14615dfecf96SmrgLispObj * 14625dfecf96SmrgLisp_Truncate(LispBuiltin *builtin) 14635dfecf96Smrg/* 14645dfecf96Smrg truncate number &optional divisor 14655dfecf96Smrg */ 14665dfecf96Smrg{ 14675dfecf96Smrg return (LispDivide(builtin, NDIVIDE_TRUNC, 0)); 14685dfecf96Smrg} 14695dfecf96Smrg 14705dfecf96SmrgLispObj * 14715dfecf96SmrgLisp_Ftruncate(LispBuiltin *builtin) 14725dfecf96Smrg/* 14735dfecf96Smrg ftruncate number &optional divisor 14745dfecf96Smrg */ 14755dfecf96Smrg{ 14765dfecf96Smrg return (LispDivide(builtin, NDIVIDE_TRUNC, 1)); 14775dfecf96Smrg} 1478