• ベストアンサー

double型で収まりきれない小数の値を求めたい。

下記のようなプログラムを作っています。 int num = 1000; double d1 = 12345.6; double d2 = 0.0: for(int i=0;i<num;i++){   d2 += Math.pow(d1,(double)i); } d2の値を求めたいのですが、これをこのまま実行すると、得られる数値が大きすぎてd2の値がInfinityになってしまいます。 小数を格納できる最大の型はdouble型ですよね? それに収まりきらないということは、私の求めたい数値はJavaでは求めることが出来ないのでしょうか? それとも何かInfinityになってしまうのを回避する手段はあるのでしょうか? d2で得られた値はそのまま他の計算式で利用するのでどうしてもすべて小数値でなくてはならないのです。 どなたかお知恵をお貸しください。 よろしくお願いします!!

  • kutar
  • お礼率100% (15/15)
  • Java
  • 回答数3
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • UKY
  • ベストアンサー率50% (604/1207)
回答No.3

加減乗除などの基本的な演算しか使えませんが、java.math.BigDecimalというクラスを使うと、どんな大きな/小さな小数も扱えます。 また、java.math.BigIntegerクラスでは、どんな大きな整数も扱えます。こちらは、累乗や余りの計算など、BigDecimalより多少多くの機能があります。 ところで、1番目の型がおっしゃる long double という数値型は、Javaにはありません。プリミティブ値では double が限界です。

kutar
質問者

お礼

やはりBigDecimalクラスですか! この質問を書き込む前にJava関連のHPを探したところ、そのクラスのことが少しだけ書いてあったのですが、今まで使ったことがないもので利用方法が分からず断念してしまいました。 今回は整数部分をlong、小数部分をdoubleに別々に格納することによって何とか対処することができました。 今後のためにも、これからBigDecimalクラスの利用法の学習をしたいと思います。 ありがとうございました! あと余談なんですが、一番目の方がおっしゃってたのはもしかしてC言語だったのでしょうか?(笑)

その他の回答 (2)

  • -soh-
  • ベストアンサー率27% (55/201)
回答No.2

プリミティブ型の限界値を越しているのは確かなんでしょうね。 私が限界値を突破してしまう数値計算をしなければならないとき取った方法を一応書きますと 数値をString型に格納するようにしました。 そいでString型渡しで四則演算できる関数を用意して (中では一桁ずつプリミティブ型に収まりきる程度の値に分割して、少しずつ計算して答えを他のStringに格納、これ繰り返して最後にまた少しずつ答えを足していきました) 越えてしまう数字を計算する。 って方法でやりくりましたよ。 速度は言うまでもなく遅いですけどね(--; それでは(^-^/~~

kutar
質問者

お礼

String型の利用ですか~。 私も少し考えたんですが、やはりその方法でも何とかコーディングできたんですね。 ただ道のりがかなり長そうですが・・・(^^; 今回は整数部分をlong、小数部分をdoubleに別々に格納することによって何とか対処することができました。 -sou-さんのご意見も、大変参考になりました。 ありがとうございました!

  • asuca
  • ベストアンサー率47% (11786/24626)
回答No.1

使っているCによりますが、 long doubleは使えませんか?

kutar
質問者

お礼

今回は整数部分と小数部分を分けて格納することによって何とか対処しました。 ありがとうございました! もしかしたらなんですが、long doubleってC言語ですよね?(笑)

kutar
質問者

補足

Cってなんですか?すみません(^^;; long doubleというと、d2の整数部分と小数部分に分けて格納する、と意味でしょうか?

関連するQ&A

  •  Javaでのある数の小数点乗について

     Javaでのある数の小数点乗について  数学での計算をJavaを使って計算している所です。Javaの中でもDoubleを使うのではなく、BIgDecimalクラスを使って計算をしています。しかし、BigDecimalの値をBigDecimal乗するという事は出来ないですよね? Math.powを使えばDouble型のDouble乗は出来ますが…  そこで、任意の精度で小数点の小数点乗を求める方法は無いでしょうか? 必要ないかもしれませんが参考までに 言語:Java OS:MacOS 10.5

    • ベストアンサー
    • Java
  • JAVAでMath.powを使用せずに、小数を小数で累乗したい

    javaでiアプリを作っているのですが、 iアプリの仕様のせいか、Mathクラスの累乗に関係する関数(pow,log,expなど)、 が使用できません。(使用しているDojaのバージョンは5.0) powの仕組みを使って、小数を小数で累乗するプログラムを作成したいのですが、 教えていただけないでしょうか?

  • 実行結果を倍精度浮動小数点数(double)で表示させたいです

    C言語の勉強をしている大学生です。 プログラミングをしている中で、質問が3つほど出てきました。 互いに関連しているのでまとめて質問させてください。 無限等比級数を計算するプログラムを作成しました。 これをコンパイルして実行すると、double型で定義しているのに 小数点以下7桁となってしまいます。 doubleは15桁ということなので、15桁で出力したいのです。 これが1つめの質問です。 <実行結果> input n:10 1.500000 1.750000 1.875000 1.937500 1.968750 1.984375 1.992188 1.996094 1.998047 pow関数がmath.hに含まれているのかも定かではなく、 インターネットでmath.hというものがあると書いてあったので、 インクルードしてみましたが、これは適切でしょうか? これが2つめの質問です。 最後になりますが、インターネットで多倍長ライブラリというものが あるということを知りましたが、この使用方法がわかれば具体的な例を 挙げながら教えていただきたいと思います。 ------------------------------------------------------------ #include <stdio.h> #include <math.h> int main(void) { int n; int i; double total; printf("input n:"); scanf("%d",&n); if (n<1){ printf("unable\n"); return 0; } for(i=1; i<n; i++){ total += 1.0 / pow(2.0,i); printf("%f\n",total+1.0); } } ------------------------------------------------------------

  • 小数点以下の値を判断したいです

    DBから取得する値が3ならば3と、3.5なら3.5と取得したいです。 この時にint型で取得すると小数点以下が切られてしまいます。 double型で取得すると3.5は3.0となってしまいます。 どうしたらよいのでしょうか? 整数値であればintで小数値を含むならばdoubleで取得するようなロジックにしようかと思っているのですが、小数点以下の値を判別させる方法はありますでしょうか?

  • JAVAのDouble型の小数点以下の値の取扱について

    JAVAのDouble型の小数点以下の値の取扱について JAVA勉強中の超初心者です。 Double aaa = 1.0; Double bbb = 1.1; という値があり、これを最終的にstring型に変換してテキストとして表示しています。 当たり前ですが、aaaなら1.0、bbbなら1.1と表示されます。 でもできれば aaa→1 bbb→1.1 という風に小数点以下が0の場合は表示しないようにしたいのですがどのようにしたらよいか悩んでおります。 単純なことかもしれませんが宜しくお願いします。

    • ベストアンサー
    • Java
  • 小数計算について

    お世話になります。 以下の小数計算方法を教えてください。 時間取得を DWORD start,end; start = start = timeGetTime(); for(int i =0; i<100000; i++){ 何らかの処理; } end = timeGetTime(); int msec = end-start; 上記 msecを1000で割った場合、 小数になるのですが、その場合、小数の変数の型は 何になるのでしょうか? また、求めた小数を用いて、 INT型の変数÷求めた小数 = 小数値(小数第2位まで) を行いたいです。 例えば、 840000 / 64.9 = 12942.99 のような処理をしたいです。 どうぞよろしくお願い致します。

  • 実数の整数部,小数部の取得

    OS:windows2000pro VB:VB6.0sp5 実数 num(変数) [as currency]  (但し 小数点以下2位まで)の値の 1.整数部 num_int(変数) [as long] 2.小数部 num_dec(変数) [as long] を上記変数に格納するのは、どのようにすればいいのでしょうか? (例1)num = 123.02 の場合、num_int=123, num_dec=2 (例2)num = 4.20 の場合、num_int= 4, num_dec=20 (例3)num = 0.23 の場合、num_int= 0, num_dec=23  よろしくお願いいたします

  • javaで1.8x10の308乗÷(ー1.8x10の308)乗割り算をしたいです。

    java初心者です。下記の割り算するプログラムが できません。ご指導下さい。実行結果はコメントどめ しました。 /*num1=1.8x10^308,num2=1.8x10^308としnum1/num2,(-num1)÷(-num2)、num1/0を計算する。 実行結果 C:\keisanclass>java WarizanMain 1.8 1.8 NaN 演算不可能と表示されました。 C:\keisanclass>java WarizanMain -1.8 -1.8 NaN 演算不可能と表示されました。 C:\keisanclass>java WarizanMain 1.8 0 Infinity 無限大と表示されました。 */ class WarizanMain { public static void main(String args[]) { double num1=0.0; double num2=0.0; num1=Double.parseDouble(args[0]); num2=Double.parseDouble(args[1]); double z = Math.pow(10,308); System.out.println((num1*z)/(num2*z)); } }

    • ベストアンサー
    • Java
  • 小数点を含む数値の切捨て

    数値の小数点以下を切捨てて変数に格納したいのですが いい方法はないものでしょうか? "123.456"なら"123"が取得できればOKです。 ちなみに要は小数点より前の数値が取れればということなので $Int = split(/./,"123.456",1) とsplit関数を試してみたんですが、変数$Intには なにも値が取得できてませんでした。 ("."を":"に変えたら取得できました。) 参考書等で色々調べてはみたんですが どうしてもわかりません。 お手数ですが、宜しくお願い致します。

    • ベストアンサー
    • Perl
  • 関数で算出した値を他の関数で使いたい。

    こんにちは。「平均点を出す関数」と「数学の点数のベスト3を出す関数」を使って、「1.平均点」と「2.数学の点数のベスト3の名前とその点数と、各々の点数と平均点との差」を求めるプログラムを作っています。平均点とベスト3の名前とその点数は出せるのですが、「平均点を出す関数」で求めた値をもって来れず、「平均点との差」がうまく表示できません。ソースは下記のようになっております。簡単な修正で直せる方法を教えていただきたいのですが。宜しくお願い致します。 #define STUDENT 4 #include <stdio.h> struct SEISEKI_T {  char name[20]; /* 生徒名を格納する配列。40バイト格納化。 */ int math; /* 数学の点数 */}; typedef struct SEISEKI_T SEISEKI; int average(SEISEKI *sp, int num, int *p); int rank_math(SEISEKI *sp, int num, int *p); int main( ) { SEISEKI seito[STUDENT] = { /* 生徒名と数学の点数のデータ */ { "佐藤", 63},{ "鈴木", 68},{ "高橋", 61},{ "田中", 40}, }; SEISEKI *sp; sp = seito; static int avg[0] = {0}; average(seito, SUBJECT, avg); rank_math(seito, SUBJECT, avg); printf("\n"); return 0; } int average(SEISEKI *sp, int num, int *p) { int i; /* ループ変数 */ static int avg[0] ={0}; for (i = 0; i < 4 ; i++) { avg[0] += (sp + i)->math; } avg[0] = avg[0] / 4 ; printf( "数学 = %3d \n", avg[0]); printf("\n\n"); } int rank_math(SEISEKI *sp, int num, int *p) { int i; /* ループ変数1 */ int j; /* ループ変数2 */ int sa_m = 0; /* 数学の上位成績者の点数と平均点との差。*/ SEISEKI dumy; /* struct SEISEKI_T 型の構造体 dumy */ for ( i = 0 ; i < STUDENT - 1 ; i++ ) { for ( j = 0 ; j < STUDENT - i - 1 ; j++ ) { if( ((sp + j)->math) < ((sp + j + 1)->math) ) { dumy = *(sp + j); *(sp + j) = *(sp + j + 1); *(sp + j + 1) = dumy; } } } printf( "■数学上位成績者\n" ); printf( "----------------------------------\n" ); printf( "順位 名前 点数 平均+\n" ); printf( "----------------------------------\n" ); for ( j = 0 ; j < 3 ; j++ ) { sa_m = (sp + j)->math - *p; printf( " %d %6s %3d %2d\n" , j + 1 , (sp + j)->name , (sp + j)->math , sa_m); } return 0; }

専門家に質問してみよう