No.11ベストアンサー
- 回答日時:
#8>RoundingModeでエラーが出てしまいます。
#10の方がおっしゃる通りなので、
RoundingMode.HALF_EVEN
の部分は、
BigDecimal.ROUND_HALF_EVEN
で置き換えてみて下さい。(importもいらない)
>divide(BigDecimal val, int scale, int roundingMode)
でいう
「int roundingMode」は、数値の丸め方をintで指定したモノで処理するということです。
ここで指定できるintは、BigDecimalのpublic static final intとして定義されていますので、BigDecimal.ROUND_XXXXXXで使うことができます。
回答ありがとうございます。
書き方を変えたらエラーが全て消えました。
BigDecimal.ROUND_~は四捨五入や切り上げなどを行うようなものみたいですね。
全くわかりませんでした。
今は、Math.PIなどを使わずにBigDecimalのみでやっています。
円周率を出すにもイロイロな方法があるので驚きました。
今は記述するのに楽そうなものを使っていますが、なぜか3.30...とか出てしまいます。
No.10
- 回答日時:
こんばんは。
#5です。
>RoundingModeがイマイチよく理解できません。
RoundingModeクラスはJDK1.5から追加されたもので、列挙型として使用されます。
ですので、1.4以前では、普通の整数型の定数を使います。
たとえば、#5で書いた
>BigDecimal answer = x.divide(y, 50, RoundingMode.HALF_UP);
は、1.4以前では使えません。
1.4対応では、
BigDecimal answer = x.divide(y, 50, BigDecimal.ROUND_HALF_UP);
こう書きます。
似ていますが、二つは同じ機能の違うメソッドです。
RoundingMode.HALF_UPは、RoundingModeクラスのインスタンス。
BigDecimal.ROUND_HALF_UPは、整数型の定数という違いがあります。
JDK1.4で勉強されているのなら、RoundingModeクラスのことは、まだ、考えなくていいと思います。
回答ありがとうございます。
>BigDecimal answer = x.divide(y, 50, BigDecimal.ROUND_HALF_UP);
このように書いたらエラーが消えました。
今は、Math.PTやMath.sinなどを使わずにやってみています。
No.9
- 回答日時:
#5です。
>>BigDecimal answer = x.divide(y, 50, RoundingMode.HALF_UP);
>この方法でやってみたのですが、RoundingMode.HALF_UPは解決できません。
>と出てしまいます。
ごめんなさい。
そのメソッドはJDK1.5からでした。
1.4以前なら、
BigDecimal divide(BigDecimal val, int scale, int roundingMode)
http://java.sun.com/j2se/1.4/ja/docs/ja/api/java …
を使ってください。
参考URL:http://java.sun.com/j2se/1.4/ja/docs/ja/api/java …
回答ありがとうございます。
divideでやってみたのですが、エラーが消えませんでした。
divide(BigDecimal val, int scale, int roundingMode)
val:BigDecimalの変数名
scale:桁数
だと思うのですが
roungindModeはこのまま入れればよろしいのでしょうか?
RoundingModeがイマイチよく理解できません。
No.8
- 回答日時:
サンプルを作ってみました。
公式そのままなので、難しいところはないと思います。
(課題ということなので、丸写しするのではなくて、こんな感じでBigDecimalの計算をやるんだなぐらいに思って貰って、円周率を求める公式というのは、他にもいろいろあるので、そういうものやプログラムを検索して、自分でも作ってみてください。ていうか、多分削除されてしまうと思うしね。(削除されるにしても、何をどうしていいかわからん感じなので、書いてみました、このプログラムでは、収束ということを調べないで、これぐらいのループをすれば充分という感じでやってます。変更するなら、収束したかどうかでループを終了するようにしたらいいかと思います。その場合、無限ループに陥らないように、最初は、回数で制限を付けた方がいいかと思います。))
--------------------------------------------------------------------
import java.math.BigDecimal;
import java.math.RoundingMode;
//π/4=tan-1(1)=1-1/3+1/5-1/7+…は、収束が遅すぎる
/* ガウス・ルジャンドルの公式
1.初期値
a = 1
b = 1 / sqrt( 2 )
t = 1 / 4
x = 1
2.a と b が求めようとする精度以上に十分等しくなるまで下の式を反復
y = a
a = ( a + b ) / 2
b = sqrt( b ・ y )
t = t - x ・ ( y - a )^2
x = 2 ・ x
3.収束した a , b および t の値を用いて、πの値は、
π = ( a + b )^2 / ( 4 ・ t )
*/
public final class Pai {
static BigDecimal pai;
static int scale;
static {
Pai.pai = Pai.pai(100);//最初に100桁分求める
}
private Pai(){};
static public BigDecimal sqrt(BigDecimal a, int scale){
/* sqrt(a)=x=(x^2+a)/2x */
scale*=2;//2倍精度
a=a.setScale(scale, RoundingMode.HALF_EVEN);
BigDecimal x = a.divide(new BigDecimal(2), RoundingMode.HALF_EVEN);
int c=(int)Math.round(Math.log(scale)/Math.log(2));
for(int i=0;i<c;i++)
x=x.pow(2).add(a).divide(x.add(x),scale,RoundingMode.HALF_EVEN);
return x.setScale(scale/2, RoundingMode.HALF_EVEN);//精度を戻す
}
static public BigDecimal pai(int scale){
if(Pai.scale==scale){
return Pai.pai;
}
if(Pai.scale > scale){
//要求桁数が保持してる桁数より小さい時は、単に桁数を変換して返す
return pai.setScale(scale, RoundingMode.HALF_EVEN);
}
//要求される桁数が保持している桁数より大きいので、更新する
Pai.scale=scale;
scale*=2;//内部的に2倍の精度で計算する
BigDecimal one = BigDecimal.ONE;
BigDecimal two = new BigDecimal(2);
one=one.setScale(scale);
two=two.setScale(scale);
BigDecimal a = one;
BigDecimal b = one.divide(Pai.sqrt(two, scale), RoundingMode.HALF_EVEN);
BigDecimal t = one.divide(new BigDecimal(4), RoundingMode.HALF_EVEN);
BigDecimal x = one;
BigDecimal y;
int c=(int)Math.round(Math.log(scale)/Math.log(2));
for(int i=0;i<=c;i++){
y = a;
a = a.add(b).divide(two, RoundingMode.HALF_EVEN);
b = Pai.sqrt(b.multiply(y), scale);
t = t.subtract(x.multiply(y.subtract(a).pow(2)));
x = x.add(x);
}
Pai.pai=a.add(b).pow(2).divide(t.multiply(new BigDecimal(4)),scale,RoundingMode.HALF_EVEN);
Pai.pai=pai.setScale(Pai.scale, RoundingMode.HALF_EVEN);
return Pai.pai;
}
public static void main(String ar[]){
BigDecimal sqrt5 = Pai.sqrt(new BigDecimal(5),50);
System.out.println(sqrt5);
System.out.println(sqrt5.multiply(sqrt5));
System.out.println(Pai.pai(100));
System.out.println(Pai.pai(50));
}
}
回答ありがとうございます。
サンプルのほうですが、コピペで試させていただきましたがRoundingModeでエラーが出てしまいます。
setScaleではなく、divideで行ってみたのですが結果は同じでした。。。
No.7
- 回答日時:
こんにちは、ソースを拝見しましたが
あまり自分の言ったことが伝わっていなかったようですね^^;
-------------足し算サンプルコード------------------
/* 全ての変数をBigDecimalに変換(有効桁数が50桁のデータで) */
BigDecimal bd = new BigDecimal("0.00000・・・");
BigDecimal bd2 = new BigDecimal("0.00000・・・");
/* 変換後のBigDecimalどうしで演算 */
bd = bd.add(bd2);
/* 表示 */
System.out.println(bd);
---------------------------------------------------
という意味だったのですが・・・
しかし、この場合すこし難しい気がします。
なぜかというと、
・問題1 精度
この中で使っている「Math.pi」自体がDouble精度のため
14~5桁の精度しか持たないのです。
そのため、この数値を用いて計算しても
50桁の精度の結果を得ることはできません。
・問題2 演算関数
計算に「Math.sin」を使っていますが、
この計算自体double型しか返せません。
また、BigDecimalにこれに相当する演算方法はありません。
有効桁数50桁で表示する際に用いる方法はBigDecimalしか
思いつきませんが、
この場合BigDecimalでも用件を満たすことができそうにありません。
課題であるならば、前提条件と満たすべき課題を
明確に教えていただけますか?
#どこかで認識違いがあるかも??
回答ありがとうございます。
返答が遅れて申し訳ありません。
BigDecimal同士ですと、50桁の計算も行えるようですが。
Math.PTを使うため、どうしてもdoubleが必要不可欠になってしまうみたいです。
課題内容ですが
「円周率πを50桁以上表示するプログラム作成」
です。
No.6
- 回答日時:
#5補足>RoundingMode.HALF_UPは解決できません
import java.math.RoundingMode;
しないとRoundingModeの定数は使えませんです。
#5のリンク先見せて貰いましたけど、
単に、doubleの値をBigDecimalにしているだけなので、
#4>無限まで続いている数値になります
と言われているようなことはありません。
>d = Math.PI;
も
>pi = n * Math.sin(Math.PI / n);
も
単にdoubleの範囲で計算されていて、
その後
bd2 = new BigDecimal(pi);
bd2 = bd2.setScale(60);
としたとしても、有効桁は、setScaleで変更できますけども、
doubleの精度しかありません。
(多くの桁を表示させたとしても、単に表現誤差を表示しているに過ぎません)
もし、計算の目的が円周率を50桁求めることだとしたら、
doubleで計算してBigDecimalにするのではなくて、
初めから、BigDecimalで級数などによって計算しなければいけません。
回答ありがとうございます。
返答が遅くなり申し訳ありません。
>import java.math.RoundingMode;
これも足しましたが、解決できませんと出てしまったのです。
>doubleの精度しかありません。
確かに、d = Math.PI;もpi = n * Math.sin(Math.PI / n);も17,18桁以降は数値が違ってきていました。
>初めから、BigDecimalで級数などによって計算しなければいけません。
これをしたかったのですが、やり方がわからずにできませんでした。
Math.PTを使う時点でdoubleじゃなければダメみたいで。。
No.5
- 回答日時:
こんばんは。
簡単な計算ですけど、これなら、ちゃんと50桁表示されました。
BigDecimal x = new BigDecimal("10");
BigDecimal y = new BigDecimal("3");
BigDecimal answer = x.divide(y, 50, RoundingMode.HALF_UP);
System.out.println(answer);
実際どんなコードを書きましたか?
そのまま載せると企業秘密に触れるとか、何かまずい事がある場合は、再現可能なサンプルでいいので、載せられませんか?
>BigDecimal answer = x.divide(y, 50, RoundingMode.HALF_UP);
この方法でやってみたのですが、RoundingMode.HALF_UPは解決できません。と出てしまいます。
ソースコードのほうです。
http://www.hayasoft.com/peach-heaven/Test.java
学校の課題でやっているものですので、秘密などは無いのです。
No.4
- 回答日時:
質問の意図があまりよくつかめていなかったようです。
申し訳ありません。
つまり、double型で計算した結果を無理やり50桁目まで0埋めしたいということですか?
それならば、無理やりフォーマットしても誤差が見えてしまうだけになりますし、ロジックを組んで無理やり0埋めすべきだとおもいます。
もしそうでなく、最大で50桁までいく可能性があるから、ということならば
計算をdouble等を使って行わずに、全てBigDecimalの関数を使った計算をするべきだと言いたかったのですが・・・
(例に挙げたのは加算だけですが、四則演算全て用意されています。)
計算ロジックの記述は面倒になりますが、
正確な値がほしい場合は、
全ての計算に使う数字をBigDecimalの形にして、BigDecimalの演算メソッドを使って計算を行うべきですね。
0埋めという結果にはならない計算です。
計算結果は0.3333・・・のように無限まで続いている数値になりますので。
>全ての計算に使う数字をBigDecimalの形にして
これも実際行ってみたのですが、やり方が悪いのか"doubleからBigDecimalへのキャストはできません"とエラーが出てしまいます。
No.3
- 回答日時:
これで今47桁まで出ているのですか。
。。まず、現在の構成について
>BigDecimal BD = new BigDecimal("0.000・・・・");
この部分で小数点第50位まであるBigDecimalのインスタンスを作成していますが
>BD = new BigDecimal(d);
でdouble型のdをBigDecimal型にしたもので上書きしてますね。
なので、当然double型での計算時に47桁までしかなければ、そこまでしか表示されません。
対策ですが、
BigDecimalを使うならば計算もBigDecimalでやるべきです。
たとえば以下のようにすれば問題ないはずです。
-------------足し算サンプルコード------------------
BigDecimal bd = new BigDecimal("0.00000・・・");
BigDecimal bd2 = new BigDecimal("0.00000・・・");
bd = bd.add(bd2);
System.out.println(bd);
---------------------------------------------------
回答ありがとうございます。
計算結果として受け取れるのがdoulbeだけで、そのまま表示したら17,18桁くらいでした。
ですが、要求されているのが50桁以上を表示というものですのでBigDecimalを使っています。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 会計ソフト・業務用ソフト エクセルについて 1 2022/06/15 17:39
- Excel(エクセル) エクセルのSUM関数について 4 2023/04/18 10:37
- C言語・C++・C# このプログラミングの問題を教えてほしいです。 キーボードからデータ数nとn個のデータを入力し、平均値 3 2022/12/19 22:51
- Excel(エクセル) エクセルの「セル書式」の「表示形式」で 2 2022/08/07 16:44
- Chrome(クローム) Chromeの描画領域を2分割して異なるスクロール位置を同時に表示させることはできますか 1 2023/03/01 16:53
- テレビ ビエラのHDDに録画した番組を BD-REにダビングすることができません 1 2022/07/09 16:42
- Excel(エクセル) エクセルのセルの書式設定・ユーザー定義の条件設定について 1 2022/08/17 21:56
- Excel(エクセル) 文字列を数式として変換する事はできますか? 6 2022/06/23 10:38
- Excel(エクセル) 1から9まで表示するのに必要なボタン 1 2023/02/05 19:06
- その他(データベース) Accessフォームにて指定のフィールドの平均値を小数点第一位で表示できない 2 2022/08/30 17:19
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
0dの意味を教えてください
-
doubleとintの違い
-
C# ToStringでの数字桁揃えの仕方
-
double型変数値の整数部分のみ...
-
Javaで何パーセント%かを表示...
-
最大値と最小値の求め方
-
実数からの小数部の取得
-
Javaで計算
-
べき乗
-
JAVAのプログラムで、2乗計算...
-
javaで質問です。 文字列2023/2...
-
C言語のポインターに関する警告
-
java キーボード入力された値の...
-
JSPやサーブレットでSystem.out...
-
「例外 *** は対応する try 文...
-
VBAで配列の計算
-
System.err. printlnとSystem.o...
-
[JAVA]try 内の変数を外で!?
-
yyyymmddからyyyy/mm/d...
-
カタカナの小文字を大文字に変...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
おすすめ情報