任意精度演算
例

階乗の計算では、非常に素早く非常に大きな数を生成する。方程式などでは他の項との組合せで出現するので、評価の順序を工夫することで、全体の計算では多くの場合（テイラー級数など）それが問題になることはない。階乗の近似値が必要なら、スターリングの近似を使えばよい。正確な値が必要なら、整数型の限界をすぐに超えることが問題となる。浮動小数点数による近似であってもその最大値を超えるのは容易で、対策として階乗の対数による計算に置き換える方法が出てくる。
大きな階乗の正確な値を求めたい場合、特別なソフトウェアが必要となる。以下の擬似コードは、1、1*2、(1*2)*3、((1*2)*3)*4 と順に計算していく手法を使ったものである。
program Factorial ;
  type natural = range 1..integer.last of integer ;
  type radical = range 2..integer.last of integer ;
  type COLUMNS_TYPE = record
    const MAX_LENGTH : natural = 1000 ; (* 十分な桁数を上限とする *)
    values : array [1:MAX_LENGTH] of natural ;
    length : natural ;
    radix : radical ;
    end ;
  
  procedure factorial (const n : natural, var columns : COLUMNS_TYPE) ;
    begin
    columns.length := 1 ;
    columns.values [columns.length] := 1 ; (* 最初は乗法の単位元 1 を設定する *)
    var carry : integer = 0 ;              (* 下の位からの桁上り *)
    for var ci := 1 to columns.length do   (* 桁ごとにループ *)
      begin
      const c = columns.values [ci] * n + carry ;  (* この桁の数との乗算と下の位からの桁上りの和 *)
      columns.values [ci] := c mod columns.radix ; (* 積の下位桁 *)
      carry := c div columns.radix ;               (* 積の上位桁、上の位への桁上り *)
      end ;
    while 0 < carry do
      begin
      if COLUMNS_TYPE.MAX_LENGTH <= columns.length then
        raise OverflowError ;
      columns.length := columns.length + 1 ;                       (* 桁を増やす *)
      columns.values [columns.length] := carry mod columns.radix ; (* 実際に格納 *)
      carry := carry div columns.radix ;                           (* 次の位への桁上り *)
      (* n が基数より大きければ、もう1桁必要になることがある。 *)
      end
    end ;
  
  procedure writeColumns (var column : COLUMNS_TYPE) ;
    begin
    if 36 < columns.radix then raise OutOfRangeError ;
    const DIGITS : array of character = ['0'..'9','A'..'Z'] ; (* 36進法まで対応可能 *)
    for var ci := columns.length downto 1 do
      write (DIGITS [columns.values [ci]]) ; (* 大きい桁から表示 *)
    end ;
  
  begin
  for var n := 1 to 35 do
    begin
    var columns : COLUMNS_TYPE ;
    columns.radix := 10 ; (* 10進法 *)
    factorial (n, columns) ;
    writeColumns (columns) ; writeln (' = !', n)
    end
  end.
この例で、詳細を見てみよう。最も重要なのは、大きな数の表現方法の選択である。この場合、階乗の計算なので整数だけでよく、固定小数点方式で事足りる。基数の冪は0から始まって大きくなっていくので、配列の先頭が0で、後ろの方ほど基数の冪が大きくなるという表現が便利である。配列のインデックスの始点や大きさの指定方法は言語によって異なるが（0から始まる言語と1から始まる言語がある）、一般に計算の必要条件には関係しないので、ここでは単純化するために配列の始点を0ではなく1としている。数字配列のインデックスがその桁の基数の冪と対応するという性質は、ここでは利用していない。
次に重要な決定は、基数を10としたことである。この場合、様々なことを考慮しなければならない。一時変数 c は、1つの桁の乗算結果と前の桁の積からの繰り上がりを加えたものを保持しなければならない。基数が10の場合、16ビット整数であれば32767まで表現できるので十分である。ただし、この例では n 自身が10を基数とする配列になっていないという点で若干ごまかしている。結果としてこの例は n ＞ 3200 などと設定するとうまく動作できなくなる。これがこの擬似コードの暗黙の限界である。一般には n も大きな数として配列で表す必要がある。また、このようなごまかしをしたせいで、一桁の乗算であっても n 全体をかけているため、繰り上がりは次の桁で収まるとは限らず、さらに次の桁にまで持ち越す場合が出てきた。結果を以下に示す。桁位置を合わせるため空白を書き加え、さらに注釈も書き加えてある。
コンピュータでの数値表現の範囲
                                        1 =  1!
                                        2 =  2!
                                        6 =  3!
                                       24 =  4!
                                      120 =  5!   8ビット符号なし  
                                      720 =  6!
                                     5040 =  7!
                                    40320 =  8!  16ビット符号なし
                                   362880 =  9!   
                                  3628800 = 10!   
                                 39916800 = 11!   
                                479001600 = 12!  32ビット符号なし
                               6227020800 = 13!   
                              87178291200 = 14!   
                            1307674368000 = 15!   
                           20922789888000 = 16!   
                          355687428096000 = 17!   
                         6402373705728000 = 18!   
                       121645100408832000 = 19!   
                      2432902008176640000 = 20!  64ビット符号なし
                     51090942171709440000 = 21!   
                   1124000727777607680000 = 22!   
                  25852016738884976640000 = 23!   
                 620448401733239439360000 = 24!   
               15511210043330985984000000 = 25!   
              403291461126605635584000000 = 26!   
            10888869450418352160768000000 = 27!   
           304888344611713860501504000000 = 28!   
          8841761993739701954543616000000 = 29!   
        265252859812191058636308480000000 = 30!   
       8222838654177922817725562880000000 = 31!
     263130836933693530167218012160000000 = 32!
    8683317618811886495518194401280000000 = 33!
  295232799039604140847618609643520000000 = 34! 128ビット符号なし
10333147966386144929666651337523200000000 = 35!
もっと実用的なプログラムを書くなら、コンピュータの計算能力をより効率よく利用するものにすべきである。単純な改良としては基数を100とするか（対応して出力部での変換が必要になる）、または各種変数をより大きくして（例えば32ビット整数）さらに基数を大きく、例えば10,000にする。十進以外の基数から十進数出力への変換には多大な計算を要する。とはいうものの、コンピュータの本来扱える整数の限界に近い基数を使った方が有利である。通常の整数型であれば、その中身が6であろうと10000であろうと操作に要する時間は同じであり、大きい値を格納した方が配列全体としてより大きな数を表せる。コンピュータによっては、積をその桁の値と桁上り（キャリー）に自動的に分ける機能があり、例にある mod と div という操作を必要としない。例えば IBM 1130 では16ビット整数の乗算の積は32ビットで表され、これを2つの16ビット整数として扱うこともできる。その場合、大きな数の基数は65536となり、桁上りは上位16ビットで、桁は下位16ビットということになる。したがって、それらを分ける際に mod や div を必要としない。
プロセッサには存在するキャリーフラグなどを扱えない、などといった理由から、こういったたぐいのプログラミングには高水準言語は不適という面があり、機械語によるハックによって格段に高速な実装が実現できる場合もある。しかし、数値演算のコードはデバッグの難しさもあり、そのあたりのトレードオフもある。高水準言語のソースレベルでポータブルなライブラリが必要な場合、C言語では共用体、あるいは FORTRAN のEQUIVALENCE文や PL/1 の OVERLAY文などを使ったトリック的な書き方で、いずれも一般論としてはあまり薦められない手法とされているものではあるが、実装が可能な場合もある。
1つの桁の乗算において、一時変数は (radix - 1)2 + carry を保持できなければならず、carry の最大値は (base - 1) である。IBM 1130 の場合、レジスタが32ビットなので、16ビットの演算の途中結果が16ビットで表せる範囲を超えても処理を続行できる。高級言語では、大きな数の配列の各要素（つまり桁）を16ビット符号無し整数とし、基数を65536としたとき、桁の乗算結果は 4,294,901,760 を超えないが、32ビット符号あり整数の上限は  2^{31}-1=2,147,483,647 である。高級言語によっては、たとえハードウェアが32ビット符号無し整数の演算をサポートしていても、32ビット符号無し整数（上限は  2^{32}-1=4,294,967,295）をデータ型として使えない場合がある。また、32ビット符号無し整数が使える場合でも、64ビット符号無し整数ではどうだろうか?
同様に、配列のインデックス用変数も16ビットや32ビットという制限がある。64ビット整数をインデックス変数に使えるとしても、今度はメモリ容量の限界という問題がある。さらに大きな数を表すには、適当な大きさのブロックに分け、インデックスとして（ブロック i、桁 j）のように2つの変数を使う方法や、インデックス自体も大きな数として桁ごとの配列で表す方法も考えられる。いずれにしても記憶装置容量の限界は避けられない。