Changeset 6ea941 in git for kernel/rmodulon.cc


Ignore:
Timestamp:
Jul 3, 2009, 3:14:10 PM (14 years ago)
Author:
Frank Seelisch <seelisch@…>
Branches:
(u'spielwiese', '8e0ad00ce244dfd0756200662572aef8402f13d5')
Children:
e1634d68136a437eacace709df6dc52c3227ad7f
Parents:
a209ec5a023aa3cf7d9f9167a249678feca0047b
Message:
corrected a modulo b in Z/n and Z/2^m


git-svn-id: file:///usr/local/Singular/svn/trunk@11940 2c84dea3-7e68-4137-9b89-c4e89433aadc
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/rmodulon.cc

    ra209ec5 r6ea941  
    22*  Computer Algebra System SINGULAR     *
    33****************************************/
    4 /* $Id: rmodulon.cc,v 1.34 2009-05-22 13:18:12 Singular Exp $ */
     4/* $Id: rmodulon.cc,v 1.35 2009-07-03 13:14:10 seelisch Exp $ */
    55/*
    66* ABSTRACT: numbers modulo n
     
    317317    return (number) erg;
    318318  }
     319}
     320
     321number nrnMod (number a, number b)
     322{
     323  /*
     324    We need to return the number r which is uniquely determined by the
     325    following two properties:
     326      (1) 0 <= r < |b| (with respect to '<' and '<=' performed in Z x Z)
     327      (2) There exists some k in the integers Z such that a = k * b + r.
     328    Consider g := gcd(n, |b|). Note that then |b|/g is a unit in Z/n.
     329    Now, there are three cases:
     330      (a) g = 1
     331          Then |b| is a unit in Z/n, i.e. |b| (and also b) divides a.
     332          Thus r = 0.
     333      (b) g <> 1 and g divides a
     334          Then a = (a/g) * (|b|/g)^(-1) * b (up to sign), i.e. again r = 0.
     335      (c) g <> 1 and g does not divide a
     336          Then denote the division with remainder of a by g as this:
     337          a = s * g + t. Then t = a - s * g = a - s * (|b|/g)^(-1) * |b|
     338          fulfills (1) and (2), i.e. r := t is the correct result. Hence
     339          in this third case, r is the remainder of division of a by g in Z.
     340  */
     341  int_number g = (int_number) omAllocBin(gmp_nrn_bin);
     342  int_number b_abs = (int_number) omAllocBin(gmp_nrn_bin);
     343  int_number r = (int_number) omAllocBin(gmp_nrn_bin);
     344  mpz_init(g);
     345  mpz_init_set(b_abs,(int_number)b);
     346  mpz_init_set_si(r,(long)0);
     347  if (mpz_isNeg(b_abs)) mpz_neg(b_abs, b_abs); // b_abs now represents |b|
     348  mpz_gcd(g, (int_number) nrnModul, b_abs); // g is now as above
     349  if (mpz_cmp_si(g, (long)1) != 0) mpz_mod(r, (int_number)a, g); // the case g <> 1
     350  mpz_clear(g);
     351  mpz_clear(b_abs);
     352  omFreeBin(g, gmp_nrn_bin);
     353  omFreeBin(b_abs, gmp_nrn_bin);
     354  return (number)r;
    319355}
    320356
Note: See TracChangeset for help on using the changeset viewer.