Previous Table of Contents Next


The name for the subroutine big_gets_char was picked because it converts a character string to a big integer. This is like intrinsic assignment that converts an integer to a real value when necessary. Indeed, it is possible to use the assignment statement to do the conversion from character to big integer. It is done by extending assignment. The following interface block is placed in the module big_integers to indicate that the module procedure big_gets_char is to be used to extend assignment to the case where the variable on the left side of the assignment is a big integer and the expression on the right side is a character expression:

   public :: assignment (=)
   private :: big_gets_char

   interface assignment (=)
      module procedure big_gets_char
   end interface

Here is what the module big_integers looks like so far:

   module big_integers_module

   integer, parameter, private :: nr_of_decimal_digits = 100

   type, public :: big_integer
      private
      integer, dimension (0 : nr_of_digits) :: digit
   end type big_integer

   interface assignment (=)
      module procedure big_gets_char
   end interface

   public :: assignment (=)
   private :: big_gets_char

   ”contains“

   subroutine big_gets_char (b, c)
      . . .
   end subroutine big_gets_char

   subroutine print_big (b)
      . . .
   end subroutine  print_big

   end module big_integers_module

Any user of the module can use the assignment statement instead of calling a subroutine, which makes the program a lot easier to understand:

   program test_big_1

      use big_integers_module
      type (big_integer) :: b1

      b1 = “71234567890987654321”
      call print_big (b1)
      b1 = “123456789+987654321”  ! Will be huge(b) = 99999…
      call print_big (b1)

   end program test_big_1

With conversion from character strings to big integers using the assignment statement, there is no need to have the subroutine big_gets_char available. It is declared private.

1.2.18.2. Extending Intrinsic Functions to Big Integers

Many of the Fortran intrinsic functions manipulate numeric values, and it is reasonable to extend some of them, such as modulo and sqrt, to have big integer arguments. This is done by writing an interface block and the function to do the computation. This is illustrated by extending the intrinsic function huge so that when given a big integer as argument, it returns the largest possible big integer. This function is tested by the program test_big_2:

   module big_integers_module

       intrinsic huge
       public :: huge
          . . .
       interface huge
          module procedure huge_big
       end interface
         . . .

   contains
      . . .

   function huge_big (b) result (huge_big_result)

      type (big_integer), intent (in) :: b
      type (big_integer) :: huge_big_result

      huge_big_result % digit (0 : nr_of_digits - 1) = 9
      huge_big_result % digit (nr_of_digits) = 0

   end function huge_big
      . . .
   end module big_integers_module

   program test_big_2

      use big_integers_module
      type (big_integer) :: b1
      call print_big (huge (b1))

   end program test_big_2

1.2.18.3. Adding Big Integers

Now that we can assign to a big integer variable and print its value, it would be nice to be able to perform some computations with big integers. Addition can be done with a function that adds just like we do with pencil and paper, adding two digits at a time and keeping track of any carry-over, starting with the rightmost digits. The function big_plus_big does this:

   function big_plus_big (x, y) result (big_plus_big_result)

      type (big_integer), intent (in) :: x, y
      type (big_integer) :: big_plus_big_result
      integer :: carry, temp_sum, n

      carry = 0
      do n = 0, nr_of_digits
         temp_sum = x % digit (n) + y % digit (n) + carry
         big_plus_big_result % digit (n) = modulo (temp_sum, 10)
         carry = temp_sum / 10
      end do

      if (big_plus_big_result % digit(nr_of_digits) /= 0 &
            .or. carry /= 0) then
         big_plus_big_result = huge (big_plus_big_result)
      end if

   end function big_plus_big

We now extend the meaning of addition to our own newly defined type, big_integer. This is done with another interface block, this time with the keyword operator, followed by the operator being extended. The + operator is public, but the subroutine big_plus_big is private:

   interface operator (+)
      module procedure big_plus_big
   end interface

The use of the + operator to add two big integers is tested by the program test_big_3:

   program test_big_3

      use big_integers_module
      type (big_integer) :: b1, b2

      b1 = “1234567890987654321”
      b2 = “9876543210123456789”
      call print_big (b1 + b2)
   end program test_big_3

The value printed by this program is

   11111111101111111110


Previous Table of Contents Next