C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[10]: べき乗計算の結果


(過去ログ 57 を表示中)

[トピック内 17 記事 (1 - 17 表示)]  << 0 >>

■32652 / inTopicNo.1)  べき乗計算の結果
  
□投稿者/ ドザえもん (1回)-(2009/02/12(Thu) 10:11:26)

分類:[C/C++] 

よろしくお願いします。

趣味で最近プログラミングを勉強しています。
VC++でwindowsのコンソールアプリケーションを作っています。
簡単な算術を使って色々試しているのですが、ひとつ質問をさせてください。

#include <math.h>
#include <iostream>

using namespace std;

void main()
{
double a, b, c;

a = 120;
b = 13;

c = pow(120,13);

cout << c << endl;
cin.ignore();
}

上記のプログラムを走らせると、エラーにはならないのですが表示が変になってしまいます。「E」が入る奴です。
自分は数学が苦手なのでそういう表示ではよくわかりません。
できればwindowsの電卓で表示されるような「10699320537907200000000000000」という表示をしたいです。
intやlongでキャストしても0になってしまうし。
可能でしょうか?
引用返信 編集キー/
■32654 / inTopicNo.2)  Re[1]: べき乗計算の結果
□投稿者/ επιστημη (1701回)-(2009/02/12(Thu) 10:37:13)
επιστημη さんの Web サイト
> 自分は数学が苦手なのでそういう表示ではよくわかりません。
> できればwindowsの電卓で表示されるような「10699320537907200000000000000」という表示をしたいです。

うーん...doubleはそんなにたくさんの有効桁を持っていないので指数表記せざるを得ないんですよね。
全桁きっちり表示するとそれが正確な値であるかのように見えてしまいます。
正しいのはアタマ数桁であることが表現できんのです。
「どうしても」であれば「自分でなんとかせぃ」になるです。

# それに全桁きっちり表示するとなると、1.0/3.0の結果が無限桁になっちゃうです。

引用返信 編集キー/
■32655 / inTopicNo.3)  Re[2]: べき乗計算の結果
□投稿者/ ドザえもん (2回)-(2009/02/12(Thu) 10:56:46)
No32654 (επιστημη さん) に返信

お返事ありがとうございます。
> > うーん...doubleはそんなにたくさんの有効桁を持っていないので指数表記せざるを得ないんですよね。
> 全桁きっちり表示するとそれが正確な値であるかのように見えてしまいます。
> > # それに全桁きっちり表示するとなると、1.0/3.0の結果が無限桁になっちゃうです。

なるほど。
じゃあwindowsの電卓とかはどうやって表示してるんでしょうか?
まぁ、自分でなんとかしとるんでしょうが。
逆に、表示はおかしくても内部で正しい結果を持っているのでしょうか?
この結果を受けて次の計算をするのに、正しい値を保持していないならおかしな事になってきますもんね。
引用返信 編集キー/
■32657 / inTopicNo.4)  Re[3]: べき乗計算の結果
□投稿者/ επιστημη (1702回)-(2009/02/12(Thu) 11:41:00)
επιστημη さんの Web サイト
2009/02/12(Thu) 11:50:39 編集(投稿者)

> じゃあwindowsの電卓とかはどうやって表示してるんでしょうか?
> まぁ、自分でなんとかしとるんでしょうが。

正確な値を表示しているなら、自分でなんとかしとるのでしょう。
内部表現にBCD使ったりとか。あるいは後述する"ごまかし"も考えられます。
なんにせよ無限の桁を表せないかぎり、誤差からは逃れられません。

> 逆に、表示はおかしくても内部で正しい結果を持っているのでしょうか?

無理です。たとえば√2の正しい結果を持つことはできません。
無理数ですから正しい結果の保持には無限のメモリを必要とします。

それに、内部の誤差と表示上の誤差はまた別物。
1を3で割って3倍してぴったり1に戻ったとしても、
適当な丸めをかけて表示しとるかもしれんので。
^^^^^^^^^^^^^^^^^^^^^^
電卓が扱う数値の内部表現として数百桁あったとしても、
表示桁は有限なのでどこかで"ごまかす"しかないわけで。

引用返信 編集キー/
■32658 / inTopicNo.5)  Re[4]: べき乗計算の結果
□投稿者/ ドザえもん (3回)-(2009/02/12(Thu) 11:55:55)
No32657 (επιστημη さん) に返信

> なんにせよ無限の桁を表せないかぎり、誤差からは逃れられません。
確かに。
今作ろうとしているのが簡単な暗号化プログラムなんです。
色々と資料を見ながら作っているのですが、
表現としてはこんな感じのことを実現したいのです。

////////////////////////////////////////////////////////////////
a = 120; //aを最初に用意。

b = (a ^ 13) % 391; //a(120)の13乗を391で割った余りをbに渡す。
////////////////////////////////////////////////////////////////

もちろんこの書き方ではC++ではエラーになるわけですが、内容的に目指しているニュアンスはこんな感じです。
bは型はなんでもかまいません。
やっぱりこの2行を実現するにはガシガシコード書かないとだめですかね?
関数作るなりクラス作るなりで。
引用返信 編集キー/
■32659 / inTopicNo.6)  Re[5]: べき乗計算の結果
□投稿者/ επιστημη (1703回)-(2009/02/12(Thu) 12:02:21)
επιστημη さんの Web サイト
> 今作ろうとしているのが簡単な暗号化プログラムなんです。

整数の範囲で大きな値を誤差なく表現、すなわち「勝手に伸びるソロバン」が
欲しいなら、たとえば BigInteger なんてークラスを作ることになるでしょう。
# 当然"正しい割り算"は無理だけども、暗号が目的なら"(整数)商と余り"が求まればいいのかな。

引用返信 編集キー/
■32660 / inTopicNo.7)  Re[5]: べき乗計算の結果
□投稿者/ 出水 (113回)-(2009/02/12(Thu) 12:16:09)
RSA暗号化ですかね?

普通、大きな数というのは上位の桁を優先して下位の桁を無視しますが、
合同式の場合は、上位の桁は必要ないかわりに下位の桁を重視しますので、自作するしかありません

まともに計算することはまず不可能なので、何らかの特殊な計算方法が必要です。
有名なところだと「バイナリ法」という計算方法が理解しやすいと思いますので
この単語でググってください。
引用返信 編集キー/
■32661 / inTopicNo.8)  Re[5]: べき乗計算の結果
□投稿者/ .SHO (670回)-(2009/02/12(Thu) 12:18:53)
No32658 (ドザえもん さん) に返信

> b = (a ^ 13) % 391; //a(120)の13乗を391で割った余りをbに渡す。

これが、何を意味しているのかわかりませんが
少なくとも、暗号化された値が割り算の余りでは
復号できないので暗号化の処理になってません。
引用返信 編集キー/
■32662 / inTopicNo.9)  Re[6]: べき乗計算の結果
□投稿者/ επιστημη (1704回)-(2009/02/12(Thu) 12:21:05)
επιστημη さんの Web サイト
2009/02/12(Thu) 12:25:37 編集(投稿者)

> 少なくとも、暗号化された値が割り算の余りでは
> 復号できないので暗号化の処理になってません。

なってるんだよな実は♪
適切な値を選べば、元の値は余りから一意に決まります。
鍵さえ知ってればね。

RSA公開鍵暗号のからくりですね > べきの剰余

引用返信 編集キー/
■32663 / inTopicNo.10)  Re[7]: べき乗計算の結果
□投稿者/ .SHO (671回)-(2009/02/12(Thu) 12:26:21)
No32662 (επιστημη さん) に返信

> なってるんだよな実は♪
> 適切な値を選べば、元の値は余りから一意に決まります。
> # 鍵さえ知ってればね。

これ暗号化処理の一部ですね。
失礼しました。
引用返信 編集キー/
■32664 / inTopicNo.11)  Re[5]: べき乗計算の結果
□投稿者/ みきぬ (375回)-(2009/02/12(Thu) 12:31:57)
> a = 120;            //aを最初に用意。
> 
> b = (a ^ 13) % 391; //a(120)の13乗を391で割った余りをbに渡す。

商はどうでもよくて余りだけ必要なのであれば、
a を順に掛けていって、391 の倍数を捨てていけば求まりそうですね。

例えば a = 120 の場合、
120 * 120 = 14400 = 36 * 391 + 324
324 * 120 = 38880 = 99 * 391 + 171
171 * 120 = 20520 = 52 * 391 + 188
188 * 120 = ...

引用返信 編集キー/
■32666 / inTopicNo.12)  Re[8]: べき乗計算の結果
□投稿者/ επιστημη (1705回)-(2009/02/12(Thu) 12:34:06)
επιστημη さんの Web サイト
> これ暗号化処理の一部ですね。

いや「全部」です ^^; ベキの剰余だけで暗号化/復号します。

キモは暗号化と復号に別の鍵を使い、
「暗号鍵を基に復号鍵が得られない」ようになってます。
受信者は復号鍵を秘密にしておき、暗号鍵を公開します。
「俺への手紙はこの鍵で暗号化してね」ってゆっとくわけ。

# ン十年前やってたんで見境なく反応

引用返信 編集キー/
■32667 / inTopicNo.13)  Re[6]: べき乗計算の結果
□投稿者/ επιστημη (1706回)-(2009/02/12(Thu) 12:35:43)
επιστημη さんの Web サイト
2009/02/12(Thu) 12:46:14 編集(投稿者)

> 商はどうでもよくて余りだけ必要なのであれば、
> a を順に掛けていって、391 の倍数を捨てていけば求まりそうですね。

ぴんぽん♪
出水さんの言う「バイナリ法」ってばそゆこと。

無骨に2乗,3乗,4乗,5乗...すんじゃ遅いから、
2乗,4乗,8乗,16乗,32乗...の結果をテケトーに掛け合わせます > バイナリ法

引用返信 編集キー/
■32668 / inTopicNo.14)  Re[7]: べき乗計算の結果
□投稿者/ みきぬ (376回)-(2009/02/12(Thu) 12:40:08)
2009/02/12(Thu) 12:52:16 編集(投稿者)

> ぴんぽん♪
> 出水さんの言う「バイナリ法」ってばそゆこと。
>
あーそっか、ちゃんとヒント書かれてましたね。
#合同式って昔聞いたような気がするけどすっかり忘れていたよママァン

[追記]
ぐぐって感動してきました。
引用返信 編集キー/
■32697 / inTopicNo.15)  Re[8]: べき乗計算の結果
□投稿者/ chobi (18回)-(2009/02/12(Thu) 22:59:22)
分からなくなりましたが、最近どこかのサイト見て作ったencrypt/decryptするソースです。
私も最近暗号にはまっています。(あまり関係ないかもしれませんが、思わず書き込みしてしまいました)
下記に公開鍵と秘密鍵の作り方を単純化したアルゴリズムありますが、実際はもちっと複雑です。
http://itpro.nikkeibp.co.jp/article/COLUMN/20071031/286010/?ST=lin-os
「秘密の国のアリス」という結構人気の暗号の本を読むと良く分かります。

private void button1_Click(object sender, EventArgs e)
{
//公開鍵と秘密鍵の作成
string publickey;
string privatekey;
Crypt.CreateKeys(out publickey, out privatekey);

//TextBox1を暗号化してtextbox2に表示する
textBox2.Text = Crypt.Encrypt(textBox1.Text, publickey);

//textbox2を復号化してtextbox3に表示する
textBox3.Text = Crypt.Decrypt(textBox2.Text, privatekey);

textBox4.Text = publickey;
textBox5.Text = privatekey;

}

}

public class Crypt
{
public static void CreateKeys(out string publicKey, out string privateKey)
{
//RSACryptoServiceProviderオブジェクトの作成
System.Security.Cryptography.RSACryptoServiceProvider rsa =
new System.Security.Cryptography.RSACryptoServiceProvider();

//公開鍵をXML形式で取得
publicKey = rsa.ToXmlString(false);
//秘密鍵をXML形式で取得
privateKey = rsa.ToXmlString(true);
}

public static string Encrypt(string str, string publicKey)
{
//RSACryptoServiceProviderオブジェクトの作成
System.Security.Cryptography.RSACryptoServiceProvider rsa =
new System.Security.Cryptography.RSACryptoServiceProvider();

//公開鍵を指定
rsa.FromXmlString(publicKey);

//暗号化する文字列をバイト配列に
byte[] data = System.Text.Encoding.UTF8.GetBytes(str);
//暗号化する
//(XP以降の場合のみ2項目にTrueを指定し、OAEPパディングを使用できる)
byte[] encryptedData = rsa.Encrypt(data, false);

//Base64で結果を文字列に変換
return System.Convert.ToBase64String(encryptedData);
}

public static string Decrypt(string str, string privateKey)
{
//RSACryptoServiceProviderオブジェクトの作成
System.Security.Cryptography.RSACryptoServiceProvider rsa =
new System.Security.Cryptography.RSACryptoServiceProvider();

//秘密鍵を指定
rsa.FromXmlString(privateKey);

//復号化する文字列をバイト配列に
byte[] data = System.Convert.FromBase64String(str);
//復号化する
byte[] decryptedData = rsa.Decrypt(data, false);

//結果を文字列に変換
return System.Text.Encoding.UTF8.GetString(decryptedData);
}
}
}
引用返信 編集キー/
■32698 / inTopicNo.16)  Re[9]: べき乗計算の結果
□投稿者/ chobi (19回)-(2009/02/12(Thu) 23:02:58)
No32697 (chobi さん) に返信
失礼しました。C++でしたね・・・・
引用返信 編集キー/
■32716 / inTopicNo.17)  Re[10]: べき乗計算の結果
□投稿者/ επιστημη (1716回)-(2009/02/13(Fri) 10:43:02)
επιστημη さんの Web サイト
> 失礼しました。C++でしたね・・・・

C++/CLI なら無問題♪

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -