1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
/*
* Copyright 1995,96 Thierry Bousch
* Licensed under the Gnu Public License, Version 2
*
* $Id: Mint.c,v 2.5 1996/08/18 08:49:14 bousch Exp $
*
* The "int" type; not very useful in itself because C has it already,
* but very handy for debugging all the other parts of SAML.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "saml.h"
#include "saml-errno.h"
#include "mnode.h"
#include "builtin.h"
typedef struct {
struct mnode_header hdr;
int n; /* the number */
} mint_mnode;
s_mnode* mint_ibuild (int);
static s_mnode* mint_build (const char*);
static gr_string* mint_stringify (mint_mnode*);
static s_mnode* mint_add (mint_mnode*, mint_mnode*);
static s_mnode* mint_sub (mint_mnode*, mint_mnode*);
static s_mnode* mint_mul (mint_mnode*, mint_mnode*);
static s_mnode* mint_div (mint_mnode*, mint_mnode*);
static int mint_notzero (mint_mnode*);
static int mint_isneg (mint_mnode*);
static int mint_differ (mint_mnode*, mint_mnode*);
static int mint_lessthan (mint_mnode*, mint_mnode*);
static s_mnode* mint_zero (mint_mnode*);
static s_mnode* mint_negate (mint_mnode*);
static s_mnode* mint_one (mint_mnode*);
static s_mnode* mint_sqrt (mint_mnode*);
static unsafe_s_mtype MathType_Mint = {
"int",
free, mint_build, mint_stringify,
NULL, NULL,
mint_add, mint_sub, mint_mul, mint_div, mn_euclidean_gcd,
mint_notzero, mint_isneg, NULL, mint_differ, mint_lessthan,
mint_zero, mint_negate, mint_one, NULL, mint_sqrt
};
void init_MathType_Mint (void)
{
register_mtype (ST_MINT, &MathType_Mint);
}
inline s_mnode* mint_ibuild (int x)
{
s_mnode* mn = __mnalloc(ST_MINT,sizeof(mint_mnode));
((mint_mnode*)mn)->n = x;
return mn;
}
static s_mnode* mint_build (const char *string)
{
return mint_ibuild(strtol(string, NULL, 10));
}
static s_mnode* mint_zero (mint_mnode* unused)
{
return mint_ibuild(0);
}
static s_mnode* mint_one (mint_mnode* unused)
{
return mint_ibuild(1);
}
static gr_string* mint_stringify (mint_mnode* x)
{
gr_string* grs = new_gr_string(30);
sprintf(grs->s, "%d", x->n);
grs->len = strlen(grs->s);
return grs;
}
static s_mnode* mint_add (mint_mnode* x1, mint_mnode* x2)
{
int x = x1->n + x2->n;
return mint_ibuild(x);
}
static s_mnode* mint_sub (mint_mnode* x1, mint_mnode* x2)
{
int x = x1->n - x2->n;
return mint_ibuild(x);
}
static s_mnode* mint_mul (mint_mnode* x1, mint_mnode* x2)
{
int x = x1->n * x2->n;
return mint_ibuild(x);
}
static s_mnode* mint_div (mint_mnode* x1, mint_mnode* x2)
{
int n1 = x1->n;
int n2 = x2->n;
if (n2 != 0)
return mint_ibuild(n1/n2);
else return mnode_error(SE_DIVZERO, "mint_div");
}
static int mint_notzero (mint_mnode* mn)
{
return (mn->n != 0);
}
static int mint_isneg (mint_mnode* mn)
{
return (mn->n < 0);
}
static int mint_differ (mint_mnode* x1, mint_mnode* x2)
{
return (x1->n != x2->n);
}
static int mint_lessthan (mint_mnode* x1, mint_mnode* x2)
{
return (x1->n < x2->n);
}
static s_mnode* mint_negate (mint_mnode* mn)
{
int x = mn->n;
return mint_ibuild(-x);
}
static s_mnode* mint_sqrt (mint_mnode* mn)
{
int n = mn->n;
unsigned int a, b;
if (n < 0)
return mnode_error(SE_OODOMAIN, "mint_sqrt");
/*
* The following algorithm appears as an exercise in Bressoud,
* "Factorization and Primality testing". It is probably very classic;
* does someone have the original reference?
*/
a = n;
b = (a+1)/2;
while (a > b) {
a = b;
b = (b + n/b) / 2;
}
return mint_ibuild(a);
}
|