[275ecc] | 1 | /**************************************** |
---|
| 2 | * Computer Algebra System SINGULAR * |
---|
| 3 | ****************************************/ |
---|
[85e68dd] | 4 | /* $Id: rmodulon.cc,v 1.23 2008-03-19 17:44:12 Singular Exp $ */ |
---|
[275ecc] | 5 | /* |
---|
| 6 | * ABSTRACT: numbers modulo n |
---|
| 7 | */ |
---|
| 8 | |
---|
| 9 | #include <string.h> |
---|
| 10 | #include "mod2.h" |
---|
| 11 | #include <mylimits.h> |
---|
| 12 | #include "structs.h" |
---|
| 13 | #include "febase.h" |
---|
| 14 | #include "omalloc.h" |
---|
| 15 | #include "numbers.h" |
---|
| 16 | #include "longrat.h" |
---|
| 17 | #include "mpr_complex.h" |
---|
| 18 | #include "ring.h" |
---|
| 19 | #include "rmodulon.h" |
---|
[8e56ad] | 20 | #include "gmp.h" |
---|
[275ecc] | 21 | |
---|
| 22 | #ifdef HAVE_RINGMODN |
---|
| 23 | |
---|
[8e56ad] | 24 | typedef MP_INT *int_number; |
---|
[bac8611] | 25 | omBin gmp_nrn_bin = omGetSpecBin(sizeof(MP_INT)); |
---|
[275ecc] | 26 | |
---|
[12ea9d] | 27 | int_number nrnModul = NULL; |
---|
| 28 | int_number nrnMinusOne = NULL; |
---|
| 29 | unsigned long nrnExponent = 0; |
---|
| 30 | unsigned long long nrnBase = 0; |
---|
[275ecc] | 31 | |
---|
[8e1c4e] | 32 | /* |
---|
| 33 | * create a number from int |
---|
| 34 | */ |
---|
| 35 | number nrnInit (int i) |
---|
| 36 | { |
---|
[bac8611] | 37 | int_number erg = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
[8e1c4e] | 38 | mpz_init_set_si(erg, i); |
---|
| 39 | mpz_mod(erg, erg, nrnModul); |
---|
| 40 | return (number) erg; |
---|
| 41 | } |
---|
| 42 | |
---|
| 43 | void nrnDelete(number *a, const ring r) |
---|
| 44 | { |
---|
[befecbc] | 45 | if (*a == NULL) return; |
---|
[8e1c4e] | 46 | mpz_clear((int_number) *a); |
---|
[bac8611] | 47 | omFreeBin((ADDRESS) *a, gmp_nrn_bin); |
---|
| 48 | *a = NULL; |
---|
| 49 | } |
---|
| 50 | |
---|
| 51 | number nrnCopy(number a) |
---|
| 52 | { |
---|
| 53 | int_number erg = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
| 54 | mpz_init_set(erg, (int_number) a); |
---|
| 55 | return (number) erg; |
---|
| 56 | } |
---|
| 57 | |
---|
| 58 | number cfrnCopy(number a, const ring r) |
---|
| 59 | { |
---|
| 60 | return nrnCopy(a); |
---|
| 61 | } |
---|
| 62 | |
---|
| 63 | int nrnSize(number a) |
---|
| 64 | { |
---|
| 65 | if (a == NULL) return 0; |
---|
| 66 | return sizeof(MP_INT); |
---|
[8e1c4e] | 67 | } |
---|
| 68 | |
---|
| 69 | /* |
---|
| 70 | * convert a number to int (-p/2 .. p/2) |
---|
| 71 | */ |
---|
| 72 | int nrnInt(number &n) |
---|
| 73 | { |
---|
| 74 | return (int) mpz_get_si( (int_number) &n); |
---|
| 75 | } |
---|
| 76 | |
---|
[275ecc] | 77 | /* |
---|
| 78 | * Multiply two numbers |
---|
| 79 | */ |
---|
[8e56ad] | 80 | number nrnMult (number a, number b) |
---|
[275ecc] | 81 | { |
---|
[bac8611] | 82 | int_number erg = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
[8e56ad] | 83 | mpz_init(erg); |
---|
| 84 | mpz_mul(erg, (int_number) a, (int_number) b); |
---|
| 85 | mpz_mod(erg, erg, nrnModul); |
---|
| 86 | return (number) erg; |
---|
[275ecc] | 87 | } |
---|
| 88 | |
---|
[8e1c4e] | 89 | void nrnPower (number a, int i, number * result) |
---|
| 90 | { |
---|
[bac8611] | 91 | int_number erg = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
[8e1c4e] | 92 | mpz_init(erg); |
---|
| 93 | mpz_powm_ui(erg, (int_number) a, i, nrnModul); |
---|
| 94 | *result = (number) erg; |
---|
| 95 | } |
---|
| 96 | |
---|
| 97 | number nrnAdd (number a, number b) |
---|
| 98 | { |
---|
[bac8611] | 99 | int_number erg = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
[8e1c4e] | 100 | mpz_init(erg); |
---|
| 101 | mpz_add(erg, (int_number) a, (int_number) b); |
---|
| 102 | mpz_mod(erg, erg, nrnModul); |
---|
| 103 | return (number) erg; |
---|
| 104 | } |
---|
| 105 | |
---|
| 106 | number nrnSub (number a, number b) |
---|
| 107 | { |
---|
[bac8611] | 108 | int_number erg = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
[8e1c4e] | 109 | mpz_init(erg); |
---|
| 110 | mpz_sub(erg, (int_number) a, (int_number) b); |
---|
| 111 | mpz_mod(erg, erg, nrnModul); |
---|
| 112 | return (number) erg; |
---|
| 113 | } |
---|
| 114 | |
---|
| 115 | number nrnNeg (number c) |
---|
| 116 | { |
---|
[a539ad] | 117 | // nNeg inplace !!! TODO |
---|
| 118 | // int_number erg = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
| 119 | // mpz_init(erg); |
---|
| 120 | mpz_sub((int_number) c, nrnModul, (int_number) c); |
---|
| 121 | return c; |
---|
[8e1c4e] | 122 | } |
---|
| 123 | |
---|
| 124 | number nrnInvers (number c) |
---|
| 125 | { |
---|
[bac8611] | 126 | int_number erg = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
[8e1c4e] | 127 | mpz_init(erg); |
---|
| 128 | mpz_invert(erg, (int_number) c, nrnModul); |
---|
| 129 | return (number) erg; |
---|
| 130 | } |
---|
| 131 | |
---|
[275ecc] | 132 | /* |
---|
| 133 | * Give the smallest non unit k, such that a * x = k = b * y has a solution |
---|
[8e1c4e] | 134 | * TODO: lcm(gcd,gcd) besser als gcd(lcm) ? |
---|
[275ecc] | 135 | */ |
---|
| 136 | number nrnLcm (number a,number b,ring r) |
---|
| 137 | { |
---|
[8e1c4e] | 138 | number erg = nrnGcd(NULL, a, NULL); |
---|
| 139 | number tmp = nrnGcd(NULL, b, NULL); |
---|
| 140 | mpz_lcm((int_number) erg, (int_number) erg, (int_number) tmp); |
---|
| 141 | nrnDelete(&tmp, NULL); |
---|
[d681e8] | 142 | return (number) erg; |
---|
[275ecc] | 143 | } |
---|
| 144 | |
---|
| 145 | /* |
---|
| 146 | * Give the largest non unit k, such that a = x * k, b = y * k has |
---|
| 147 | * a solution. |
---|
| 148 | */ |
---|
| 149 | number nrnGcd (number a,number b,ring r) |
---|
| 150 | { |
---|
[31e857] | 151 | if ((a == NULL) && (b == NULL)) return nrnInit(0); |
---|
[bac8611] | 152 | int_number erg = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
[31e857] | 153 | mpz_init_set(erg, nrnModul); |
---|
| 154 | if (a != NULL) mpz_gcd(erg, erg, (int_number) a); |
---|
| 155 | if (b != NULL) mpz_gcd(erg, erg, (int_number) b); |
---|
[8e56ad] | 156 | return (number) erg; |
---|
| 157 | } |
---|
| 158 | |
---|
[8e1c4e] | 159 | /* Not needed any more, but may have room for improvement |
---|
[af378f7] | 160 | number nrnGcd3 (number a,number b, number c,ring r) |
---|
| 161 | { |
---|
[bac8611] | 162 | int_number erg = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
[af378f7] | 163 | mpz_init(erg); |
---|
| 164 | if (a == NULL) a = (number) nrnModul; |
---|
| 165 | if (b == NULL) b = (number) nrnModul; |
---|
| 166 | if (c == NULL) c = (number) nrnModul; |
---|
| 167 | mpz_gcd(erg, (int_number) a, (int_number) b); |
---|
| 168 | mpz_gcd(erg, erg, (int_number) c); |
---|
[8e1c4e] | 169 | mpz_gcd(erg, erg, nrnModul); |
---|
[af378f7] | 170 | return (number) erg; |
---|
| 171 | } |
---|
[8e1c4e] | 172 | */ |
---|
[af378f7] | 173 | |
---|
[8e56ad] | 174 | /* |
---|
| 175 | * Give the largest non unit k, such that a = x * k, b = y * k has |
---|
| 176 | * a solution and r, s, s.t. k = s*a + t*b |
---|
| 177 | */ |
---|
| 178 | number nrnExtGcd (number a, number b, number *s, number *t) |
---|
| 179 | { |
---|
[bac8611] | 180 | int_number erg = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
| 181 | int_number bs = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
| 182 | int_number bt = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
[8e56ad] | 183 | mpz_init(erg); |
---|
| 184 | mpz_init(bs); |
---|
| 185 | mpz_init(bt); |
---|
| 186 | mpz_gcdext(erg, bs, bt, (int_number) a, (int_number) b); |
---|
[8e1c4e] | 187 | mpz_mod(bs, bs, nrnModul); |
---|
| 188 | mpz_mod(bt, bt, nrnModul); |
---|
[8e56ad] | 189 | *s = (number) bs; |
---|
| 190 | *t = (number) bt; |
---|
| 191 | return (number) erg; |
---|
[275ecc] | 192 | } |
---|
| 193 | |
---|
[8e1c4e] | 194 | BOOLEAN nrnIsZero (number a) |
---|
[275ecc] | 195 | { |
---|
[8e1c4e] | 196 | return 0 == mpz_cmpabs_ui((int_number) a, 0); |
---|
[275ecc] | 197 | } |
---|
| 198 | |
---|
[8e1c4e] | 199 | BOOLEAN nrnIsOne (number a) |
---|
[275ecc] | 200 | { |
---|
[8e1c4e] | 201 | return 0 == mpz_cmp_si((int_number) a, 1); |
---|
[8e56ad] | 202 | } |
---|
| 203 | |
---|
[8e1c4e] | 204 | BOOLEAN nrnIsMOne (number a) |
---|
[8e56ad] | 205 | { |
---|
[8e1c4e] | 206 | return 0 == mpz_cmp((int_number) a, nrnMinusOne); |
---|
[275ecc] | 207 | } |
---|
| 208 | |
---|
[8e1c4e] | 209 | BOOLEAN nrnEqual (number a,number b) |
---|
[275ecc] | 210 | { |
---|
[8e1c4e] | 211 | return 0 == mpz_cmp((int_number) a, (int_number) b); |
---|
[275ecc] | 212 | } |
---|
| 213 | |
---|
[8e1c4e] | 214 | BOOLEAN nrnGreater (number a,number b) |
---|
[275ecc] | 215 | { |
---|
[8e1c4e] | 216 | return 0 < mpz_cmp((int_number) a, (int_number) b); |
---|
[275ecc] | 217 | } |
---|
| 218 | |
---|
[8e1c4e] | 219 | BOOLEAN nrnGreaterZero (number k) |
---|
[275ecc] | 220 | { |
---|
[8e1c4e] | 221 | return 0 <= mpz_cmp_si((int_number) k, 0); |
---|
| 222 | } |
---|
| 223 | |
---|
| 224 | BOOLEAN nrnIsUnit (number a) |
---|
| 225 | { |
---|
| 226 | number tmp = nrnGcd(a, (number) nrnModul, NULL); |
---|
| 227 | bool res = nrnIsOne(tmp); |
---|
| 228 | nrnDelete(&tmp, NULL); |
---|
| 229 | return res; |
---|
[275ecc] | 230 | } |
---|
| 231 | |
---|
[af378f7] | 232 | number nrnGetUnit (number k) |
---|
[1e579c6] | 233 | { |
---|
[8a0aa2] | 234 | if (mpz_divisible_p(nrnModul, (int_number) k)) return nrnInit(1); |
---|
[97c4ad] | 235 | |
---|
[31e857] | 236 | int_number unit = (int_number) nrnGcd(k, 0, currRing); |
---|
| 237 | mpz_tdiv_q(unit, (int_number) k, unit); |
---|
| 238 | int_number gcd = (int_number) nrnGcd((number) unit, 0, currRing); |
---|
| 239 | if (!nrnIsOne((number) gcd)) |
---|
[af378f7] | 240 | { |
---|
[31e857] | 241 | int_number ctmp; |
---|
| 242 | // tmp := unit^2 |
---|
| 243 | int_number tmp = (int_number) nrnMult((number) unit,(number) unit); |
---|
| 244 | // gcd_new := gcd(tmp, 0) |
---|
| 245 | int_number gcd_new = (int_number) nrnGcd((number) tmp, 0, currRing); |
---|
| 246 | while (!nrnEqual((number) gcd_new,(number) gcd)) |
---|
[af378f7] | 247 | { |
---|
[31e857] | 248 | // gcd := gcd_new |
---|
| 249 | ctmp = gcd; |
---|
[af378f7] | 250 | gcd = gcd_new; |
---|
[31e857] | 251 | gcd_new = ctmp; |
---|
| 252 | // tmp := tmp * unit |
---|
| 253 | mpz_mul(tmp, tmp, unit); |
---|
| 254 | mpz_mod(tmp, tmp, nrnModul); |
---|
| 255 | // gcd_new := gcd(tmp, 0) |
---|
| 256 | mpz_gcd(gcd_new, tmp, nrnModul); |
---|
[af378f7] | 257 | } |
---|
[31e857] | 258 | // unit := unit + nrnModul / gcd_new |
---|
| 259 | mpz_tdiv_q(tmp, nrnModul, gcd_new); |
---|
| 260 | mpz_add(unit, unit, tmp); |
---|
| 261 | mpz_mod(unit, unit, nrnModul); |
---|
| 262 | nrnDelete((number*) &gcd_new, NULL); |
---|
| 263 | nrnDelete((number*) &tmp, NULL); |
---|
[af378f7] | 264 | } |
---|
[31e857] | 265 | nrnDelete((number*) &gcd, NULL); |
---|
| 266 | return (number) unit; |
---|
[1e579c6] | 267 | } |
---|
| 268 | |
---|
[8e1c4e] | 269 | BOOLEAN nrnDivBy (number a,number b) |
---|
[275ecc] | 270 | { |
---|
[97c4ad] | 271 | if (a == NULL) |
---|
| 272 | return mpz_divisible_p(nrnModul, (int_number) b); |
---|
| 273 | else |
---|
| 274 | return mpz_divisible_p((int_number) a, (int_number) b); |
---|
[821a22] | 275 | /* |
---|
[31e857] | 276 | number bs = nrnGcd(a, b, NULL); |
---|
| 277 | mpz_tdiv_q((int_number) bs, (int_number) b, (int_number) bs); |
---|
[8e1c4e] | 278 | bool res = nrnIsUnit(bs); |
---|
| 279 | nrnDelete(&bs, NULL); |
---|
[af378f7] | 280 | return res; |
---|
[821a22] | 281 | */ |
---|
[275ecc] | 282 | } |
---|
| 283 | |
---|
[8e56ad] | 284 | int nrnComp(number a, number b) |
---|
[275ecc] | 285 | { |
---|
[8e56ad] | 286 | if (nrnEqual(a, b)) return 0; |
---|
[31e857] | 287 | if (mpz_divisible_p((int_number) a, (int_number) b)) return -1; |
---|
| 288 | if (mpz_divisible_p((int_number) b, (int_number) a)) return 1; |
---|
[8e56ad] | 289 | return 2; |
---|
[275ecc] | 290 | } |
---|
| 291 | |
---|
| 292 | number nrnDiv (number a,number b) |
---|
| 293 | { |
---|
[af378f7] | 294 | if (a == NULL) a = (number) nrnModul; |
---|
[bac8611] | 295 | int_number erg = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
[8e56ad] | 296 | mpz_init(erg); |
---|
[af378f7] | 297 | if (mpz_divisible_p((int_number) a, (int_number) b)) |
---|
[275ecc] | 298 | { |
---|
[8e56ad] | 299 | mpz_divexact(erg, (int_number) a, (int_number) b); |
---|
| 300 | return (number) erg; |
---|
[275ecc] | 301 | } |
---|
| 302 | else |
---|
| 303 | { |
---|
[8e56ad] | 304 | int_number gcd = (int_number) nrnGcd(a, b, NULL); |
---|
| 305 | mpz_divexact(erg, (int_number) b, gcd); |
---|
| 306 | if (!nrnIsUnit((number) erg)) |
---|
| 307 | { |
---|
[12ea9d] | 308 | WarnS("Division not possible, even by cancelling zero divisors."); |
---|
[8e56ad] | 309 | WarnS("Result is zero."); |
---|
[12ea9d] | 310 | mpz_set_ui(erg, 0); |
---|
[31e857] | 311 | nrnDelete((number*) &gcd, NULL); |
---|
[12ea9d] | 312 | return (number) erg; |
---|
[8e56ad] | 313 | } |
---|
[31e857] | 314 | // a / gcd(a,b) * [b / gcd (a,b)]^(-1) |
---|
| 315 | int_number tmp = (int_number) nrnInvers((number) erg); |
---|
[8e56ad] | 316 | mpz_divexact(erg, (int_number) a, gcd); |
---|
[12ea9d] | 317 | mpz_mul(erg, erg, tmp); |
---|
[31e857] | 318 | nrnDelete((number*) &gcd, NULL); |
---|
| 319 | nrnDelete((number*) &tmp, NULL); |
---|
[8e56ad] | 320 | mpz_mod(erg, erg, nrnModul); |
---|
| 321 | return (number) erg; |
---|
[275ecc] | 322 | } |
---|
| 323 | } |
---|
| 324 | |
---|
| 325 | number nrnIntDiv (number a,number b) |
---|
| 326 | { |
---|
[bac8611] | 327 | int_number erg = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
[8e56ad] | 328 | mpz_init(erg); |
---|
[af378f7] | 329 | if (a == NULL) a = (number) nrnModul; |
---|
[8e56ad] | 330 | mpz_tdiv_q(erg, (int_number) a, (int_number) b); |
---|
| 331 | return (number) erg; |
---|
[275ecc] | 332 | } |
---|
| 333 | |
---|
| 334 | nMapFunc nrnSetMap(ring src, ring dst) |
---|
| 335 | { |
---|
| 336 | return NULL; /* default */ |
---|
| 337 | } |
---|
| 338 | |
---|
| 339 | /* |
---|
| 340 | * set the exponent (allocate and init tables) (TODO) |
---|
| 341 | */ |
---|
| 342 | |
---|
[12ea9d] | 343 | void mpz_set_ull(int_number res, unsigned long long xx) |
---|
| 344 | { |
---|
| 345 | unsigned long h = xx >> 32; |
---|
| 346 | mpz_set_ui (res, h); |
---|
| 347 | mpz_mul_2exp (res, res, 32); |
---|
| 348 | mpz_add_ui (res, res, (unsigned long) xx); |
---|
| 349 | } |
---|
| 350 | |
---|
[275ecc] | 351 | void nrnSetExp(int m, ring r) |
---|
| 352 | { |
---|
[12ea9d] | 353 | if ((nrnBase == r->ringflaga) && (nrnExponent == r->ringflagb)) return; |
---|
| 354 | nrnBase = r->ringflaga; |
---|
| 355 | nrnExponent = r->ringflagb; |
---|
[07b6ac] | 356 | if (nrnModul == NULL) |
---|
[12ea9d] | 357 | { |
---|
[07b6ac] | 358 | nrnModul = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
| 359 | mpz_init(nrnModul); |
---|
| 360 | nrnMinusOne = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
| 361 | mpz_init(nrnMinusOne); |
---|
[12ea9d] | 362 | } |
---|
| 363 | mpz_set_ull(nrnModul, nrnBase); |
---|
| 364 | mpz_pow_ui(nrnModul, nrnModul, nrnExponent); |
---|
[8e56ad] | 365 | mpz_sub_ui(nrnMinusOne, nrnModul, 1); |
---|
[275ecc] | 366 | } |
---|
| 367 | |
---|
| 368 | void nrnInitExp(int m, ring r) |
---|
| 369 | { |
---|
[12ea9d] | 370 | nrnSetExp(m, r); |
---|
[093f30e] | 371 | |
---|
[12ea9d] | 372 | if (mpz_cmp_ui(nrnModul,2) <= 0) |
---|
[275ecc] | 373 | { |
---|
[093f30e] | 374 | WarnS("nrnInitExp failed"); |
---|
[275ecc] | 375 | } |
---|
| 376 | } |
---|
| 377 | |
---|
| 378 | #ifdef LDEBUG |
---|
[85e68dd] | 379 | BOOLEAN nrnDBTest (number a, const char *f, const int l) |
---|
[275ecc] | 380 | { |
---|
[8e56ad] | 381 | if ( (mpz_cmp_si((int_number) a, 0) < 0) || (mpz_cmp((int_number) a, nrnModul) > 0) ) |
---|
[275ecc] | 382 | { |
---|
| 383 | return FALSE; |
---|
| 384 | } |
---|
| 385 | return TRUE; |
---|
| 386 | } |
---|
| 387 | #endif |
---|
| 388 | |
---|
| 389 | void nrnWrite (number &a) |
---|
| 390 | { |
---|
[8e56ad] | 391 | char *s,*z; |
---|
| 392 | if (a==NULL) |
---|
| 393 | { |
---|
| 394 | StringAppendS("o"); |
---|
| 395 | } |
---|
| 396 | else |
---|
| 397 | { |
---|
| 398 | int l=mpz_sizeinbase((int_number) a, 10); |
---|
| 399 | if (a->s<2) l=si_max(l,mpz_sizeinbase((int_number) a,10)); |
---|
| 400 | l+=2; |
---|
| 401 | s=(char*)omAlloc(l); |
---|
| 402 | z=mpz_get_str(s,10,(int_number) a); |
---|
| 403 | StringAppendS(z); |
---|
| 404 | omFreeSize((ADDRESS)s,l); |
---|
| 405 | } |
---|
[275ecc] | 406 | } |
---|
| 407 | |
---|
[8e56ad] | 408 | /*2 |
---|
| 409 | * extracts a long integer from s, returns the rest (COPY FROM longrat0.cc) |
---|
| 410 | */ |
---|
[85e68dd] | 411 | static const char * nlCPEatLongC(char *s, MP_INT *i) |
---|
[275ecc] | 412 | { |
---|
[85e68dd] | 413 | const char * start=s; |
---|
[af378f7] | 414 | if (!(*s >= '0' && *s <= '9')) |
---|
| 415 | { |
---|
| 416 | mpz_init_set_si(i, 1); |
---|
| 417 | return s; |
---|
| 418 | } |
---|
| 419 | mpz_init(i); |
---|
[8e56ad] | 420 | while (*s >= '0' && *s <= '9') s++; |
---|
| 421 | if (*s=='\0') |
---|
[275ecc] | 422 | { |
---|
[8e56ad] | 423 | mpz_set_str(i,start,10); |
---|
| 424 | } |
---|
| 425 | else |
---|
| 426 | { |
---|
| 427 | char c=*s; |
---|
| 428 | *s='\0'; |
---|
| 429 | mpz_set_str(i,start,10); |
---|
| 430 | *s=c; |
---|
[275ecc] | 431 | } |
---|
| 432 | return s; |
---|
| 433 | } |
---|
| 434 | |
---|
[85e68dd] | 435 | const char * nrnRead (const char *s, number *a) |
---|
[275ecc] | 436 | { |
---|
[bac8611] | 437 | int_number z = (int_number) omAllocBin(gmp_nrn_bin); // evtl. spaeter mit bin |
---|
[275ecc] | 438 | { |
---|
[85e68dd] | 439 | s = nlCPEatLongC((char *)s, z); |
---|
[275ecc] | 440 | } |
---|
[8e56ad] | 441 | *a = (number) z; |
---|
[275ecc] | 442 | return s; |
---|
| 443 | } |
---|
| 444 | #endif |
---|