source: git/kernel/rmodulon.cc @ 76e501

spielwiese
Last change on this file since 76e501 was 599326, checked in by Kai Krüger <krueger@…>, 14 years ago
Anne, Kai, Frank: - changes to #include "..." statements to allow cleaner build structure - affected directories: omalloc, kernel, Singular - not yet done: IntergerProgramming git-svn-id: file:///usr/local/Singular/svn/trunk@13032 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 14.3 KB
RevLine 
[275ecc]1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
[341696]4/* $Id$ */
[275ecc]5/*
6* ABSTRACT: numbers modulo n
7*/
8
9#include <string.h>
[599326]10#include <kernel/mod2.h>
[275ecc]11#include <mylimits.h>
[599326]12#include <kernel/structs.h>
13#include <kernel/febase.h>
14#include <omalloc.h>
15#include <kernel/numbers.h>
16#include <kernel/longrat.h>
17#include <kernel/mpr_complex.h>
18#include <kernel/ring.h>
19#include <kernel/rmodulon.h>
20#include <kernel/si_gmp.h>
[275ecc]21
[c90b43]22#ifdef HAVE_RINGS
23  extern omBin gmp_nrz_bin;
[275ecc]24
[12ea9d]25int_number nrnMinusOne = NULL;
26unsigned long nrnExponent = 0;
[275ecc]27
[8e1c4e]28/*
29 * create a number from int
30 */
[8391d8]31number nrnInit (int i, const ring r)
[8e1c4e]32{
[3c3880b]33  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[8e1c4e]34  mpz_init_set_si(erg, i);
[196b4b]35  mpz_mod(erg, erg, r->nrnModul);
[8e1c4e]36  return (number) erg;
37}
38
39void nrnDelete(number *a, const ring r)
40{
[befecbc]41  if (*a == NULL) return;
[8e1c4e]42  mpz_clear((int_number) *a);
[3c3880b]43  omFreeBin((ADDRESS) *a, gmp_nrz_bin);
[bac8611]44  *a = NULL;
45}
46
47number nrnCopy(number a)
48{
[3c3880b]49  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[bac8611]50  mpz_init_set(erg, (int_number) a);
51  return (number) erg;
52}
53
54number cfrnCopy(number a, const ring r)
55{
56  return nrnCopy(a);
57}
58
59int nrnSize(number a)
60{
61  if (a == NULL) return 0;
[a604c3]62  return sizeof(mpz_t);
[8e1c4e]63}
64
65/*
[25d15e]66 * convert a number to int
[8e1c4e]67 */
[cf74cd6]68int nrnInt(number &n, const ring r)
[8e1c4e]69{
[5dd581]70  return (int) mpz_get_si( (int_number) n);
[8e1c4e]71}
72
[275ecc]73/*
74 * Multiply two numbers
75 */
[8e56ad]76number nrnMult (number a, number b)
[275ecc]77{
[3c3880b]78  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[8e56ad]79  mpz_init(erg);
80  mpz_mul(erg, (int_number) a, (int_number) b);
[196b4b]81  mpz_mod(erg, erg, currRing->nrnModul);
[8e56ad]82  return (number) erg;
[275ecc]83}
84
[8e1c4e]85void nrnPower (number a, int i, number * result)
86{
[3c3880b]87  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[8e1c4e]88  mpz_init(erg);
[196b4b]89  mpz_powm_ui(erg, (int_number) a, i, currRing->nrnModul);
[8e1c4e]90  *result = (number) erg;
91}
92
93number nrnAdd (number a, number b)
94{
[3c3880b]95  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[8e1c4e]96  mpz_init(erg);
97  mpz_add(erg, (int_number) a, (int_number) b);
[196b4b]98  mpz_mod(erg, erg, currRing->nrnModul);
[8e1c4e]99  return (number) erg;
100}
101
102number nrnSub (number a, number b)
103{
[3c3880b]104  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[8e1c4e]105  mpz_init(erg);
106  mpz_sub(erg, (int_number) a, (int_number) b);
[196b4b]107  mpz_mod(erg, erg, currRing->nrnModul);
[8e1c4e]108  return (number) erg;
109}
110
111number nrnNeg (number c)
112{
[1eef69]113// nNeg inplace !!!
[196b4b]114  mpz_sub((int_number) c, currRing->nrnModul, (int_number) c);
[a539ad]115  return c;
[8e1c4e]116}
117
118number  nrnInvers (number c)
119{
[3c3880b]120  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[8e1c4e]121  mpz_init(erg);
[196b4b]122  mpz_invert(erg, (int_number) c, currRing->nrnModul);
[8e1c4e]123  return (number) erg;
124}
125
[275ecc]126/*
127 * Give the smallest non unit k, such that a * x = k = b * y has a solution
[8e1c4e]128 * TODO: lcm(gcd,gcd) besser als gcd(lcm) ?
[275ecc]129 */
130number nrnLcm (number a,number b,ring r)
131{
[196b4b]132  number erg = nrnGcd(NULL, a, r);
133  number tmp = nrnGcd(NULL, b, r);
[8e1c4e]134  mpz_lcm((int_number) erg, (int_number) erg, (int_number) tmp);
135  nrnDelete(&tmp, NULL);
[d681e8]136  return (number) erg;
[275ecc]137}
138
139/*
140 * Give the largest non unit k, such that a = x * k, b = y * k has
141 * a solution.
142 */
143number nrnGcd (number a,number b,ring r)
144{
[8391d8]145  if ((a == NULL) && (b == NULL)) return nrnInit(0,r);
[3c3880b]146  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[196b4b]147  mpz_init_set(erg, r->nrnModul);
[31e857]148  if (a != NULL) mpz_gcd(erg, erg, (int_number) a);
149  if (b != NULL) mpz_gcd(erg, erg, (int_number) b);
[8e56ad]150  return (number) erg;
151}
152
[8e1c4e]153/* Not needed any more, but may have room for improvement
[af378f7]154number nrnGcd3 (number a,number b, number c,ring r)
155{
[3c3880b]156  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[af378f7]157  mpz_init(erg);
[196b4b]158  if (a == NULL) a = (number) r->nrnModul;
159  if (b == NULL) b = (number) r->nrnModul;
160  if (c == NULL) c = (number) r->nrnModul;
[af378f7]161  mpz_gcd(erg, (int_number) a, (int_number) b);
162  mpz_gcd(erg, erg, (int_number) c);
[196b4b]163  mpz_gcd(erg, erg, r->nrnModul);
[af378f7]164  return (number) erg;
165}
[8e1c4e]166*/
[af378f7]167
[8e56ad]168/*
169 * Give the largest non unit k, such that a = x * k, b = y * k has
170 * a solution and r, s, s.t. k = s*a + t*b
171 */
172number  nrnExtGcd (number a, number b, number *s, number *t)
173{
[3c3880b]174  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
175  int_number bs = (int_number) omAllocBin(gmp_nrz_bin);
176  int_number bt = (int_number) omAllocBin(gmp_nrz_bin);
[8e56ad]177  mpz_init(erg);
178  mpz_init(bs);
179  mpz_init(bt);
180  mpz_gcdext(erg, bs, bt, (int_number) a, (int_number) b);
[196b4b]181  mpz_mod(bs, bs, currRing->nrnModul);
182  mpz_mod(bt, bt, currRing->nrnModul);
[8e56ad]183  *s = (number) bs;
184  *t = (number) bt;
185  return (number) erg;
[275ecc]186}
187
[8e1c4e]188BOOLEAN nrnIsZero (number  a)
[275ecc]189{
[01d4d3]190#ifdef LDEBUG
[191795]191  if (a == NULL) return FALSE;
[01d4d3]192#endif
[8e1c4e]193  return 0 == mpz_cmpabs_ui((int_number) a, 0);
[275ecc]194}
195
[8e1c4e]196BOOLEAN nrnIsOne (number a)
[275ecc]197{
[191795]198#ifdef LDEBUG
199  if (a == NULL) return FALSE;
200#endif
[8e1c4e]201  return 0 == mpz_cmp_si((int_number) a, 1);
[8e56ad]202}
203
[8e1c4e]204BOOLEAN nrnIsMOne (number a)
[8e56ad]205{
[191795]206#ifdef LDEBUG
207  if (a == NULL) return FALSE;
208#endif
[8e1c4e]209  return 0 == mpz_cmp((int_number) a, nrnMinusOne);
[275ecc]210}
211
[8e1c4e]212BOOLEAN nrnEqual (number a,number b)
[275ecc]213{
[8e1c4e]214  return 0 == mpz_cmp((int_number) a, (int_number) b);
[275ecc]215}
216
[8e1c4e]217BOOLEAN nrnGreater (number a,number b)
[275ecc]218{
[8e1c4e]219  return 0 < mpz_cmp((int_number) a, (int_number) b);
[275ecc]220}
221
[8e1c4e]222BOOLEAN nrnGreaterZero (number k)
[275ecc]223{
[675ce47]224  return 0 < mpz_cmp_si((int_number) k, 0);
[8e1c4e]225}
226
227BOOLEAN nrnIsUnit (number a)
228{
[196b4b]229  number tmp = nrnGcd(a, (number) currRing->nrnModul, currRing);
[8e1c4e]230  bool res = nrnIsOne(tmp);
231  nrnDelete(&tmp, NULL);
232  return res;
[275ecc]233}
234
[af378f7]235number  nrnGetUnit (number k)
[1e579c6]236{
[196b4b]237  if (mpz_divisible_p(currRing->nrnModul, (int_number) k)) return nrnInit(1,currRing);
[97c4ad]238
[31e857]239  int_number unit = (int_number) nrnGcd(k, 0, currRing);
240  mpz_tdiv_q(unit, (int_number) k, unit);
241  int_number gcd = (int_number) nrnGcd((number) unit, 0, currRing);
242  if (!nrnIsOne((number) gcd))
[af378f7]243  {
[31e857]244    int_number ctmp;
245    // tmp := unit^2
246    int_number tmp = (int_number) nrnMult((number) unit,(number) unit);
247    // gcd_new := gcd(tmp, 0)
248    int_number gcd_new = (int_number) nrnGcd((number) tmp, 0, currRing);
249    while (!nrnEqual((number) gcd_new,(number) gcd))
[af378f7]250    {
[31e857]251      // gcd := gcd_new
252      ctmp = gcd;
[af378f7]253      gcd = gcd_new;
[31e857]254      gcd_new = ctmp;
255      // tmp := tmp * unit
256      mpz_mul(tmp, tmp, unit);
[196b4b]257      mpz_mod(tmp, tmp, currRing->nrnModul);
[31e857]258      // gcd_new := gcd(tmp, 0)
[196b4b]259      mpz_gcd(gcd_new, tmp, currRing->nrnModul);
[af378f7]260    }
[31e857]261    // unit := unit + nrnModul / gcd_new
[196b4b]262    mpz_tdiv_q(tmp, currRing->nrnModul, gcd_new);
[31e857]263    mpz_add(unit, unit, tmp);
[196b4b]264    mpz_mod(unit, unit, currRing->nrnModul);
[31e857]265    nrnDelete((number*) &gcd_new, NULL);
266    nrnDelete((number*) &tmp, NULL);
[af378f7]267  }
[31e857]268  nrnDelete((number*) &gcd, NULL);
269  return (number) unit;
[1e579c6]270}
271
[8e1c4e]272BOOLEAN nrnDivBy (number a,number b)
[275ecc]273{
[97c4ad]274  if (a == NULL)
[196b4b]275    return mpz_divisible_p(currRing->nrnModul, (int_number) b);
[97c4ad]276  else
277    return mpz_divisible_p((int_number) a, (int_number) b);
[821a22]278  /*
[196b4b]279  number bs = nrnGcd(a, b, currRing);
[31e857]280  mpz_tdiv_q((int_number) bs, (int_number) b, (int_number) bs);
[8e1c4e]281  bool res = nrnIsUnit(bs);
282  nrnDelete(&bs, NULL);
[af378f7]283  return res;
[821a22]284  */
[275ecc]285}
286
[d351d8]287int nrnDivComp(number a, number b)
[275ecc]288{
[8e56ad]289  if (nrnEqual(a, b)) return 0;
[31e857]290  if (mpz_divisible_p((int_number) a, (int_number) b)) return -1;
291  if (mpz_divisible_p((int_number) b, (int_number) a)) return 1;
[8e56ad]292  return 2;
[275ecc]293}
294
295number nrnDiv (number a,number b)
296{
[196b4b]297  if (a == NULL) a = (number) currRing->nrnModul;
[3c3880b]298  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[8e56ad]299  mpz_init(erg);
[af378f7]300  if (mpz_divisible_p((int_number) a, (int_number) b))
[275ecc]301  {
[8e56ad]302    mpz_divexact(erg, (int_number) a, (int_number) b);
303    return (number) erg;
[275ecc]304  }
305  else
306  {
[196b4b]307    int_number gcd = (int_number) nrnGcd(a, b, currRing);
[8e56ad]308    mpz_divexact(erg, (int_number) b, gcd);
309    if (!nrnIsUnit((number) erg))
310    {
[bca575c]311      WerrorS("Division not possible, even by cancelling zero divisors.");
312      WerrorS("Result is integer division without remainder.");
[67dbdb]313      mpz_tdiv_q(erg, (int_number) a, (int_number) b);
[31e857]314      nrnDelete((number*) &gcd, NULL);
[12ea9d]315      return (number) erg;
[8e56ad]316    }
[31e857]317    // a / gcd(a,b) * [b / gcd (a,b)]^(-1)
318    int_number tmp = (int_number) nrnInvers((number) erg);
[8e56ad]319    mpz_divexact(erg, (int_number) a, gcd);
[12ea9d]320    mpz_mul(erg, erg, tmp);
[31e857]321    nrnDelete((number*) &gcd, NULL);
322    nrnDelete((number*) &tmp, NULL);
[196b4b]323    mpz_mod(erg, erg, currRing->nrnModul);
[8e56ad]324    return (number) erg;
[275ecc]325  }
326}
327
[6ea941]328number nrnMod (number a, number b)
329{
330  /*
331    We need to return the number r which is uniquely determined by the
332    following two properties:
333      (1) 0 <= r < |b| (with respect to '<' and '<=' performed in Z x Z)
334      (2) There exists some k in the integers Z such that a = k * b + r.
335    Consider g := gcd(n, |b|). Note that then |b|/g is a unit in Z/n.
336    Now, there are three cases:
337      (a) g = 1
338          Then |b| is a unit in Z/n, i.e. |b| (and also b) divides a.
339          Thus r = 0.
340      (b) g <> 1 and g divides a
341          Then a = (a/g) * (|b|/g)^(-1) * b (up to sign), i.e. again r = 0.
342      (c) g <> 1 and g does not divide a
343          Then denote the division with remainder of a by g as this:
344          a = s * g + t. Then t = a - s * g = a - s * (|b|/g)^(-1) * |b|
345          fulfills (1) and (2), i.e. r := t is the correct result. Hence
346          in this third case, r is the remainder of division of a by g in Z.
[e1634d]347     Remark: according to mpz_mod: a,b are always non-negative
[6ea941]348  */
[3c3880b]349  int_number g = (int_number) omAllocBin(gmp_nrz_bin);
350  int_number r = (int_number) omAllocBin(gmp_nrz_bin);
[6ea941]351  mpz_init(g);
352  mpz_init_set_si(r,(long)0);
[196b4b]353  mpz_gcd(g, (int_number) currRing->nrnModul, (int_number)b); // g is now as above
[6ea941]354  if (mpz_cmp_si(g, (long)1) != 0) mpz_mod(r, (int_number)a, g); // the case g <> 1
355  mpz_clear(g);
[3c3880b]356  omFreeBin(g, gmp_nrz_bin);
[6ea941]357  return (number)r;
358}
359
[275ecc]360number nrnIntDiv (number a,number b)
361{
[3c3880b]362  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[8e56ad]363  mpz_init(erg);
[196b4b]364  if (a == NULL) a = (number) currRing->nrnModul;
[8e56ad]365  mpz_tdiv_q(erg, (int_number) a, (int_number) b);
366  return (number) erg;
[275ecc]367}
368
[d351d8]369/*
[d9301a]370 * Helper function for computing the module
371 */
372
373int_number nrnMapCoef = NULL;
374
[d351d8]375number nrnMapModN(number from)
376{
[d9301a]377  return nrnMult(from, (number) nrnMapCoef);
[d351d8]378}
[d9301a]379
380number nrnMap2toM(number from)
381{
[3c3880b]382  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[d9301a]383  mpz_init(erg);
384  mpz_mul_ui(erg, nrnMapCoef, (NATNUMBER) from);
[196b4b]385  mpz_mod(erg, erg, currRing->nrnModul);
[d9301a]386  return (number) erg;
387}
388
[894f5b1]389number nrnMapZp(number from)
390{
[3c3880b]391  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[894f5b1]392  mpz_init(erg);
393  mpz_mul_si(erg, nrnMapCoef, (NATNUMBER) from);
[196b4b]394  mpz_mod(erg, erg, currRing->nrnModul);
[894f5b1]395  return (number) erg;
396}
397
398number nrnMapGMP(number from)
[d9301a]399{
[3c3880b]400  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[d9301a]401  mpz_init(erg);
[196b4b]402  mpz_mod(erg, (int_number) from, currRing->nrnModul);
[d9301a]403  return (number) erg;
404}
405
[894f5b1]406number nrnMapQ(number from)
407{
[3c3880b]408  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[894f5b1]409  mpz_init(erg);
410  nlGMP(from, (number) erg);
[196b4b]411  mpz_mod(erg, erg, currRing->nrnModul);
[894f5b1]412  return (number) erg;
413}
414
[208e0c]415nMapFunc nrnSetMap(const ring src, const ring dst)
[275ecc]416{
[d9301a]417  /* dst = currRing */
418  if (rField_is_Ring_Z(src))
[d351d8]419  {
[894f5b1]420    return nrnMapGMP;
421  }
422  if (rField_is_Q(src))
423  {
424    return nrnMapQ;
[d9301a]425  }
[894f5b1]426  // Some type of Z/n ring / field
427  if (rField_is_Ring_ModN(src) || rField_is_Ring_PtoM(src) || rField_is_Ring_2toM(src) || rField_is_Zp(src))
[d9301a]428  {
[894f5b1]429    if (   (src->ringtype > 0)
[c81a40]430        && (mpz_cmp(src->ringflaga, dst->ringflaga) == 0)
[894f5b1]431        && (src->ringflagb == dst->ringflagb)) return nrnMapGMP;
[d351d8]432    else
433    {
[3c3880b]434      int_number nrnMapModul = (int_number) omAllocBin(gmp_nrz_bin);
[894f5b1]435      // Computing the n of Z/n
436      if (rField_is_Zp(src))
437      {
438        mpz_init_set_si(nrnMapModul, src->ch);
439      }
440      else
441      {
442        mpz_init(nrnMapModul);
[c81a40]443        mpz_set(nrnMapModul, src->ringflaga);
[894f5b1]444        mpz_pow_ui(nrnMapModul, nrnMapModul, src->ringflagb);
445      }
446      // nrnMapCoef = 1 in dst       if dst is a subring of src
447      // nrnMapCoef = 0 in dst / src if src is a subring of dst
[d9301a]448      if (nrnMapCoef == NULL)
[d351d8]449      {
[3c3880b]450        nrnMapCoef = (int_number) omAllocBin(gmp_nrz_bin);
[d9301a]451        mpz_init(nrnMapCoef);
452      }
[196b4b]453      if (mpz_divisible_p(nrnMapModul, currRing->nrnModul))
[894f5b1]454      {
455        mpz_set_si(nrnMapCoef, 1);
456      }
457      else
[d9301a]458      if (nrnDivBy(NULL, (number) nrnMapModul))
459      {
[196b4b]460        mpz_divexact(nrnMapCoef, currRing->nrnModul, nrnMapModul);
461        int_number tmp = currRing->nrnModul;
462        currRing->nrnModul = nrnMapModul;
[0959dc]463        if (!nrnIsUnit((number) nrnMapCoef))
464        {
[196b4b]465          currRing->nrnModul = tmp;
[0959dc]466          nrnDelete((number*) &nrnMapModul, currRing);
467          return NULL;
468        }
[d9301a]469        int_number inv = (int_number) nrnInvers((number) nrnMapCoef);
[196b4b]470        currRing->nrnModul = tmp;
[d9301a]471        mpz_mul(nrnMapCoef, nrnMapCoef, inv);
[196b4b]472        mpz_mod(nrnMapCoef, nrnMapCoef, currRing->nrnModul);
[d9301a]473        nrnDelete((number*) &inv, currRing);
474      }
475      else
476      {
477        nrnDelete((number*) &nrnMapModul, currRing);
478        return NULL;
[d351d8]479      }
[d9301a]480      nrnDelete((number*) &nrnMapModul, currRing);
481      if (rField_is_Ring_2toM(src))
482        return nrnMap2toM;
[894f5b1]483      else if (rField_is_Zp(src))
484        return nrnMapZp;
[d351d8]485      else
[d9301a]486        return nrnMapModN;
[d351d8]487    }
488  }
489  return NULL;      // default
[275ecc]490}
491
492/*
493 * set the exponent (allocate and init tables) (TODO)
494 */
495
496void nrnSetExp(int m, ring r)
497{
[196b4b]498  if ((r->nrnModul != NULL) && (mpz_cmp(r->nrnModul, r->ringflaga) == 0) && (nrnExponent == r->ringflagb)) return;
[20704f]499
[12ea9d]500  nrnExponent = r->ringflagb;
[196b4b]501  if (r->nrnModul == NULL)
[12ea9d]502  {
[3c3880b]503    r->nrnModul = (int_number) omAllocBin(gmp_nrz_bin);
[196b4b]504    mpz_init(r->nrnModul);
[3c3880b]505    nrnMinusOne = (int_number) omAllocBin(gmp_nrz_bin);
[07b6ac]506    mpz_init(nrnMinusOne);
[12ea9d]507  }
[196b4b]508  mpz_set(r->nrnModul, r->ringflaga);
509  mpz_pow_ui(r->nrnModul, r->nrnModul, nrnExponent);
510  mpz_sub_ui(nrnMinusOne, r->nrnModul, 1);
[275ecc]511}
512
513void nrnInitExp(int m, ring r)
514{
[12ea9d]515  nrnSetExp(m, r);
[093f30e]516
[196b4b]517  if (mpz_cmp_ui(r->nrnModul,2) <= 0)
[275ecc]518  {
[093f30e]519    WarnS("nrnInitExp failed");
[275ecc]520  }
521}
522
523#ifdef LDEBUG
[85e68dd]524BOOLEAN nrnDBTest (number a, const char *f, const int l)
[275ecc]525{
[01d4d3]526  if (a==NULL) return TRUE;
[196b4b]527  if ( (mpz_cmp_si((int_number) a, 0) < 0) || (mpz_cmp((int_number) a, currRing->nrnModul) > 0) )
[275ecc]528  {
529    return FALSE;
530  }
531  return TRUE;
532}
533#endif
534
[8e56ad]535/*2
536* extracts a long integer from s, returns the rest    (COPY FROM longrat0.cc)
537*/
[a604c3]538static const char * nlCPEatLongC(char *s, mpz_ptr i)
[275ecc]539{
[85e68dd]540  const char * start=s;
[af378f7]541  if (!(*s >= '0' && *s <= '9'))
542  {
543    mpz_init_set_si(i, 1);
544    return s;
545  }
546  mpz_init(i);
[8e56ad]547  while (*s >= '0' && *s <= '9') s++;
548  if (*s=='\0')
[275ecc]549  {
[8e56ad]550    mpz_set_str(i,start,10);
551  }
552  else
553  {
554    char c=*s;
555    *s='\0';
556    mpz_set_str(i,start,10);
557    *s=c;
[275ecc]558  }
559  return s;
560}
561
[85e68dd]562const char * nrnRead (const char *s, number *a)
[275ecc]563{
[3c3880b]564  int_number z = (int_number) omAllocBin(gmp_nrz_bin);
[275ecc]565  {
[85e68dd]566    s = nlCPEatLongC((char *)s, z);
[275ecc]567  }
[196b4b]568  mpz_mod(z, z, currRing->nrnModul);
[8e56ad]569  *a = (number) z;
[275ecc]570  return s;
571}
572#endif
Note: See TracBrowser for help on using the repository browser.