Commit 2e45500e by Thomas Quinot Committed by Arnaud Charlet

uintp.ads, uintp.adb (UI_Div_Rem): New subprogram, extending previous implementation of UI_Div.

2007-04-06  Thomas Quinot  <quinot@adacore.com>

	* uintp.ads, uintp.adb (UI_Div_Rem): New subprogram, extending previous
	implementation of UI_Div.
	(UI_Div): Reimplement as a call to UI_Div_Rem.
	(UI_Rem): Take advantage of the fact that UI_Div_Rem provides the
	remainder, avoiding the cost of a multiplication and a subtraction.
	(UI_Modular_Inverse): Take advantage of the fact that UI_Div_Rem
	provides both quotient and remainder in a single computation.
	(UI_Modular_Exponentiation, UI_Modular_Inverse): New modular arithmetic
	functions for uint.
	(UI_Modular_Inverse): Add a note that the behaviour of this subprogram
	is undefined if the given n is not inversible.

From-SVN: r123603
parent d72eef29
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- S p e c -- -- S p e c --
-- -- -- --
-- Copyright (C) 1992-2005, Free Software Foundation, Inc. -- -- Copyright (C) 1992-2006, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -224,6 +224,17 @@ package Uintp is ...@@ -224,6 +224,17 @@ package Uintp is
pragma Inline (UI_Sub); pragma Inline (UI_Sub);
-- Returns difference of two integer values -- Returns difference of two integer values
function UI_Modular_Exponentiation
(B : Uint;
E : Uint;
Modulo : Uint) return Uint;
-- Efficiently compute (B ** E) rem Modulo
function UI_Modular_Inverse (N : Uint; Modulo : Uint) return Uint;
-- Compute the multiplicative inverse of N in modular arithmetics with the
-- given Modulo (uses Euclid's algorithm). Note: the call is considered
-- to be erroneous (and the behavior is undefined) if n is not inversible.
function UI_From_Dint (Input : Dint) return Uint; function UI_From_Dint (Input : Dint) return Uint;
-- Converts Dint value to universal integer form -- Converts Dint value to universal integer form
...@@ -392,18 +403,18 @@ private ...@@ -392,18 +403,18 @@ private
-- a multi-digit format using Base as the base. This value is chosen so -- a multi-digit format using Base as the base. This value is chosen so
-- that the product Base*Base is within the range of allowed Int values. -- that the product Base*Base is within the range of allowed Int values.
-- Base is defined to allow efficient execution of the primitive -- Base is defined to allow efficient execution of the primitive operations
-- operations (a0, b0, c0) defined in the section "The Classical -- (a0, b0, c0) defined in the section "The Classical Algorithms"
-- Algorithms" (sec. 4.3.1) of Donald Knuth's "The Art of Computer -- (sec. 4.3.1) of Donald Knuth's "The Art of Computer Programming",
-- Programming", Vol. 2. These algorithms are used in this package. -- Vol. 2. These algorithms are used in this package.
Base_Bits : constant := 15; Base_Bits : constant := 15;
-- Number of bits in base value -- Number of bits in base value
Base : constant Int := 2 ** Base_Bits; Base : constant Int := 2 ** Base_Bits;
-- Values in the range -(Base+1) .. maxdirect are encoded directly as -- Values in the range -(Base+1) .. Max_Direct are encoded directly as
-- Uint values by adding a bias value. The value of maxdirect is chosen -- Uint values by adding a bias value. The value of Max_Direct is chosen
-- so that a directly represented number always fits in two digits when -- so that a directly represented number always fits in two digits when
-- represented in base format. -- represented in base format.
...@@ -411,10 +422,10 @@ private ...@@ -411,10 +422,10 @@ private
Max_Direct : constant Int := (Base - 1) * (Base - 1); Max_Direct : constant Int := (Base - 1) * (Base - 1);
-- The following values define the bias used to store Uint values which -- The following values define the bias used to store Uint values which
-- are in this range, as well as the biased values for the first and -- are in this range, as well as the biased values for the first and last
-- last values in this range. We use a new derived type for these -- values in this range. We use a new derived type for these constants to
-- constants to avoid accidental use of Uint arithmetic on these -- avoid accidental use of Uint arithmetic on these values, which is never
-- values, which is never correct. -- correct.
type Ctrl is range Int'First .. Int'Last; type Ctrl is range Int'First .. Int'Last;
...@@ -466,11 +477,11 @@ private ...@@ -466,11 +477,11 @@ private
Save_Udigit : Int; Save_Udigit : Int;
end record; end record;
-- Values outside the range that is represented directly are stored -- Values outside the range that is represented directly are stored using
-- using two tables. The secondary table Udigits contains sequences of -- two tables. The secondary table Udigits contains sequences of Int values
-- Int values consisting of the digits of the number in a radix Base -- consisting of the digits of the number in a radix Base system. The
-- system. The digits are stored from most significant to least -- digits are stored from most significant to least significant with the
-- significant with the first digit only carrying the sign. -- first digit only carrying the sign.
-- There is one entry in the primary Uints table for each distinct Uint -- There is one entry in the primary Uints table for each distinct Uint
-- value. This table entry contains the length (number of digits) and -- value. This table entry contains the length (number of digits) and
...@@ -478,11 +489,11 @@ private ...@@ -478,11 +489,11 @@ private
Uint_First_Entry : constant Uint := Uint (Uint_Table_Start); Uint_First_Entry : constant Uint := Uint (Uint_Table_Start);
-- Some subprograms defined in this package manipulate the Udigits -- Some subprograms defined in this package manipulate the Udigits table
-- table directly, while for others it is more convenient to work with -- directly, while for others it is more convenient to work with locally
-- locally defined arrays of the digits of the Universal Integers. -- defined arrays of the digits of the Universal Integers. The type
-- The type UI_Vector is defined for this purpose and some internal -- UI_Vector is defined for this purpose and some internal subprograms
-- subprograms used for converting from one to the other are defined. -- used for converting from one to the other are defined.
type UI_Vector is array (Pos range <>) of Int; type UI_Vector is array (Pos range <>) of Int;
-- Vector containing the integer values of a Uint value -- Vector containing the integer values of a Uint value
...@@ -522,7 +533,7 @@ private ...@@ -522,7 +533,7 @@ private
Table_Name => "Udigits"); Table_Name => "Udigits");
-- Note: the reason these tables are defined here in the private part of -- Note: the reason these tables are defined here in the private part of
-- the spec, rather than in the body, is that they are refrerenced -- the spec, rather than in the body, is that they are referenced directly
-- directly by gigi. -- by gigi.
end Uintp; end Uintp;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment