Prjalp2 コーディング要点

  alpinc2.h             ヘッダファイル（素数関数）

下記内容と、上記のヘッダファイルに書かれていることを合わせて参照してください。

1.素数テーブル操作
 エラトステネスの篩のアルゴリズムを利用して素数テーブルを作成します。
 (1)素数テーブルの作成
  __int64 *adr0; /*素数テーブルの参照アドレス*/

  adr0 = _primenew(128);  /* １２８ＭＢ のエリアを動的に確保して素数テーブルを作成します。 */

  素数関数は素数テーブル(adr0)を参照して処理します。

  動的に確保可能なサイズは実行するＰＣのメモリサイズに依存します。
  １２８０ＭＢの確保サイズの場合は１０分前後の処理時間が必要です。
  プログラム仕様上は４０９６ＭＢ超の素数テーブルを作成できます。

 (2)素数テーブルのファイル処理
__int64 rcd; /* 関数の戻りコード 0:正常終了 -1:処理できない */

 rcd = _writeprim((char *)"prime.dat", adr0);  /* adr0に作成した素数テーブルを prime.datに出力します。*/

 大きな素数テーブルの場合、ファイルを利用すれば次回から素数テーブル作成は不要です。

 adr0 = _readprim((char *)"prime.dat");       /* prime.datから素数テーブルを読み込みます */

 (3)素数テーブルの拡張
__int64 rcd; /* 関数の戻りコード 0:正常終了 -1:処理できない */

  rcd = _primexpd(128, adr0); /* _primenewでadr0に作成した素数テーブルを１２８ＭＢ拡張する  */

 ファイル入力して作成した素数テーブルを拡張するときに利用します。

 (4)素数テーブルの解放
__int64 rcd; /* 関数の戻りコード 0:正常終了 -1:処理できない */

 rcd = _freeprm(adr0);

 プログラム実行中に素数テーブルが不要になった場合に解放します。


2.素数関数
 (1)素数テーブルに関連する関数

__int64	_prmtmax(__int64* p1);
//
//   素数テーブル上の最大の素数を求める
//
//   p1(rcx) 素数テーブルのアドレス
//
//   戻り
//		求めた素数
//
__int64	_prmtcnt(__int64* p1);
//
//   素数テーブルに格納されている素数の個数
//
//	p1(rcx)	素数テーブルのアドレス
//
//   戻り
//		求めた個数
//
__int64	_prmtsize(__int64* p1);
//
//   素数テーブルのサイズを求める
//
//   p1(rcx) 素数テーブルのアドレス
//
//   戻り
//		サイズ(クワード数)
//

 (2)素数処理

素数判定は素数テーブルに格納された素数を順に割って判定しています。
１２８ＭＢの素数テーブルの最大素数は4697619557(=0x117fffc65)です。
4697619557^2の数値は６４ビットを超えるので６４ビット超の数値処理が必要です。
したがって、素数処理は１２８ビット数値で行います。


__int64	_prmnoth(__int64 p1, __int64* p2);
//
//   ｎ番目の素数
//
//	p1(rcx)	ｎ
//	p2(rdx)	素数テーブルのアドレス
//
//   戻り
//		求めた素数
//		-1	求められない
//

__int64 _primetst(__int64* p1, __int64* p2);
//
//	１２８ビット数値(※)の素数判定
//	※連続する６４ビットエリアに下位、上位の順で格納されている
//
//	p1	１２８ビット数値のアドレス
//	p2	素数テーブル
//
//	戻り
//		0	素数
//		1	素数ではない
//		-1	判定不能
//

__int64	_prmnext(__int64* p1, __int64* p2, __int64* p3);
//
//   指定数値(※)より大きな次の素数を求める
//	※連続する６４ビットエリアに下位、上位の順で格納されている１２８ビット数値
//
//   p1 求めた結果を格納したエリアのアドレス
//   p2 １２８ビット数値のアドレス
//   p3 素数テーブルのアドレス
//
//   戻り
//		0	正常終了
//		-1  求められない
//

__int64 _prmfct(__int64* p1, __int64* p2, __int64* p3);
//
//   １２８ビット数値(※)の素因数分解
//	※連続する６４ビットエリアに下位、上位の順で格納されている
//
//  p1	結果を格納するエリアのアドレス
//	p2	素因数分解する１２８ビット数値
//	p3	素数テーブルのアドレス
//
//   戻り
//		1～ 素因数の個数(1のときは素数)
//       -1  素因数分解できない(範囲外)
//
素因数分解結果(b1以外は各１クワード(8バイト), b1は２クワード(16バイト))
   +------+------*------*       *------+------*------*
   | fnmm |  a1  |  a2  | ,,,,, |  am  |     b1      |
   +------+------*------*       *------+------*------*
          |<-----  mm   -       ------>|<---- n ---->|
    f:0xff
    mm:a1～amの個数(各１クワード)
    n:b1の個数(２クワード)


char* _prmfctput(__int64* p1);
//
//   素因数分解した結果の編集
//
//	 p1(rcx) 素因数分解した結果のアドレス
// 
//   【編集形式】
//   a^ n* b^ n* c^ n, , ,
//   (n = 1 の時は'^n'は表示しない)
//	 "素数です”  結果が素数のとき
// 
//	戻り
//		編集結果を格納したエリアのアドレス
//

3.１２８ビット数値の処理

__int64 q2num[2];   /*１２８ビット数値のエリア定義*/


(1)文字列からの取込み、文字列編集

__int64 _strto128num(__int64* p1, char* p2, __int64 p3);
//
//	数字文字列を１２８ビット数値(※)に変換する
//	※連続する６４ビットエリアに下位、上位の順で格納されている
//
//	p1  １２８ビット数値のアドレス
//	p2  文字列のアドレス
//  	p3  数値変換する文字列の長さ
//
//	戻り
//		0	正常終了
//		-1	変換出来ない(数字以外を検出した)
//

char* _prt128num(__int64* p1);
//
//   １２８ビット数値(※)の編集
//	※連続する６４ビットエリアに下位、上位の順で格納されている
//
//	p1	１２８ビット数値のアドレス
//
//	戻り
//		編集結果を格納したエリアのアドレス
//

(2)四則演算

__int64 _divq2q2(__int64* p1, __int64* p2);
//
//   １２８ビット数値(※)の除算
//	※連続する６４ビットエリアに下位、上位の順で格納されている
//
//	p1	除算される１２８ビット数値のアドレス
//	p2	除算する１２８ビット数値のアドレス
//
//	戻り
//      0	正常終了
//      1	ゼロ割
//		-1	処理できない
//

__int64 _mulq2q2(__int64* p1, __int64* p2);
//
//   １２８ビット数値(※)の乗算
//	※連続する６４ビットエリアに下位、上位の順で格納されている
//
//	p1	乗算される１２８ビット数値のアドレス
//	p2	乗算する１２８ビット数値のアドレス
//
//	戻り
//      0    正常終了
//      -1   オーバーフロー(下位１２８ビットを格納)
//

__int64 _addq2q2(__int64* p1, __int64* p2);
//
//   １２８ビット数値(※)の加算
//	※連続する６４ビットエリアに下位、上位の順で格納されている
//
//	p1	加算される１２８ビット数値のアドレス
//	p2	加算する１２８ビット数値のアドレス
//
//	戻り
//		0	正常終了
//      1	オーバーフローした
//		-1	処理できない
//
//

__int64 _subq2q2(__int64* p1, __int64* p2);
//
//   １２８ビット数値(※)の減算
//	※連続する６４ビットエリアに下位、上位の順で格納されている
//
//	p1	減算される１２８ビット数値のアドレス
//	p2	減算する１２８ビット数値のアドレス
//
//	戻り
//		0	正常終了
//      1	符号が変わった
//		-1	処理できない
//

6.その他

  サンプルプログラムは自由に改変してかまいません。
  また、ほとんどの関数で戻りコードの判定なして記述しています。
  必要に応じて戻りコードの判定を入れたロジックにしてください。

  開発は ＭＡＳＭ６４ ９０％ ＣＰＰ（Ｃ＋＋） １０％ です。
 

以上


2026.8.29(大安) by Boke-jisan