source: git/libpolys/coeffs/numbers.cc @ 0b0298

spielwiese
Last change on this file since 0b0298 was 0b0298, checked in by Hans Schoenemann <hannes@…>, 18 months ago
ndAnn prints a warning
  • Property mode set to 100644
File size: 18.1 KB
Line 
1/*****************************************
2*  Computer Algebra System SINGULAR      *
3*****************************************/
4
5/*
6* ABSTRACT: interface to coefficient aritmetics
7*/
8
9#include <string.h>
10#include <stdlib.h>
11
12#include "misc/auxiliary.h"
13#include "misc/mylimits.h"
14#include "factory/factory.h"
15
16#include "reporter/reporter.h"
17
18#include "coeffs/coeffs.h"
19#include "coeffs/numbers.h"
20
21#include "coeffs/longrat.h"
22#include "coeffs/modulop.h"
23#include "coeffs/gnumpfl.h"
24#include "coeffs/gnumpc.h"
25#include "coeffs/ffields.h"
26#include "coeffs/shortfl.h"
27#include "coeffs/ntupel.h"
28#include "coeffs/flintcf_Qrat.h"
29
30#ifdef HAVE_RINGS
31#include "coeffs/rmodulo2m.h"
32#include "coeffs/rmodulon.h"
33#include "coeffs/rintegers.h"
34#endif
35
36#ifdef HAVE_POLYEXTENSIONS
37#include "polys/ext_fields/algext.h"
38#include "polys/ext_fields/transext.h"
39#endif
40
41
42//static int characteristic = 0;
43//extern int IsPrime(int p);
44
45VAR n_Procs_s *cf_root=NULL;
46
47void   nNew(number* d) { *d=NULL; }
48
49static void   ndDelete(number* d, const coeffs) { *d=NULL; }
50static number ndAnn(number, const coeffs cf) { WarnS("cfAnn undefined"); return n_Init(0,cf); }
51static char* ndCoeffString(const coeffs r)
52{
53  return omStrDup(r->cfCoeffName(r));
54}
55static void ndCoeffWrite(const coeffs r,BOOLEAN)
56{
57  PrintS(r->cfCoeffName(r));
58}
59static char* ndCoeffName(const coeffs r)
60{
61  STATIC_VAR char s[20];
62  snprintf(s,11,"Coeffs(%d)",r->type);
63  return s;
64}
65static void   ndInpMult(number &a, number b, const coeffs r)
66{
67  number n=r->cfMult(a,b,r);
68  r->cfDelete(&a,r);
69  a=n;
70}
71void ndInpAdd(number &a, number b, const coeffs r)
72{
73  number n=r->cfAdd(a,b,r);
74  r->cfDelete(&a,r);
75  a=n;
76}
77
78static void ndPower(number a, int i, number * res, const coeffs r)
79{
80  if (i==0)
81  {
82    *res = r->cfInit(1, r);
83  }
84  else if (i==1)
85  {
86    *res = r->cfCopy(a, r);
87  }
88  else if (i==2)
89  {
90    *res = r->cfMult(a, a, r);
91  }
92  else if (i<0)
93  {
94    number b = r->cfInvers(a, r);
95    ndPower(b, -i, res, r);
96    r->cfDelete(&b, r);
97  }
98  else
99  {
100    ndPower(a, i/2, res, r);
101    r->cfInpMult(*res, *res, r);
102    if (i&1)
103    {
104      r->cfInpMult(*res, a, r);
105    }
106  }
107}
108static number ndInvers(number a, const coeffs r)
109{
110  number one=r->cfInit(1,r);
111  number res=r->cfDiv(one,a,r);
112  r->cfDelete(&one,r);
113  return res;
114}
115static number ndInvers_Ring(number a, const coeffs r)
116{
117  if (!r->cfIsUnit(a,r)) Print("ndInvers_Ring used with non-unit\n");
118  number one=r->cfInit(1,r);
119  number res=r->cfDiv(one,a,r);
120  r->cfDelete(&one,r);
121  return res;
122}
123
124static BOOLEAN ndIsUnit_Ring(number a, const coeffs r)
125{ return r->cfIsOne(a,r)|| r->cfIsMOne(a,r); }
126static BOOLEAN ndIsUnit_Field(number a, const coeffs r)
127{ return !r->cfIsZero(a,r); }
128static number ndGetUnit_Ring(number, const coeffs r)
129{ return r->cfInit(1,r); }
130static number ndRandom(siRandProc p, number, number, const coeffs cf)
131{ return cf->cfInit(p(),cf); }
132static number ndEucNorm(number a, const coeffs cf)
133{ return cf->cfInit(cf->cfSize(a,cf),cf); }
134#ifdef LDEBUG
135// static void   nDBDummy1(number* d,char *, int) { *d=NULL; }
136static BOOLEAN ndDBTest(number, const char *, const int, const coeffs){ return TRUE; }
137#endif
138
139static number ndFarey(number,number,const coeffs r)
140{
141  Werror("farey not implemented for %s (c=%d)",r->cfCoeffName(r),getCoeffType(r));
142  return NULL;
143}
144static number ndXExtGcd(number, number, number *, number *, number *, number *, const coeffs r)
145{
146  Werror("XExtGcd not implemented for %s (c=%d)",r->cfCoeffName(r),getCoeffType(r));
147  return NULL;
148}
149static number ndChineseRemainder(number *,number *,int,BOOLEAN,CFArray&,const coeffs r)
150{
151  Werror("ChineseRemainder not implemented for %s (c=%d)",r->cfCoeffName(r),getCoeffType(r));
152  return r->cfInit(0,r);
153}
154number ndReadFd( const ssiInfo *, const coeffs r)
155{
156  Warn("ReadFd not implemented for %s (c=%d)",r->cfCoeffName(r),getCoeffType(r));
157  return NULL;
158}
159
160static void ndWriteFd(number, const ssiInfo *, const coeffs r)
161{
162  Warn("WriteFd not implemented for %s (c=%d)",r->cfCoeffName(r),getCoeffType(r));
163}
164
165static int ndParDeg(number n, const coeffs r)
166{
167  return (-r->cfIsZero(n,r));
168}
169
170static number ndParameter(const int, const coeffs r)
171{
172  return r->cfInit(1,r);
173}
174
175BOOLEAN n_IsZeroDivisor( number a, const coeffs r)
176{
177  BOOLEAN ret = n_IsZero(a, r);
178  int c = n_GetChar(r);
179  if (ret || (c==0) || (r->is_field))
180    return ret; /*n_IsZero(a, r)*/
181  number ch = n_Init( c, r );
182  number g = n_Gcd( ch, a, r );
183  ret = !n_IsOne (g, r);
184  n_Delete(&ch, r);
185  n_Delete(&g, r);
186  return ret;
187}
188
189void   ndNormalize(number&, const coeffs) { }
190static number ndReturn0(number, const coeffs r)        { return r->cfInit(0,r); }
191number ndGcd(number, number, const coeffs r)    { return r->cfInit(1,r); }
192static number ndIntMod(number a, number b, const coeffs R)
193{
194  if (R->is_field)
195    return R->cfInit(0,R);
196  else // implementation for a non-field:
197  {
198    number d=n_Div(a,b,R);
199    number p=n_Mult(b,d,R);
200    number r=n_Sub(a,p,R);
201    n_Delete(&p,R);
202    n_Delete(&d,R);
203    return r;
204  }
205}
206static number ndGetDenom(number &, const coeffs r)     { return r->cfInit(1,r); }
207static number ndGetNumerator(number &a,const coeffs r) { return r->cfCopy(a,r); }
208static int    ndSize(number a, const coeffs r)         { return (int)r->cfIsZero(a,r)==FALSE; }
209
210static void ndClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs r)
211{
212  assume(r != NULL);
213
214  // no fractions
215  assume(!(  nCoeff_is_Q(r) ));
216  // all coeffs are given by integers!!!
217
218  numberCollectionEnumerator.Reset();
219
220  if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial?
221  {
222    c = n_Init(1, r);
223    return;
224  }
225
226  number &curr = numberCollectionEnumerator.Current();
227
228#ifdef HAVE_RINGS
229  /// TODO: move to a separate implementation
230  if (nCoeff_is_Ring(r))
231  {
232    if (nCoeff_has_Units(r))
233    {
234      c = n_GetUnit(curr, r);
235
236      if (!n_IsOne(c, r))
237      {
238        number inv = n_Invers(c, r);
239
240        n_InpMult(curr, inv, r);
241
242        while( numberCollectionEnumerator.MoveNext() )
243        {
244          number &n = numberCollectionEnumerator.Current();
245          n_Normalize(n, r); // ?
246          n_InpMult(n, inv, r); // TODO: either this or directly divide!!!?
247        }
248
249        n_Delete(&inv, r);
250      }
251    } else c = n_Init(1, r);
252
253    return;
254  }
255#endif
256
257  assume(!nCoeff_is_Ring(r));
258  assume(nCoeff_is_Zp(r) || nCoeff_is_numeric(r) || nCoeff_is_GF(r) || nCoeff_is_Zp_a(r) || nCoeff_is_Q_algext(r));
259
260  n_Normalize(curr, r); // Q: good/bad/ugly??
261
262  if (!n_IsOne(curr, r))
263  {
264    number t = curr; // takes over the curr! note: not a reference!!!
265
266    curr = n_Init(1, r); // ???
267
268    number inv = n_Invers(t, r);
269
270    while( numberCollectionEnumerator.MoveNext() )
271    {
272      number &n = numberCollectionEnumerator.Current();
273      n_InpMult(n, inv, r); // TODO: either this or directly divide!!!?
274//      n_Normalize(n, r); // ?
275    }
276
277    n_Delete(&inv, r);
278
279    c = t;
280  } else
281    c = n_Copy(curr, r); // c == 1 and nothing else to do...
282}
283
284static void ndClearDenominators(ICoeffsEnumerator& /*numberCollectionEnumerator*/, number& d, const coeffs r)
285{
286  assume( r != NULL );
287  assume( !(nCoeff_is_Q(r) || nCoeff_is_transExt(r) || nCoeff_is_algExt(r)) );
288  assume( nCoeff_is_Ring(r) || nCoeff_is_Zp(r) || nCoeff_is_numeric(r) || nCoeff_is_GF(r) );
289
290  d = n_Init(1, r);
291}
292
293number ndCopyMap(number a, const coeffs aRing, const coeffs r)
294{
295  // aRing and r need not be the same, but must be the same representation
296  assume(aRing->rep==r->rep);
297  if ( nCoeff_has_simple_Alloc(r) && nCoeff_has_simple_Alloc(aRing) )
298    return a;
299  else
300    return r->cfCopy(a, r);
301}
302
303static void ndKillChar(coeffs) {}
304static void ndSetChar(const coeffs) {}
305
306static number ndCopy(number a, const coeffs) { return a; }
307number nd_Copy(number a, const coeffs r) { return r->cfCopy(a, r); }
308
309#ifdef HAVE_RINGS
310static BOOLEAN ndDivBy(number, number, const coeffs) { return TRUE; } // assume a,b !=0
311static int ndDivComp(number, number, const coeffs) { return 2; }
312static number  ndExtGcd (number, number, number *, number *, const coeffs r) { return r->cfInit(1,r); }
313#endif
314
315CanonicalForm ndConvSingNFactoryN( number, BOOLEAN /*setChar*/, const coeffs)
316{
317  CanonicalForm term(0);
318  WerrorS("no conversion to factory");
319  return term;
320}
321
322static number ndConvFactoryNSingN( const CanonicalForm, const coeffs)
323{
324  WerrorS("no conversion from factory");
325  return NULL;
326}
327
328/**< [in, out] a bigint number >= 0  */
329/**< [out] the GMP equivalent    */
330/// Converts a non-negative bigint number into a GMP number.
331static void ndMPZ(mpz_t result, number &n, const coeffs r)
332{
333  mpz_init_set_si( result, r->cfInt(n, r) );
334}
335
336static number ndInitMPZ(mpz_t m, const coeffs r)
337{
338  return r->cfInit( mpz_get_si(m), r);
339}
340
341static const char *ndRead(const char * s, number *, const coeffs r)
342{
343  Werror("cfRead is undefined for %s",nCoeffString(r));
344  return s;
345}
346static nMapFunc ndSetMap(const coeffs src, const coeffs dst)
347{
348  if (src==dst) return ndCopyMap;
349  Werror("cfSetMap is undefined for %s",nCoeffString(dst));
350  return NULL;
351}
352
353static BOOLEAN ndCoeffIsEqual(const coeffs r, n_coeffType n, void *)
354{
355  /* test, if r is an instance of nInitCoeffs(n,parameter) */
356  /* if parameter is not needed */
357  return (n==r->type);
358}
359
360number ndQuotRem (number a, number b, number * r, const coeffs R)
361{
362  // implementation for a field: r: 0, result: n_Div
363  if(R->is_field)
364  {
365    *r=n_Init(0,R);
366    return n_Div(a,b,R);
367  }
368  else
369  // implementation for a non-field:
370  {
371    number d=n_Div(a,b,R);
372    number p=n_Mult(b,d,R);
373    *r=n_Sub(a,p,R);
374    n_Delete(&p,R);
375    return d;
376  }
377}
378STATIC_VAR n_coeffType nLastCoeffs=n_CF;
379VAR cfInitCharProc nInitCharTableDefault[]=
380{ NULL,        /*n_unknown */
381 npInitChar,   /* n_Zp */
382 nlInitChar,   /* n_Q */
383 nrInitChar,   /* n_R */
384 nfInitChar,   /* n_GF */
385 ngfInitChar,  /* n_long_R */
386 #ifdef HAVE_POLYEXTENSIONS
387 n2pInitChar, /* n_polyExt */
388 naInitChar,  /* n_algExt */
389 ntInitChar,  /* n_transExt */
390 #else
391 NULL,        /* n_polyExt */
392 NULL,        /* n_algExt */
393 NULL,        /* n_transExt */
394 #endif
395 ngcInitChar,  /* n_long_C */
396 nnInitChar,   /* n_nTupel */
397 #ifdef HAVE_RINGS
398 nrzInitChar,  /* n_Z */
399 nrnInitChar,  /* n_Zn */
400 nrnInitChar,  /* n_Znm */
401 nr2mInitChar, /* n_Z2m */
402 #else
403 NULL,         /* n_Z */
404 NULL,         /* n_Zn */
405 NULL,         /* n_Znm */
406 NULL,         /* n_Z2m */
407 #endif
408 flintQrat_InitChar, /* n_FlintQrat */
409 NULL         /* n_CF */
410};
411
412STATIC_VAR cfInitCharProc *nInitCharTable=nInitCharTableDefault;
413/*2
414* init operations for coeffs r
415*/
416coeffs nInitChar(n_coeffType t, void * parameter)
417{
418  n_Procs_s *n=cf_root;
419
420  while((n!=NULL) && (n->nCoeffIsEqual!=NULL) && (!n->nCoeffIsEqual(n,t,parameter)))
421      n=n->next;
422
423  if (n==NULL)
424  {
425    n=(n_Procs_s*)omAlloc0(sizeof(n_Procs_s));
426    n->next=cf_root;
427    n->ref=1;
428    n->type=t;
429
430    // default entries (different from NULL) for some routines:
431    n->nCoeffIsEqual = ndCoeffIsEqual;
432    n->cfSize = ndSize;
433    n->cfGetDenom= ndGetDenom;
434    n->cfGetNumerator= ndGetNumerator;
435    n->cfImPart=ndReturn0;
436    n->cfDelete= ndDelete;
437    n->cfAnn = ndAnn;
438    n->cfCoeffString = ndCoeffString;
439    n->cfCoeffWrite = ndCoeffWrite;
440    n->cfCoeffName = ndCoeffName; // should alway be changed!
441    n->cfInpAdd=ndInpAdd;
442    n->cfInpMult=ndInpMult;
443    n->cfCopy = ndCopy;
444    n->cfIntMod=ndIntMod; /* dummy !! */
445    n->cfNormalize=ndNormalize;
446    n->cfGcd  = ndGcd;
447    n->cfNormalizeHelper  = ndGcd; /* tricky, isn't it ?*/
448    n->cfLcm  = ndGcd; /* tricky, isn't it ?*/
449    n->cfInitMPZ = ndInitMPZ;
450    n->cfMPZ = ndMPZ;
451    n->cfPower = ndPower;
452    n->cfQuotRem = ndQuotRem;
453    n->cfInvers = ndInvers;
454    n->cfRandom = ndRandom;
455
456    n->cfKillChar = ndKillChar; /* dummy */
457    n->cfSetChar = ndSetChar; /* dummy */
458    // temp. removed to catch all the coeffs which miss to implement this!
459
460    n->cfChineseRemainder = ndChineseRemainder; /* not implemented */
461    n->cfFarey = ndFarey; /* not implemented */
462    n->cfParDeg = ndParDeg; /* not implemented */
463    n->cfReadFd = ndReadFd; /* not implemented */
464    n->cfWriteFd = ndWriteFd; /* not implemented */
465
466    n->cfParameter = ndParameter;
467
468    n->cfClearContent = ndClearContent;
469    n->cfClearDenominators = ndClearDenominators;
470
471    n->cfEucNorm = ndEucNorm;
472#ifdef HAVE_RINGS
473    n->cfDivComp = ndDivComp;
474    n->cfDivBy = ndDivBy;
475    n->cfExtGcd = ndExtGcd;
476    n->cfXExtGcd = ndXExtGcd;
477    //n->cfGetUnit = ndGetUnit_Ring;// set afterwards
478#endif
479
480    // report error, if not redefined
481    n->cfRead=ndRead;
482    n->cfSetMap=ndSetMap;
483
484#ifdef LDEBUG
485    n->cfDBTest=ndDBTest;
486#endif
487
488    n->convSingNFactoryN=ndConvSingNFactoryN;
489    n->convFactoryNSingN=ndConvFactoryNSingN;
490
491    BOOLEAN nOK=TRUE;
492    // init
493    if ((t<=nLastCoeffs) && (nInitCharTable[t]!=NULL))
494      nOK = (nInitCharTable[t])(n,parameter);
495    else
496       Werror("Sorry: the coeff type [%d] was not registered: it is missing in nInitCharTable", (int)t);
497    if (nOK)
498    {
499      omFreeSize(n,sizeof(*n));
500      return NULL;
501    }
502    cf_root=n;
503    // post init settings:
504    if (n->cfRePart==NULL) n->cfRePart=n->cfCopy;
505    if (n->cfExactDiv==NULL) n->cfExactDiv=n->cfDiv;
506    if (n->cfSubringGcd==NULL) n->cfSubringGcd=n->cfGcd;
507    if (n->cfWriteShort==NULL) n->cfWriteShort = n->cfWriteLong;
508    if (n->cfIsUnit==NULL)
509    {
510      if (n->is_field) n->cfIsUnit=ndIsUnit_Field;
511      else             n->cfIsUnit=ndIsUnit_Ring;
512    }
513    #ifdef HAVE_RINGS
514    if (n->cfGetUnit==NULL)
515    {
516      if (n->is_field) n->cfGetUnit=n->cfCopy;
517      else             n->cfGetUnit=ndGetUnit_Ring;
518    }
519    if ((n->cfInvers==ndInvers)&&(n->is_field))
520    {
521      n->cfInvers=ndInvers_Ring;
522    }
523    #endif
524
525
526    if(n->cfMult==NULL)  PrintS("cfMult missing\n");
527    if(n->cfSub==NULL)  PrintS("cfSub missing\n");
528    if(n->cfAdd==NULL) PrintS("cfAdd missing\n");
529    if(n->cfDiv==NULL) PrintS("cfDiv missing\n");
530    if(n->cfExactDiv==NULL) PrintS("cfExactDiv missing\n");
531    if(n->cfInit==NULL) PrintS("cfInit missing\n");
532    if(n->cfInt==NULL) PrintS("cfInt missing\n");
533    if(n->cfIsUnit==NULL) PrintS("cfIsUnit missing\n");
534    if(n->cfGetUnit==NULL) PrintS("cfGetUnit missing\n");
535    if(n->cfInpNeg==NULL)  PrintS("cfInpNeg missing\n");
536    if(n->cfXExtGcd==NULL)  PrintS("cfXExtGcd missing\n");
537    if(n->cfAnn==NULL)  PrintS("cfAnn missing\n");
538    if(n->cfWriteLong==NULL) PrintS("cfWriteLong missing\n");
539
540    assume(n->iNumberOfParameters>= 0);
541
542    assume( (n->iNumberOfParameters == 0 && n->pParameterNames == NULL) ||
543            (n->iNumberOfParameters >  0 && n->pParameterNames != NULL) );
544
545
546    if(n->cfGreater==NULL) PrintS("cfGreater missing\n");
547    if(n->cfEqual==NULL) PrintS("cfEqual missing\n");
548    if(n->cfIsZero==NULL) PrintS("cfIsZero missing\n");
549    if(n->cfIsOne==NULL) PrintS("cfIsOne missing\n");
550    if(n->cfIsMOne==NULL) PrintS("cfIsMOne missing\n");
551    if(n->cfGreaterZero==NULL) PrintS("cfGreaterZero missing\n");
552    /* error reporter:
553    if(n->cfRead==ndRead) PrintS("cfRead missing\n");
554    if(n->cfSetMap==ndSetMap) PrintS("cfSetMap missing\n");
555    */
556
557    assume(n->type==t);
558
559#ifndef SING_NDEBUG
560    if(n->cfWriteLong==NULL) Warn("cfWrite is NULL for coeff %d",t);
561    if(n->cfWriteShort==NULL) Warn("cfWriteShort is NULL for coeff %d",t);
562#endif
563  }
564  else
565  {
566    n->ref++;
567  }
568  return n;
569}
570
571void nKillChar(coeffs r)
572{
573  if (r!=NULL)
574  {
575    r->ref--;
576    if (r->ref<=0)
577    {
578      n_Procs_s tmp;
579      n_Procs_s* n=&tmp;
580      tmp.next=cf_root;
581      while((n->next!=NULL) && (n->next!=r)) n=n->next;
582      if (n->next==r)
583      {
584        n->next=n->next->next;
585        if (cf_root==r) cf_root=n->next;
586        assume (r->cfKillChar!=NULL); r->cfKillChar(r);
587        omFreeSize((void *)r, sizeof(n_Procs_s));
588        r=NULL;
589      }
590      else
591      {
592        WarnS("cf_root list destroyed");
593      }
594    }
595  }
596}
597
598n_coeffType nRegister(n_coeffType n, cfInitCharProc p)
599{
600  if (n==n_unknown)
601  {
602    nLastCoeffs=(n_coeffType)(int(nLastCoeffs)+1);
603    if (nInitCharTable==nInitCharTableDefault)
604    {
605      nInitCharTable=(cfInitCharProc*)omAlloc0(
606                                          ((int)nLastCoeffs+1)*sizeof(cfInitCharProc));
607      memcpy(nInitCharTable,nInitCharTableDefault,
608              ((int)nLastCoeffs)*sizeof(cfInitCharProc));
609    }
610    else
611    {
612      nInitCharTable=(cfInitCharProc*)omReallocSize(nInitCharTable,
613                                          ((int)nLastCoeffs)*sizeof(cfInitCharProc),
614                                          (((int)nLastCoeffs)+1)*sizeof(cfInitCharProc));
615    }
616
617    nInitCharTable[nLastCoeffs]=p;
618    return nLastCoeffs;
619  }
620  else
621  {
622    if (nInitCharTable[n]!=NULL) Print("coeff %d already initialized\n",n);
623    nInitCharTable[n]=p;
624    return n;
625  }
626}
627
628struct nFindCoeffByName_s;
629typedef struct nFindCoeffByName_s* nFindCoeffByName_p;
630
631struct nFindCoeffByName_s
632{
633  n_coeffType n;
634  cfInitCfByNameProc p;
635  nFindCoeffByName_p next;
636};
637
638VAR nFindCoeffByName_p nFindCoeffByName_Root=NULL;
639void nRegisterCfByName(cfInitCfByNameProc p,n_coeffType n)
640{
641  nFindCoeffByName_p h=(nFindCoeffByName_p)omAlloc0(sizeof(*h));
642  h->p=p;
643  h->n=n;
644  h->next=nFindCoeffByName_Root;
645  nFindCoeffByName_Root=h;
646}
647
648coeffs nFindCoeffByName(char *cf_name)
649{
650  n_Procs_s* n=cf_root;
651  // try existings coeffs:
652  while(n!=NULL)
653  {
654    if ((n->cfCoeffName!=NULL)
655    && (strcmp(cf_name,n->cfCoeffName(n))==0)) return n;
656    n=n->next;
657  }
658  // TODO: parametrized cf, e.g. flint:Z/26[a]
659  // try existing types:
660  nFindCoeffByName_p p=nFindCoeffByName_Root;
661  while(p!=NULL)
662  {
663    coeffs cf=p->p(cf_name,p->n);
664    if (cf!=NULL) return cf;
665    p=p->next;
666  }
667  return NULL;
668}
669
670void n_Print(number& a,  const coeffs r)
671{
672   assume(r != NULL);
673   n_Test(a,r);
674
675   StringSetS("");
676   n_Write(a, r);
677   { char* s = StringEndS(); Print("%s", s); omFree(s); }
678}
679
680char* nEati(char *s, int *i, int m)
681{
682
683  if (((*s) >= '0') && ((*s) <= '9'))
684  {
685    unsigned long ii=0L;
686    do
687    {
688      ii *= 10;
689      ii += *s++ - '0';
690      if ((m!=0) && (ii > (MAX_INT_VAL / 10))) ii = ii % m;
691    }
692    while (((*s) >= '0') && ((*s) <= '9'));
693    if ((m!=0) && (ii>=(unsigned)m)) ii=ii%m;
694    *i=(int)ii;
695  }
696  else (*i) = 1;
697  return s;
698}
699
700/// extracts a long integer from s, returns the rest
701char * nEatLong(char *s, mpz_ptr i)
702{
703  const char * start=s;
704
705  while (*s >= '0' && *s <= '9') s++;
706  if (*s=='\0')
707  {
708    mpz_set_str(i,start,10);
709  }
710  else
711  {
712    char c=*s;
713    *s='\0';
714    mpz_set_str(i,start,10);
715    *s=c;
716  }
717  return s;
718}
719
Note: See TracBrowser for help on using the repository browser.