プログラミング

2008年10月02日

メルセンヌ素数を求めるjavaプログラム

GIMPSにより最大の素数が更新されたニュースを見ました。
1000万桁を超えるメルセンヌ素数で2^n -1で表わされ、nも素数になります。

javaには多倍長計算用にBigDecimalが用意されていると言うことなので、エラトステネスの篩で素数を求めて、メルセンヌ素数になるかどうか判定するプログラムを作ってみました。
nは10000までの制限もありますが、まったく最適化に向かないコードで、かなり遅いです。

最初J#で書き始めましたがMSはBigDecimalを実装してないので、あらためてeclipse(windows版)のインストールから始めましたが、5時間で18番目のメルセンヌ素数が出てきました。

//実行結果(実行中)
メルセンヌ素数を探します。
0:2:55: 2^3-1 = 7
0:2:55: 2^5-1 = 31
0:2:55: 2^7-1 = 127
0:2:55: 2^13-1 = 8191
0:2:55: 2^17-1 = 131071
0:2:55: 2^19-1 = 524287
0:2:55: 2^31-1 = 2147483647
0:2:55: 2^61-1 = 2305843009213693951
0:2:55: 2^89-1 = 618970019642690137449562111
0:2:55: 2^107-1 = 162259276829213363391578010288127
0:2:55: 2^127-1 = 170141183460469231731687303715884105727
0:3:10: 2^521-1 = 6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151
0:3:22: 2^607-1 = 531137992816767098689588206552468627329593117727031923199444138200403559860852242739162502265229285668889329486246501015346579337652707239409519978766587351943831270835393219031728127
0:11:44: 2^1279-1 = 10407932194664399081925240327364085538615262247266704805319112350403608059673360298012239441732324184842421613954281007791383566248323464908139906605677320762924129509389220345773183349661583550472959420547689811211693677147548478866962501384438260291732348885311160828538416585028255604666224831890918801847068222203140521026698435488732958028878050869736186900714720710555703168729087
1:12:32: 2^2203-1 = 1475979915214180235084898622737381736312066145333169775147771216478570297878078949377407337049389289382748507531496480477281264838760259191814463365330269540496961201113430156902396093989090226259326935025281409614983499388222831448598601834318536230923772641390209490231836446899608210795482963763094236630945410832793769905399982457186322944729636418890623372171723742105636440368218459649632948538696905872650486914434637457507280441823676813517852099348660847172579408422316678097670224011990280170474894487426924742108823536808485072502240519452587542875349976558572670229633962575212637477897785501552646522609988869914013540483809865681250419497686697771007
1:23:45: 2^2281-1 = 446087557183758429571151706402101809886208632412859901111991219963404685792820473369112545269003989026153245931124316702395758705693679364790903497461147071065254193353938124978226307947312410798874869040070279328428810311754844108094878252494866760969586998128982645877596028979171536962503068429617331702184750324583009171832104916050157628886606372145501702225925125224076829605427173573964812995250569412480720738476855293681666712844831190877620606786663862190240118570736831901886479225810414714078935386562497968178729127629594924411960961386713946279899275006954917139758796061223803393537381034666494402951052059047968693255388647930440925104186817009640171764133172418132836351
5:2:38: 2^3217-1 = 259117086013202627776246767922441530941818887553125427303974923161874019266586362086201209516800483406550695241733194177441689509238807017410377709597512042313066624082916353517952311186154862265604547691127595848775610568757931191017711408826252153849035830401185072116424747461823031471398340229288074545677907941037288235820705892351068433882986888616658650280927692080339605869308790500409503709875902119018371991620994002568935113136548829739112656797303241986517250116412703509705427773477972349821676443446668383119322540099648994051790241624056519054483690809616061625743042361721863339415852426431208737266591962061753535748892894599629195183082621860853400937932839420261866586142503251450773096274235376822938649407127700846077124211823080804139298087057504713825264571448379371125032081826126566649084251699453951887789613650248405739378594599444335231188280123660406262468609212150349937584782292237144339628858485938215738821232393687046160677362909315071


//2008/10/1 少し判り易く修正
//さらに改修
//テストプログラム
import java.io.*;
import java.math.*;
import java.util.*;

//メルセンヌ素数をLucas-Lehmerテストによって確認するクラス
public class Mersenne {
static BigDecimal number2 = new BigDecimal(2);

static BigDecimal number1 = new BigDecimal(1);

static BigDecimal zero = new BigDecimal(0);

// Lucas-Lehmerテストによって素数を判別する
public static boolean IsMersenne(int sosu) {
BigDecimal worknumber = new BigDecimal(4);
BigDecimal merse = new BigDecimal(2);
BigDecimal result[] = new BigDecimal[2];
int i;
for(i=1; i merse = merse.multiply(number2);
}
merse = merse.subtract(number1);

for (i = 2; i < sosu; i++) {
worknumber = worknumber.multiply(worknumber);
worknumber = worknumber.subtract(number2);
result = worknumber.divideAndRemainder(merse);
worknumber = result[1];
}
result = worknumber.divideAndRemainder(merse);
if (result[1].compareTo((zero)) == 0) {
Calendar cal = Calendar.getInstance();
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minu = cal.get(Calendar.MINUTE);
int sec = cal.get(Calendar.SECOND);
System.out.println(hour + ":" + minu + ":" + sec + ": 2^" + sosu
+ "-1 = " + merse);
return true;
}
return false;
}

/**
* @param args
*/
public static void main(String[] args) {
long time = System.currentTimeMillis();

System.out.println("メルセンヌ素数を探します。");
// エストラネスの篩を使ってmaxnumberまでの素数を探す
int maxnumber = 10000;
byte sosu[] = new byte[maxnumber];
for (int i = 2; i < maxnumber; i++) {
if (sosu[i] != 0) {
// 合成数
continue;
}
//素数なのでメルセンヌ素数になるかチェックする
if (IsMersenne(i)) {
}
//合成数を篩にかける
int j = i * 2;
while (j < maxnumber) {
sosu[j] = 1;
j = j + i;
}
}
System.out.println("総実行時間:" + (System.currentTimeMillis() - time)
+ "msec");
}
}


yamama009ma at 11:59|この記事のURLComments(0)TrackBack(0)

2008年07月27日

JPGGPSMODIFY

JPEG画像のGPS位置情報からGoogleMap上に位置を表示するプログラムを修正し、
GPS位置情報を修正するプログラムを追加しました。
位置情報を直接入力するか、位置の差分値から、撮影対象に位置に修正する時などに使うことを想定しています。

呼び出すGoogleMapのurlとパラメータも変更しました。
こちらのurlの場合マップ上に緯度経度の表示とバルーンが表示されています。
例 http://maps.google.co.jp/?q=35.894469,139.634050
このマップ上から撮影した対象物の座標を「ここへのルート」として選択すると新しい座標が表示されますので、変更先の座標として使えます。

http://www.ksky.ne.jp/~yamama/
http://www.ksky.ne.jp/~yamama/jpggpsmap/manual.htm


yamama009ma at 18:55|この記事のURLComments(0)TrackBack(0)

2008年07月04日

JPEG画像のGPS情報からGoogleMapへ

GPSの位置情報は利用方法が広がりそうで。

先週携帯で撮影した画像のEXIF情報にGPS情報が入っていたので、他の人が作ったツールやVBスクリプトで取り出してみてましたが、やっぱりVBSは使い難いです。

VBSは捨てて、C++よりイージーなC#でGPS情報を取り出すアプリを作り、撮影した位置をGoogleMapで表示するようにしてみました。
撮影地点を見てみるという最初の目的は達しましたが、もう少し使ってるうちに欲しくなる機能が膨らむかどうか。
GoogleMapAPIを使えば楽しい表示ができるかどうか。

ネット上の多くのJPEG画像にGPS情報が含まれているという記事が載ってましたが、探してみると全然ないので、観光写真や携帯の画像ではなくて、学術用や報道用なのかもしれません。

JPEGからGoogleMapを表示するアプリC#版
http://www.ksky.ne.jp/~yamama/jpggpsmap/manual.htm

yamama009ma at 10:44|この記事のURLComments(0)TrackBack(0)

2008年05月31日

InternetExplorerのタイムアウトを変更

InternetExplorer7(IE7)になって、サーバーからの応答を待つタイムアウトの設定が30秒と短くなっています。
応答の遅いDBサーバの場合でもIE6以前と同じようにタイムアウトを長く設定する為、レジストリを設定しました。

MicroSoftのサポートページ
http://support.microsoft.com/kb/181050/ja

1. 以下のレジストリ キーに、ReceiveTimeout という DWORD 値を追加して、値のデータを <秒数>*1000 に設定します。
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings
たとえば、タイムアウトの時間を 8 分に設定するには、ReceiveTimeout を 480000 (480*1000) に設定します。
2. コンピュータを再起動します。

注 : この設定は、Internet Explorer 4.0 SP1 より前のバージョンの Internet Explorer では機能しません。


yamama009ma at 10:16|この記事のURLComments(1)TrackBack(0)

2008年05月06日

状況依存ヘルプ

ダイアログの?をクリックしてコントロールのバルーンヘルプを表示するには、HelpWorkShopで作成したヘルプファイルをインストールします。

ヘルプファイルの作成手順
PRTGRAPH.hpjプロジェクトファイルを作成し、MicrosoftWordを使ってrtf形式でヘルプファイルを作成します。
検索項目を脚注として挿入し、1ページに1項目作成します。
脚注と検索番号をヘッダファイルで定義して、ヘルプコンパイラを起動してコンパイルするとprtgraph.hlpファイルが作成されます。



yamama009ma at 14:15|この記事のURLComments(0)TrackBack(0)

PRTGRAPHにイベントログと状況依存ヘルプを追加

PRTGRAPHにイベントログの追加、状況依存ヘルプの追加
コードの一部修正を行って更新しました。ver1.1.4.9

イベントログではイベントビューアのアプリケーションログに印刷エラーや画像変換のエラーを記録します。
イベントログの登録には
RegiserEventSource()によりイベントログのハンドルを取得して
ReportEvent()によりエラー番号を登録します。
DeregisterEventSourceによりハンドルを閉じます。

またイベントログにメッセージを表示させるためには
イベントログに対応したメッセージをDLL等にリンクしてレジストリに登録する必要があります。
メッセージはprtgraph.mcファイルに以下のような形式で作成します。

MessageId=2
Severity=Error
Facility=Error
SymbolicName=MSG_OUTPUT_WRITE_ERROR
Language=Japanese
出力画像ファイルの作成に失敗しました。%n
出力先の空き容量の確認をしてください。

メッセージファイルは
mc prtgraph.mcとして変換しリソースファイルprtgraph.rcとprtgraphmsg.bin等に変換します
レジストリはWindowsInstallerで登録しますが、HKLM/System/CurrentControlSet/Services/EventLog/Application/PRTGRAPH/EventMessageFileにDLLファイルのパスを登録します。

以上でイベントビューアに登録されたエラーのメッセージ表示が可能になります。



yamama009ma at 11:47|この記事のURLComments(1)TrackBack(0)

2008年03月23日

カスタム用紙の作成アプリケーションを追加

WindowsアプリケーションとしてPRTGRAPHのカスタム用紙作成プログラムを追加しました。
規定のサイズの用紙A4等と比較しながら、mm,インチ、ピクセル数からカスタム用紙を作成できます。
ただしPRTGRAPHの登録ユーザ専用です。
フリーバージョンでは用紙名は固定ですが従来通りaddform.exeを使用できます。
PRTPAPER カスタム用紙を作成

yamama009ma at 23:43|この記事のURLComments(0)TrackBack(0)

2008年02月24日

PRTGRAPHにカスタムサイズの用紙を追加する方法

PRTGRAPHは仮想プリンタですので、出力画像の用紙サイズを自由に指定する事ができます。
version1.1.4.6にコマンドラインからカスタムサイズの用紙を追加する為のプログラムaddform.exeを追加しました。

またプログラムから指定する場合はプリンタ用のAPIを使うことで同様に設定出来ます。

Windows2000,xp,vistaではカスタムサイズの用紙としてプリンタにFormを追加して使用します。
最初にPRTGRAPHプリンタをOpenPrinter()により開きます。
Formには追加する用紙名と用紙サイズを設定し、
AddForm()で追加します。
最後にClosePrinter()で閉じるとPRTGRAPHプリンタに指定の用紙が追加されます。
addform.exeでは用紙名PRTGRAPH_UserPaperを追加していますが、
AddForm()を使用すると幾つでも追加できます。

Formで指定する用紙のサイズは1/1000mm単位になりますので、出力されるピクセル数は
size/1000/25.4*dpiになります。

画像は96dpiで200mm X 200mmのカスタム用紙に透かしを設定して出力したものです。
カスタムサイズの用紙

yamama009ma at 00:41|この記事のURLComments(0)TrackBack(0)

2008年02月17日

プログラムからPRTGRAPHの設定を行う方法

PRTGRAPHの設定はプロパティを開きデバイス設定タブから行いますが、
バッチやコマンドプロンプトから変更したい場合は1.1.4.5に同梱しsetprtgraph.exeを利用できます。

プログラムから設定する場合はOpenPrinter()でPRTGRAPHプリンタのハンドルを開き、SetPrinterData()を使ってプリンタのレジストリPrinterDariverDataのキーを設定する事ができます。

このAPIを使うには #include <winspool.h>を宣言します。
OpenPrinter()の第1引数には TEXT("PRTGRAPH virtual printer")を
第2引数には受け取るハンドル HANDLE hPrinterを
第3引数にはアクセス属性を設定するため PRINTER_DEFAULTS Defaultを設定します。

 TCHAR pPrinterName[]=TEXT("PRTGRAPH virtual printer");
 HANDLE hPrinter;
 PRINTER_DEFAULTS Default = {NULL, NULL, PRINTER_ALL_ACCESS};
 BOOL bres = OpenPrinter(pPrinterName, &hPrinter, &Default);
 if(FALSE == bres){
    printf("Can't open printer %ws\n", pPrinterName);
    return bres;
 }
//パラメータはSetPrinterData()またはSetPrinterDataEx()APIで指定します。
 wres = SetPrinterDataEx(hPrinter,strprimkey[keytbl[idx].primkey], keytbl[idx].regkey, keytbl[idx].type, (LPBYTE)argv[2], (DWORD)wcslen(argv[2])*sizeof(TCHAR));
//最後はハンドルを閉じます。
ClosePrinter(hPrinter);


yamama009ma at 19:55|この記事のURLComments(0)TrackBack(0)

2008年01月21日

PRTGRAPHの透かし正式版リリース

透かし仕様をリリースしました。
組み込みの透かし画像の容量が大きかったので、モノクロに変換しました。
単純に1/24のサイズになりました。
ユーザ指定画像ならgif,jpeg,pngのカラー画像も指定できます。
透かし合成に使っているアルファブレンドの合成率は10%ですが将来的には指定できるようにする必要があるかも知れません。
埋め込み画像は縦横4倍までは拡大してサイズを合わせますが、それ以上は4倍固定です。
組み込み文字列は「秘」「社外秘」「部外秘」「複写禁止」「回覧」「サンプル」があります。


yamama009ma at 11:16|この記事のURLComments(6)TrackBack(0)