Pascalの三角形 #9

60段目までPascalの三角形の値を計算すると、
そこに現れる最大値は60段目の中央の値
{}_{60}C_{30}=118264581564861424である。
実際にpascal3.gが生成したグラフ中でname属性が"60_30"のノードのlabel属性は、

$ gvpr -fpascal3.g -a60 | gvpr "N [name == '60_30'] { print(label); }"
118264581564861424

であり一致する。
64ビット符号あり整数の最大値は9223372036854775807なので60段目までの計算ではこれをオーバーしないが、
70段目なら{}_{70}C_{35}=112186277816662845432であり、もはや64ビット整数の範囲を遥かに超える。
実際、計算された"70_35"のノードのlabel属性は、

$ gvpr -fpascal3.g -a70 | gvpr "N [name == '70_35'] { print(label); }"
1505813374405535736

であり、オーバーフローを起こして正しい値になっていないことが分かる。

段数が増えていくとPascalの三角形としては正しくなくなる。
ところが、この誤った値を含むPascalの三角形をsierpinski2.gでフィルタして作成したSierpinskiの三角形は、

$ gvpr -fpascal3.g -a100 | gvpr -c -fsierpinski2.g | dot -Tpng -osierpinski_100.png


となり、確実に誤った値に基づく100段目までのものでも正しく出力されている。
これは、このSierpinskiの三角形ではPascalの三角形の値の2を法とする剰余でノードの白黒を決定するからである。
下位の段の二つの値を加算した時に9223372036854775807=263-1を超えてオーバーフローしても、
2を法とする剰余系で考えれば求められた値は正しい結果となる。
つまり、偶数同士、奇数同士の加算はオーバーフローしても結果は偶数であり、
偶数と奇数との加算の結果はオーバーフローしても奇数になるということである。