|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T b
Length: 7329 (0x1ca1)
Types: TextFile
Names: »bignum.h«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/gnu-31mar87/scheme/microcode/bignum.h«
/* Hey EMACS, this is -*- C -*- code! */
/****************************************************************
* *
* Copyright (c) 1984 *
* Massachusetts Institute of Technology *
* *
* This material was developed by the Scheme project at the *
* Massachusetts Institute of Technology, Department of *
* Electrical Engineering and Computer Science. Permission to *
* copy this software, to redistribute it, and to use it for any *
* purpose is granted, subject to the following restrictions and *
* understandings. *
* *
* 1. Any copy made of this software must include this copyright *
* notice in full. *
* *
* 2. Users of this software agree to make their best efforts (a)*
* to return to the MIT Scheme project any improvements or *
* extensions that they make, so that these may be included in *
* future releases; and (b) to inform MIT of noteworthy uses of *
* this software. *
* *
* 3. All materials developed as a consequence of the use of *
* this software shall duly acknowledge such use, in accordance *
* with the usual standards of acknowledging credit in academic *
* research. *
* *
* 4. MIT has made no warrantee or representation that the *
* operation of this software will be error-free, and MIT is *
* under no obligation to provide any services, by way of *
* maintenance, update, or otherwise. *
* *
* 5. In conjunction with products arising from the use of this *
* material, there shall be no use of the name of the *
* Massachusetts Institute of Technology nor of any adaptation *
* thereof in any advertising, promotional, or sales literature *
* without prior written consent from MIT in each case. *
* *
****************************************************************/
\f
/* Head file for bignums. This is shared by bignum.c and generic.c. */
#ifdef ENABLE_DEBUGGING_TOOLS
#define Debug_Test(Res) \
{ Pointer R = Make_Pointer(TC_BIG_FIXNUM, Res); \
if (Nth_Vector_Loc(R, Vector_Length(R)) != (Free-1)) \
{ printf("\nResult=%x => %x %x %x, Length=%d, Free=%x\n", \
R, Fast_Vector_Ref(R, 0), \
Fast_Vector_Ref(R, 1), Fast_Vector_Ref(R, 2), \
Vector_Length(R), Free); \
Microcode_Termination(TERM_EXIT); \
} \
}
#else
#define Debug_Test(Res) { }
#endif
\f
#define POSITIVE 1
#define NEGATIVE 0
/* The representation of a BIGNUM is machine dependent. For a VAX-11
* it is as follows:
*/
#ifdef pdp10
typedef unsigned int bigdigit;
typedef long bigdouble;
#define SHIFT 16
#define factor 1
#else
#if ((USHORT_SIZE * 2) <= ULONG_SIZE)
#define bigdigit unsigned short
#define bigdouble long /* Should be unsigned */
#define SHIFT (CHAR_SIZE*sizeof(bigdigit))
#define factor (sizeof(Pointer)/sizeof(bigdigit))
#else
#if ((CHAR_SIZE * 2) <= ULONG_SIZE)
#define bigdigit unsigned char
#define bigdouble long /* Should be unsigned */
#define SHIFT CHAR_SIZE
#define factor (sizeof(Pointer)/sizeof(bigdigit))
#else
#include "Cannot compile bignums. All types too large. See bignum.h"
#endif
#endif
#endif
#define DELTA \
((sizeof(bigdouble)-sizeof(bigdigit))*CHAR_SIZE)
#define SIGN(Bignum) (Bignum[factor])
#define LEN(Bignum) (Bignum[factor+1])
#define Bignum_Bottom(Bignum) (&(Bignum)[factor+2])
#define Bignum_Top(Bignum) (&(Bignum)[factor+1+LEN(Bignum)])
#define Align(ndigits) ((((ndigits) + factor + 1) / factor) + 1)
/* For temporary bignums */
#define TEMP_SIZE Align(4)
/* Macros for making BIGNUM headers */
#define Make_Header(l) Make_Non_Pointer(TC_MANIFEST_NM_VECTOR,(l-1))
#define Prepare_Header(Bignum,Length,Sign) \
{ *((Pointer *) Bignum) = Make_Header(Align(Length)); \
SIGN(Bignum) = Sign; \
LEN(Bignum) = Length; \
}
\f
/* Predicates coded as macros for determining the sign of BIGNUM's */
#define POS_BIGNUM(Bignum) (SIGN(Bignum) == POSITIVE)
#define NEG_BIGNUM(Bignum) (SIGN(Bignum) == NEGATIVE)
#define ZERO_BIGNUM(Bignum) (LEN(Bignum) == 0)
#define NON_ZERO_BIGNUM(Bignum) (LEN(Bignum) != 0)
/* Coerces a C pointer to point to BIGNUM digits */
#define BIGNUM(ptr) ((bigdigit *) ptr)
/* Macros for manipulating long BIGNUM digits */
#define RADIX (1<<SHIFT)
#define MAX_DIGIT_SIZE (RADIX-1)
#define CARRY_MASK (MAX_DIGIT_SIZE<<SHIFT)
#define DIGIT_MASK MAX_DIGIT_SIZE
#define DIV_MASK ((1<<DELTA)-1)
#define Get_Carry(lw) (((lw & CARRY_MASK) >> SHIFT) & DIGIT_MASK)
#define Get_Digit(lw) (lw & DIGIT_MASK)
#define Mul_Radix(sw) (sw << SHIFT)
#define Div_Radix(lw) ((lw >> SHIFT) & DIV_MASK)
#define Rem_Radix(lw) (lw & DIGIT_MASK)
/* Length of the BIGNUM that contains the largest FIXNUM */
#define FIXNUM_LENGTH_AS_BIGNUM ((FIXNUM_LENGTH+(SHIFT-1))/SHIFT)
#define C_INTEGER_LENGTH_AS_BIGNUM ((POINTER_LENGTH+(SHIFT-1))/SHIFT)
\f
/* Cases returned by the comparison function big_compare() */
#define EQUAL 0
#define ONE_BIGGER 1
#define TWO_BIGGER 2
/* Categorize_Sign() takes two bignum's and classify them according
* to four possible cases, depending on each's sign. Depends on
* definition of POSITIVE and NEGATIVE, earlier!!!
*/
#define Categorize_Sign(ARG1, ARG2) ((SIGN(ARG1) << 1) | SIGN(ARG2))
#define BOTH_NEGATIVE 0
#define ARG1_NEGATIVE 1
#define ARG2_NEGATIVE 2
#define BOTH_POSITIVE 3
#define Sign_Error(proc) \
{ printf(proc); \
printf(" -- Sign Determination Error\n"); \
printf("Possibly Uncanonicalized Bignum\n"); \
return ERR_UNDEFINED_PRIMITIVE; \
}
#define Fetch_Bignum(big) BIGNUM(Get_Pointer(big))
#define Bignum_Operation(Object, Result) \
Result = (Object); \
Free = Nth_Vector_Loc(Result, Vector_Length(Result)+1); \
Result = Big_To_Fix(Result);
\f
#define Divide_Bignum_Operation(Object, Result) \
{ Pointer *End_Of_First, *First, *Second, *Orig_Free=Free; \
Result = (Object); \
First = Get_Pointer(Vector_Ref(Result, CONS_CAR)); \
Second = Get_Pointer(Vector_Ref(Result, CONS_CDR)); \
End_Of_First = First+1+Get_Integer(First[0]); \
if (End_Of_First != Second) \
{ *End_Of_First = \
Make_Non_Pointer(TC_MANIFEST_NM_VECTOR, (Second-End_Of_First)-1); \
if (Bignum_Debug) printf("\nGap=0x%x\n", (Second-End_Of_First)-1); \
} \
Free = Second+1+Get_Integer(Second[0]); \
Vector_Set(Result,CONS_CAR,Big_To_Fix(Vector_Ref(Result,CONS_CAR))); \
Vector_Set(Result,CONS_CDR,Big_To_Fix(Vector_Ref(Result,CONS_CDR))); \
}