山本ワールド
Windowsプログラミング
アルゴリズム Vitual C++ 2008/2013によるWin32/Win64 APIレベルのプログラム 基礎 Vitual C++ 2008/2013によるAPIレベルのプログラム(32/64bit) Wix3でインストーラーを作る Visual C++ 2008 Standard Editonによるフォームアプリケーションのプログラム(32/64bit) Vitual C++ 2008 Standard EditonによるAPIレベルのプログラム(32/64bit) Windows 7対応 Visual C++ 2008 ExpressによるAPIレベルのプログラム Visual C++ 2005 ExpressによるAPIレベルのプログラム Visual C++ Versiosn 5 BORLAND C++ Windowsプログラム全般 Excel VBA その他円周率計算プログラム(64bit整数による計算)(32/64bit)
ガウス=ルジャンドルのアルゴリズム
初期値
反復式
πの算出
64bit整数型を用いて円周率を計算する
64bit整数型で小数点を表現する
Visual C++の64bit整数型はUINT64です。表現できる数値の範囲は、0~18,446,744,073,709,551,615(10進数で20桁弱)です。
C++での掛け算の結果64bitを超えないようにするには、非乗数・乗数ともに32bit(0~4,294,967,295(10進数で10桁弱))に収まっていれば64bitを超えるとこはありません。
上記の式での円周率の計算では、整数部は1桁もあればよいので、小数点を整数に換算して計算するために1,000,000,000を掛けて計算します。
64bitアセンブラの場合 CPU命令で、64bit*64bit=128bit、128bit/64bit=64bitの計算ができるので、64bitの整数の桁数を有効に活用できます。
平方根の計算
Aの平方根は下記の式で反復すると近似できる初期値は
計算例
0 ,  a0= 1000000000 , b0=707106781 , t0=250000000 , p0=1
1 ,  a1= 853553390 , b1=840896415 , t1=228553391 , p1=2
2 ,  a2= 847224902 , b2=847201266 , t2=228473292 , p2=4
3 ,  a3= 847213084 , b3=847213083 , t3=228473292 , p3=8
4 ,  a4= 847213083 , b4=847213083 , t4=228473292 , p4=16
5 ,  a5= 847213083 , b5=847213083 , t5=228473292 , p5=32
3141592619
ソースコード
// ガウス=ルジャンドルのアルゴリズムによる64bit整数演算を使用した円周率の算定
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#define INT_OFFSET  (UINT64(1000000000))
UINT64 sqrt64(UINT64 src);
int _tmain(void){
        UINT64 a = INT_OFFSET;
        UINT64 a0=0;
        UINT64 b;
        UINT64 t=INT_OFFSET/4;
        UINT64 p=1;
        UINT64 pi;
        b = sqrt64( 2 * INT_OFFSET * INT_OFFSET );
        b = INT_OFFSET*INT_OFFSET / b;
        int n=0;
        _tprintf(_TEXT("%i ,  a%i= %lld , b%i=%lld , t%i=%lld , p%i=%lld\n"),n,n,a,n,b,n,t,n,p);
        do{
                a0 = a;
                a = ( a + b ) / 2;
                b = sqrt64( a0 * b );
                t = t - ( p * (a0 - a) * (a0 - a) ) / INT_OFFSET;
                p = 2 * p;
                ++n;
                _tprintf(_TEXT("%i ,  a%i= %lld , b%i=%lld , t%i=%lld , p%i=%lld\n"),n,n,a,n,b,n,t,n,p);
        }while(a0 != a);
        pi = ( a + b ) * ( a + b ) / ( 4 * t);
        _tprintf(_TEXT("%li\n"),pi);
        return 0;
}
UINT64 sqrt64(UINT64 src){
        UINT64 ans=src/2;
        UINT64 ans0;
        UINT64 t;
        do{
                ans0=ans;
                t=src/ans0;
                ans=(t+ans0)/2;
        }while(ans0 != ans);
        return ans;
}
      Copyright (C) 2012 山本ワールド All Rights Reserved.
    
    
  