C言語関係掲示板

過去ログ

No.1184 桁数が多いときの計算について

[戻る] [ホームページ]
No.15502

桁数が多いときの計算について
投稿者---ののむら4(2004/07/14 12:03:44)


scanfについてのご回答ありがとうございました。助かりました。
しかし、プログラムをコンパイルし、いろいろとやっていたら次の疑問が湧き、自己解決できなくなってしまい再びこちらで質問させていただきたく、きました。
たとえば、数1に10000000000000、数2にもおなじ数1とおなじものを入れた場合、結果が-1662697472となってしまい、期待通りのけっかになりません。
初心者的な質問で申し訳ありませんが、解決法などありましたら、ぜひ教えてください。
よろしくお願いいたします。

以下ソース
#include <stdio.h>

void main()
{
int n1, n2, ans;
char op;

printf("数1 をいれてください。");
scanf("%d",&n1);
printf("数2 をいれてください。");
scanf("%d",&n2);
printf("演算子を入れてください。");
scanf("%s",&op);

switch(op)
{
case '+':
ans = n1 + n2;
printf("結果:%d\n", ans);
break;
case '-':
ans = n1 - n2;
printf("結果:%d\n", ans);
break;
case '*':
ans = n1 * n2;
printf("結果:%d\n", ans);
break;
case '/':
ans = n1 / n2;
printf("結果:%d\n", ans);
break;
default:
printf("正しい演算子を入れてください。" );
}
}


No.15504

Re:桁数が多いときの計算について
投稿者---REE(2004/07/14 13:22:23)


>scanfについてのご回答ありがとうございました。助かりました。
>しかし、プログラムをコンパイルし、いろいろとやっていたら次の疑問が湧き、自己解決できなくなってしまい再びこちらで質問させていただきたく、きました。

scanfの時の問題点が解決されていないように見えます。
まず、そちらの解決が先決かと思われます。

>たとえば、数1に10000000000000、数2にもおなじ数1とおなじものを入れた場合、結果が-1662697472となってしまい、期待通りのけっかになりません。
>初心者的な質問で申し訳ありませんが、解決法などありましたら、ぜひ教えてください。
>よろしくお願いいたします。

int型に限りませんが、変数には、扱える値の範囲が決まっています。
それを超えた数値を使用するとオーバーフローが発生するため、ご提示のような症状がおきます。

この問題を回避する手っ取り早い方法は、入力の値に上限を設けることです。
それが許されないのであれば、大きい数値でも扱えるような工夫をしなければいけません。



No.15506

Re:桁数が多いときの計算について
投稿者---ののむら4(2004/07/14 13:35:37)


>scanfの時の問題点が解決されていないように見えます。
>まず、そちらの解決が先決かと思われます。
あ・・・・申し訳ありません、以前のソースを書いてしまいました・・・
以後きおつけます。

>int型に限りませんが、変数には、扱える値の範囲が決まっています。
>それを超えた数値を使用するとオーバーフローが発生するため、ご提示の
>ような症状がおきます。

なるほど、オーバーフローが発生するから、変な結果になるのですね。

>この問題を回避する手っ取り早い方法は、入力の値に上限を設けること。
>それが許されないのであれば、大きい数値でも扱えるような工夫をしなけ
>ればいけません。

了解です。値に上限を設ければいいのですね。
もう少しあがいてみます。
お手数をおかけいたします。感謝です。


No.15509

Re:桁数が多いときの計算について
投稿者---巨大整数(2004/07/14 16:26:50)


>int型に限りませんが、変数には、扱える値の範囲が決まっています。
>この問題を回避する手っ取り早い方法は、入力の値に上限を設けること。
>それが許されないのであれば、大きい数値でも扱えるような工夫をしなけ
>ればいけません。

もし、ののむら4さんがLinuxを使える環境にいらっしゃるのでしたら、
Gnu MP というのを使うのもいいかもしれません。(http://www.swox.com/gmp/)

これを使うとどんなに大きい整数でも扱えます。(多分)

最初の内は使い方とかよくわからないかもしれませんが、Document も
ありますので、それを見ながら簡単なプログラムを作っていけば使えるように
なると思います。
 
【入手とインストール】
 ‐綉HPよりgmp-4.1.3.tar.gzをDL
 適当なディレクトリで
   tar xvfz gmp-4.1.3.tar.gz
cd gmp-4.1.3
./configure
make
make install

【使い方】
 ののむら4さんのプログラムなら

#include <stdio.h>
#include <gmp.h>

void main()
{
  mpz_t n1, n2, ans;
  mpz_init(n1); mpz_init(n2); mpz_init(ans);
  char op;

  printf("数1 をいれてください。");
  gmp_scanf("%Zd",n1);
  printf("数2 をいれてください。");
  gmp_scanf("%Zd",n2);

  ・・・

  mpz_mul(ans, n1, n2);
  gmp_printf("結果:%Zd\n", ans);

  ・・・

  mpz_clear(n1); mpz_clear(n2); mpz_clear(ans);
  
}

みたいな感じで。

コンパイルは
 gcc ファイル名 -lgmp
と -lgmp を付け加えて行ってください。


No.15513

Re:桁数が多いときの計算について
投稿者---ニタチ(2004/07/14 17:44:25)


>>この問題を回避する手っ取り早い方法は、入力の値に上限を設けること。
>>それが許されないのであれば、大きい数値でも扱えるような工夫をしなけ
>>ればいけません。
>
>了解です。値に上限を設ければいいのですね。

 ののむら4さんの環境はわかりませんが・・・、
 10000000000000という数値を扱いたいのなら、
 __int64型やlong long型などを使うといいです。



No.15519

Re:桁数が多いときの計算について
投稿者---巨大整数(2004/07/14 20:34:30)


> ののむら4さんの環境はわかりませんが・・・、
> 10000000000000という数値を扱いたいのなら、
> __int64型やlong long型などを使うといいです。

int型の掛け算程度であれば __int64型やlong long型で十分ですね。

それでも所詮64ビット(10進20桁程度?)までの数しか扱えませんが…。

ここは自分でBigInt型のようなものを作ってみるのもいいかもしれませんね。
昔、RSA暗号か何かの実装の本に作り方が書いてあったような。
ご存知の方いらっしゃいませんか?