Changeset 6ea941 in git


Ignore:
Timestamp:
Jul 3, 2009, 3:14:10 PM (14 years ago)
Author:
Frank Seelisch <seelisch@…>
Branches:
(u'spielwiese', '0d6b7fcd9813a1ca1ed4220cfa2b104b97a0a003')
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
Location:
kernel
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • kernel/numbers.cc

    ra209ec5 r6ea941  
    22*  Computer Algebra System SINGULAR      *
    33*****************************************/
    4 /* $Id: numbers.cc,v 1.22 2009-06-09 18:10:44 Singular Exp $ */
     4/* $Id: numbers.cc,v 1.23 2009-07-03 13:14:10 seelisch Exp $ */
    55
    66/*
     
    367367     n->nDiv   = nr2mDiv;
    368368     n->nIntDiv       = nr2mIntDiv;
     369     n->nIntMod=nr2mMod;
    369370     n->nExactDiv= nr2mDiv;
    370371     n->nNeg   = nr2mNeg;
     
    409410     n->nDiv   = nrnDiv;
    410411     n->nIntDiv= nrnIntDiv;
     412     n->nIntMod= nrnMod;
    411413     n->nExactDiv= nrnDiv;
    412414     n->nNeg   = nrnNeg;
  • kernel/rmodulo2m.cc

    ra209ec5 r6ea941  
    22*  Computer Algebra System SINGULAR     *
    33****************************************/
    4 /* $Id: rmodulo2m.cc,v 1.24 2009-05-06 12:53:49 Singular Exp $ */
     4/* $Id: rmodulo2m.cc,v 1.25 2009-07-03 13:14:10 seelisch Exp $ */
    55/*
    66* ABSTRACT: numbers modulo 2^m
     
    346346}
    347347
     348number nr2mMod (number a, number b)
     349{
     350  /*
     351    We need to return the number r which is uniquely determined by the
     352    following two properties:
     353      (1) 0 <= r < |b| (with respect to '<' and '<=' performed in Z x Z)
     354      (2) There exists some k in the integers Z such that a = k * b + r.
     355    Consider g := gcd(2^m, |b|). Note that then |b|/g is a unit in Z/2^m.
     356    Now, there are three cases:
     357      (a) g = 1
     358          Then |b| is a unit in Z/2^m, i.e. |b| (and also b) divides a.
     359          Thus r = 0.
     360      (b) g <> 1 and g divides a
     361          Then a = (a/g) * (|b|/g)^(-1) * b (up to sign), i.e. again r = 0.
     362      (c) g <> 1 and g does not divide a
     363          Let's denote the division with remainder of a by g as follows:
     364          a = s * g + t. Then t = a - s * g = a - s * (|b|/g)^(-1) * |b|
     365          fulfills (1) and (2), i.e. r := t is the correct result. Hence
     366          in this third case, r is the remainder of division of a by g in Z.
     367    This algorithm is the same as for the case Z/n, except that we may
     368    compute the gcd of |b| and 2^m "by hand": We just extract the highest
     369    power of 2 (<= 2^m) that is contained in b.
     370  */
     371  NATNUMBER g = 1;
     372  NATNUMBER b_div = b;
     373  if (b_div < 0) b_div = - b_div; // b_div now represents |b|
     374  NATNUMBER r = 0;
     375  while ((g < nr2mModul) && (b_div > 0) && (b_div % 2 == 0))
     376  {
     377    b_div = b_div >> 1;
     378    g = g << 1;
     379  } // g is now the gcd of 2^m and |b|
     380
     381  if (g != 1) r = (NATNUMBER)a % g;
     382  return (number)r;
     383}
     384
    348385number nr2mIntDiv (number a,number b)
    349386{
  • kernel/rmodulo2m.h

    ra209ec5 r6ea941  
    44*  Computer Algebra System SINGULAR     *
    55****************************************/
    6 /* $Id: rmodulo2m.h,v 1.11 2009-05-06 12:53:49 Singular Exp $ */
     6/* $Id: rmodulo2m.h,v 1.12 2009-07-03 13:14:10 seelisch Exp $ */
    77/*
    88* ABSTRACT: numbers modulo 2^m
     
    2828number  nr2mDiv         (number a, number b);
    2929number  nr2mIntDiv      (number a,number b);
     30number  nr2mMod         (number a,number b);
    3031number  nr2mNeg         (number c);
    3132number  nr2mInvers      (number c);
  • 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
  • kernel/rmodulon.h

    ra209ec5 r6ea941  
    44*  Computer Algebra System SINGULAR     *
    55****************************************/
    6 /* $Id: rmodulon.h,v 1.11 2009-05-22 16:57:41 Singular Exp $ */
     6/* $Id: rmodulon.h,v 1.12 2009-07-03 13:14:10 seelisch Exp $ */
    77/*
    88* ABSTRACT: numbers modulo n
     
    3232number  nrnGetUnit     (number a);
    3333number  nrnDiv         (number a, number b);
     34number  nrnMod         (number a,number b);
    3435number  nrnIntDiv      (number a,number b);
    3536number  nrnNeg         (number c);
Note: See TracChangeset for help on using the changeset viewer.