- PR -

BigDecimalの有効桁指定について。

1
投稿者投稿内容
未記入
ベテラン
会議室デビュー日: 2005/02/24
投稿数: 55
投稿日時: 2005-09-05 11:23
BigDecimalで有効桁3桁分を表示させようとしています。

具体的には
BigDecimal numA = new BigDecimal("0.00000123456");
BigDecimal numB = new BigDecimal("123456.789012");
でnumAは0.00000123,numBは123456.789といったかんじです。

setScale()を使用するとnumBは123456.789と表示されますが、
numAのほうが0.000と表示されます。
両方のBigDecimalを希望どおりに表示させる方法はないでしょうか?
またはBigDecimalの機能では無理なのでしょうか?
よろしくお願いいたします。


ハツキタツミ
大ベテラン
会議室デビュー日: 2005/05/24
投稿数: 108
投稿日時: 2005-09-05 11:29
どうしたいのか、いまいちピンとこないのですが..
DecimalFormatでいいような気が
未記入
常連さん
会議室デビュー日: 2005/02/23
投稿数: 20
投稿日時: 2005-09-05 11:59
浮動小数点の要領で数字を仮数部(1.23456)と指数部(10^-6)に分けて考えればよいのでは?
この場合の指数部は10を底にした対数をで得られます。
未記入
ベテラン
会議室デビュー日: 2005/02/24
投稿数: 55
投稿日時: 2005-09-05 14:39
整理しますので
よろしくお願い致します。



【希望する処理結果】
BigDecimalで保持している数値を小数部有効桁3桁で取り出す。


【例】
BigDecimal numA = new BigDecimal("0.00000123456");
BigDecimal numB = new BigDecimal("123456.789012");

numA → 0.00000123の値を取得する
numB → 123456.789の値を取得する



【BigDecimal.setScale(3)を使用した場合】
numA → 0.000 (NG)
numB → 123456.789


【DecimalFormatを使用した場合】
DecimalFormat df = new DecimalFormat(".000");でフォーマットする

numA → .000 (NG)
numB → 123456.789


【DecimalFormatで科学表記を使用する場合】
DecimalFormat df = new DecimalFormat(".000E0");でフォーマットする

numA  →  .123E-5    さらに変換すれば一応OK
numB  →  .123E6    変換しても123456.789は取得できない。(NG)



【補足】
切捨てではなく、丸めも行いたいので
できるだけBigDecimalやDecimalFormatなどを使いたい。



[ メッセージ編集済み 編集者: 未記入 編集日時 2005-09-05 14:40 ]
Edosson
ぬし
会議室デビュー日: 2004/04/30
投稿数: 675
投稿日時: 2005-09-05 15:28
「有効桁数3桁」と「小数部3桁まで表示する」は全然別物ですよ。
その辺の混同が、混乱の原因でしょう。
「小数部有効桁3桁」ってのは、一般に扱われない定義ですので、
ロジックは自分で書かないといけないんじゃないでしょうか。
コード:

保持している数値が1.0以上の場合
  DecimalFormat df = new DecimalFormat(".000");でフォーマットする
そうでない場合(数値が1.0未満の場合)
  DecimalFormat df = new DecimalFormat(".000E0");でフォーマットする
  小数表示に変換


あるいは、
コード:

保持している数値を、整数部と小数部に分離
DecimalFormat df = new DecimalFormat(".000E0");でフォーマットする
整数部はそのまま、小数部は小数表示に変換


とりあえず、こうすれば要件は満たせるのではないでしょうか。

<追記>
失礼しました。
2番目のは、1.00234みたいな場合は、期待通りに動きませんね。
やっぱり、整数部の0判定をしなきゃいけないかな。

[ メッセージ編集済み 編集者: Edosson 編集日時 2005-09-05 17:42 ]
まさ
ベテラン
会議室デビュー日: 2002/11/15
投稿数: 74
投稿日時: 2005-09-06 13:27

まさです。
ちょっとかったるいですが、正規表現でいかが?

コード:
import java.math.BigDecimal;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
    public static void main(final String[] args) {
        BigDecimal[] decimals = new BigDecimal[] {
                new BigDecimal("0.00000123456"),    //  OK
                new BigDecimal("123456.789012"),    //  OK
                new BigDecimal("0.012"),            //  NG?
            };

        //  小数部有効桁3桁までの正規表現
        Pattern pattern;
        pattern = Pattern.compile("([^.]*\\.)([0]*[0-9]{0,3}).*");

        for (int index = 0; index < decimals.length; index++) {
            BigDecimal target;
            target = decimals[index];

            //  BigDecimal の文字列表現取得
            String value;
//            value = target.toString() + "000";  //  3番目の BigDecimal の初めの有効桁から 3桁取りたいときはこっち
            value = target.toString();

            //  パターンマッチャ
            Matcher matcher;
            matcher = pattern.matcher(value);

            //  マッチ!
            if (matcher.matches()) {
                System.out.println(matcher.group(1) + matcher.group(2));

            //  アンマッチ
            } else {
                System.out.println("* unmatch pattern. [" + value + "]");
            }
        }
    }
}



未記入
ベテラン
会議室デビュー日: 2005/02/24
投稿数: 55
投稿日時: 2005-09-06 15:35
Edossonさんの1番目の案で
うまくできました!。
1で切り分けただけで結構シンプルになりました。
みなさんどうもありがとうございました。

コード:

public class BigDecimalTest {

public static void main(String[] args) throws ParseException {
BigDecimal[] num = new BigDecimal[] {
new BigDecimal("0.00000123456"),
new BigDecimal("0.001257"),
new BigDecimal("1"),
new BigDecimal("10"),
new BigDecimal("0.9999999"),
new BigDecimal("1.0000001"),
new BigDecimal("0.100000"),
new BigDecimal("123456.789999")
};
for (int i = 0, end = num.length; i < end; i++) {
String result;
// 1以下のとき
if (num[i].compareTo(new BigDecimal(1)) == -1) {
DecimalFormat df = new DecimalFormat(".000E0");
String s = df.format(num[i]);
BigDecimal bd = new BigDecimal(s);
result = bd.toString();
              // 1以上のとき
} else {
DecimalFormat df = new DecimalFormat(".000");
result = df.format(num[i]);
}
System.out.println(result);
}
}
}






[ メッセージ編集済み 編集者: 未記入 編集日時 2005-09-06 15:42 ]
1

スキルアップ/キャリアアップ(JOB@IT)