source: git/Singular/longrat0.cc @ 18dd47

spielwiese
Last change on this file since 18dd47 was 4c001a, checked in by Olaf Bachmann <obachman@…>, 27 years ago
Merged fixes from 1-0-0 release git-svn-id: file:///usr/local/Singular/svn/trunk@358 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 4.6 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: longrat0.cc,v 1.5 1997-06-04 19:45:21 obachman Exp $ */
5/*
6* ABSTRACT -
7* IO for long rational numbers (Hubert Grassmann)
8*/
9
10#include <stdio.h>
11#include <string.h>
12#include "mod2.h"
13#include "tok.h"
14#include "mmemory.h"
15#include "febase.h"
16#include "longrat.h"
17
18#ifdef HAVE_GMP
19
20#define SR_HDL(A) ((long)(A))
21#define SR_INT    1
22#define INT_TO_SR(INT)  ((number) (((long)INT << 2) + SR_INT))
23#define SR_TO_INT(SR)   (((long)SR) >> 2)
24
25
26/*2
27* extracts a long integer from s, returns the rest
28*/
29char * nlEatLong(char *s, MP_INT *i)
30{
31  char * start=s;
32
33  while (*s >= '0' && *s <= '9') s++;
34  if (*s=='\0')
35  {
36    mpz_set_str(i,start,10);
37  }
38  else
39  {
40    char c=*s;
41    *s='\0';
42    mpz_set_str(i,start,10);
43    *s=c;
44  }
45  return s;
46}
47
48/*2
49* extracts the number a from s, returns the rest
50*/
51char * nlRead (char *s, number *a)
52{
53  if (*s<'0' || *s>'9')
54  {
55    *a = nlInit(1);
56    return s;
57  }
58  *a=(number)Alloc(sizeof(rnumber));
59  {
60    (*a)->s = 3;
61#ifdef LDEBUG
62    (*a)->debug=123456;
63#endif
64    MP_INT *z=&((*a)->z);
65    MP_INT *n=&((*a)->n);
66    mpz_init(z);
67    s = nlEatLong(s, z);
68    if (*s == '/')
69    {
70      mpz_init(n);
71      (*a)->s = 0;
72      s++;
73      s = nlEatLong(s, n);
74      if (mpz_cmp_si(n,(long)0)==0)
75      {
76        WerrorS("Zero Denominator");
77        mpz_clear(n);
78        (*a)->s = 3;
79      }
80      else if (mpz_cmp_si(n,(long)1)==0)
81      {
82        mpz_clear(n);
83        (*a)->s=3;
84      }
85    }
86    if (mpz_cmp_si(z,(long)0)==0)
87    {
88      *a=INT_TO_SR(0);
89    }
90    else
91    if ((*a)->s==3)
92    {
93      int ui=(int)mpz_get_si(&(*a)->z);
94      if ((((ui<<3)>>3)==ui)
95      && (mpz_cmp_si(&(*a)->z,(long)ui)==0))
96      {
97        mpz_clear(&(*a)->z);
98        Free((ADDRESS)(*a),sizeof(rnumber));
99        (*a)=INT_TO_SR(ui);
100      }
101    }
102    else
103      nlNormalize(*a);
104  }
105  return s;
106}
107
108/*2
109* write a rational number
110*/
111void nlWrite (number &a)
112{
113  char *s,*z;
114  if (SR_HDL(a) & SR_INT)
115  {
116    StringAppend("%d",SR_TO_INT(a));
117  }
118#ifdef TEST
119  else if (a==NULL)
120  {
121    StringAppend("o");
122  }
123#endif
124  else
125  {
126    if (a->s==0)
127    {
128      nlNormalize(a);
129      nlWrite(a);
130      return;
131    }
132    int l=mpz_sizeinbase(&a->z,10);
133    if (a->s<2) l=max(l,mpz_sizeinbase(&a->n,10));
134    l+=2;
135    s=(char*)Alloc(l);
136    z=mpz_get_str(s,10,&a->z);
137    StringAppend(z);
138    if (a->s!=3)
139    {
140      StringAppend("/");
141      z=mpz_get_str(s,10,&a->n);
142      StringAppend(z);
143    }
144    Free((ADDRESS)s,l);
145  }
146}
147
148#else
149#define NLLENGTH(a) ((int)(*(a)&0X7FFF))
150#define NUM_BASIS 10000
151#define NLISRAT(a)   ((a)->s)
152
153/*3
154* extracts a long integer from s, returns the rest
155*/
156static char * nlEatLong(char *s, number *i)
157{
158  number j, k, ten, n;
159  j = nlInit(0);
160  ten = nlInit(10);
161  while (*s >= '0' && *s <= '9')
162  {
163    k = nlMult(j, ten);
164    nlDelete(&j);
165    j = nlInit((int)*s-(int)'0');
166    s++;
167    n = nlAdd(j, k);
168    nlDelete(&j);
169    nlDelete(&k);
170    j = n;
171  }
172  nlDelete(&ten);
173  *i = j;
174  return s;
175}
176
177/*2
178* extracts the numberio a from s, returns the rest
179*/
180char * nlRead (char *s, number *a)
181{
182  number z, n;
183  BOOLEAN neg = (*s == '-');
184
185  if (*s == '+' || *s == '-')
186    s++;
187  if (*s<'0' || *s>'9')
188  {
189    if (neg)
190      *a = nlInit(-1);
191    else
192      *a = nlInit(1);
193    return s;
194  }
195  s = nlEatLong(s, &z);
196  if (neg)
197    nlNeg(z);
198  *a = z;
199  if (*s == '/')
200  {
201    s++;
202    s = nlEatLong(s, &n);
203    if (nlIsZero(n))
204    {
205      WerrorS("Zero Denominator");
206      nlDelete(&n);
207      nlDelete(a);
208      return s;
209    }
210    if (nlIsOne(n))
211      nlDelete(&n);
212    else
213    {
214      *a = nlDiv(z, n);
215      nlNormalize(*a);
216    }
217  }
218  return s;
219}
220
221/*3
222* write long integer, assume n!=NULL
223*/
224static void nlWriteLong(lint n)
225{
226  char save;
227  char *lonstr, *str1;
228  int i, k, j;
229  lint a;
230  int16 al, w;
231  al = NLLENGTH(n);
232  k = al+1;
233  i = k*sizeof(int16);
234  a = (lint)Alloc(i);
235  memcpy(a, n, i);
236  j = k*5*sizeof(char);
237  lonstr = (char *)Alloc(j);
238  str1 = lonstr+(k*5-1);
239  *str1 = '\0';
240  do
241  {
242    nlDivMod(a, al, NUM_BASIS, &w);
243    save = *str1;
244    str1 -= 4;
245    sprintf(str1, "%04u", w);
246    str1[4] = save;
247    if (a[al]==0)
248      al--;
249  } while (al!=0);
250  Free((ADDRESS)a,i);
251  while (*str1 == '0') str1++;
252  StringAppend(str1);
253  Free((ADDRESS)lonstr, j);
254}
255
256/*2
257* write a number
258*/
259void nlWrite (number &a)
260{
261  if (nlIsZero(a))
262  {
263    StringAppend("0");
264    return;
265  }
266  if (!nlGreaterZero(a))
267  {
268    StringAppend("-");
269  }
270  if (a->s<0)
271    nlNormalize(a);
272  nlWriteLong(a->z);
273  if (NLISRAT(a))
274  {
275    StringAppend("/");
276    nlWriteLong(a->n);
277  }
278}
279#endif
280
Note: See TracBrowser for help on using the repository browser.