JSP / Javaでdoubleから整数部と小数部を取得するにはどうすればよいですか?


104

JSP / Javaでdoubleから整数部分と小数部分を取得するにはどうすればよいですか?値が3.25の場合、を取得しますfractional =.25whole = 3

これをJavaでどのように実行できますか?


4
あなたは仮数と指数が何であるかについて不正確な考えを持っているようです。それらは単に「全体」や「一部」ではありません。en.wikipedia.org/wiki/Floating_pointを
Jon Skeet

実際、私は「ちょっと..それは指数と呼ばれていません」に行く前に約5つの投稿を読みました。私の脳は言葉を捨てて問題を解決し始めました..プログラミングを読むという悪い習慣が私に与えてくれました:)
Gishu

1
また、他の理由の間でOP ..の質問を言い換えてください。
岐阜

1
宿題のように聞こえます。
Brian Knoblauch、

おお、分かった。私はすでに彼がどのように奇妙な結果を得るのか疑問に思いました
Johannes Schaub-litb

回答:


102

http://www.java2s.com/Code/Java/Data-Type/Obtainingtheintegerandfractionalparts.htm

double num;
long iPart;
double fPart;

// Get user input
num = 2.3d;
iPart = (long) num;
fPart = num - iPart;
System.out.println("Integer part = " + iPart);
System.out.println("Fractional part = " + fPart);

出力:

Integer part = 2
Fractional part = 0.2999999999999998

61
実際、このページは、「ダブルJavaから部分的および全体的な部分を取り出す」というGoogle検索の最初のヒットです=)
Chris

12
実際にはこの答えは正しくありません。longよりも大きい値はそれが表すことができるので、小数部に膨大な数を与えます。以下のDan Vintonの回答も同じくらい簡単で、常に正しい結果を返します。
arberg

2
出力で確認できるように、実際にはこれは正しくありません。入力は3の端数で、出力は29999999です... Doubleの代わりにBigDecimalを使用するとトリックが実行されます
Alex

2
@アレックスいいえ、入力はに非常に近い数値です2.3が、確かにそうではありません2.3。また、10桁を超える有効な数字が必要でない限り、出力に問題はありません。必要なのは、各出力(たとえば、format %.9f)の丸めだけBigDecimalです。ここでの唯一の問題はオーバーフローです。
maaartinus 2015年

1
doubleをintに変換することは、ほとんど常に悪い考えです。たとえば、(long)1.0e100あなたのために0を取得します。多くの場合、あなたは、単に「フローリング」されているdouble値が必要ですfloor()。整数部と小数部の両方が必要な場合は、を使用してくださいmodf()。本当に、これは悪い答えです。
mojuba 2016年

155
double value = 3.25;
double fractionalPart = value % 1;
double integralPart = value - fractionalPart;

12
なぜこれが反対投票されたのですか?正常に動作し、編集すると負の値も動作します。
HRJ 2011

整数部分は、=> long longPart =(long)3.25
jdurango、2014

2
否定のために働きません。値。つまり-3.25%1 = 0.75は0.25ではありません。したがって、integralPartは-3.25-0.75 = -4になります。
WindRider 2014

2
@WindRider、負数とその動作を確認しました。ただし、小数点以下の桁数が少ない場合は、若干の誤差が生じます。例 -03.0025の場合、-0.0024999999999999467および-3.0を返します
justshams

5
ここでの混乱は、Pythonなどの一部の言語が%モジュロ(-3.25 % 1 == 0.75)を意味するために使用し、Java、Fortran、C、およびC ++などの他の言語が%剰余(-3.25 % 1 == -0.25)を意味するために使用するためです。WindRiderは便宜上、それをPython REPLに入力した可能性がありますが、この質問はJVMに関するものであるため、その答えは誤解を招くものです。
Jim Pivarski、2015年

24

この1年前の質問は、質問の件名を修正した人によって蹴られ、この質問にはのタグが付けられておりjsp、JSPを対象とした回答を提供できなかったため、ここに私のJSPを対象とした貢献を示します。

使用JSTL(ちょうどドロップJSTL-1.2.jarをして/WEB-INF/libFMTのtaglib。および属性<fmt:formatNumber>を使用して、非常に簡単な方法で希望どおりのことを行うタグがmaxFractionDigitsありmaxIntegerDigitsます。

ここだSSCCE、それをcopy'n'paste'n'run。

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

<%
    // Just for quick prototyping. Don't do this in real! Use servlet/javabean.
    double d = 3.25;
    request.setAttribute("d", d);
%>

<!doctype html>
<html lang="en">
    <head>
        <title>SO question 343584</title>
    </head>
    <body>
        <p>Whole: <fmt:formatNumber value="${d}" maxFractionDigits="0" />
        <p>Fraction: <fmt:formatNumber value="${d}" maxIntegerDigits="0" />
    </body>
</html>

出力:

全体:3

分数:.25

それでおしまい。生のJavaコードの助けを借りてマッサージする必要はありません。


8

元の質問では、小数部や全体ではなく、指数と仮数を求めていました。

doubleから指数と仮数を取得するには、それをIEEE 754表現に変換し、次のようにビットを抽出します。

long bits = Double.doubleToLongBits(3.25);

boolean isNegative = (bits & 0x8000000000000000L) != 0; 
long exponent      = (bits & 0x7ff0000000000000L) >> 52;
long mantissa      =  bits & 0x000fffffffffffffL;

マンティンサの最初のビットは暗黙的に1に設定されていないため、仮数は(ビット&0x000fffffffffffffL)である必要があります。0x0010000000000000L?
2008

Rasmusそれはryt出力ではなかった出力:指数0と仮数2814749767106560そしてuがurs agnulを選択した場合、仮数は0
Vinayak Bevinakatti

4票で破られました:)ジョイントでdouble値を分解してコードが何をしようとしているのかはわかりますが、コードは正しい値を出力していないようです。
岐阜

@agnul:通常、「仮数」はビットの値だけを指します。(時々)1ビットを付加することでこれを仮数に変換するだけかもしれません。しかし、ウィキペディアによると、仮数という単語は「分数」を支持して廃止されました。
Rasmus Faber

5

最初に、小数点以下の桁数を見つける必要がある主なロジック。
このコードは、16桁までの任意の数値で機能します。BigDecimalを使用する場合、最大18桁まで実行できます。入力値(数値)を変数 "num"に入力します。ここでは例として、ハードコーディングしています。

double num, temp=0;
double frac,j=1;

num=1034.235;
// FOR THE FRACTION PART
do{
j=j*10;
temp= num*j;
}while((temp%10)!=0);       

j=j/10;
temp=(int)num;
frac=(num*j)-(temp*j);

System.out.println("Double number= "+num);      
System.out.println("Whole part= "+(int)num+" fraction part= "+(int)frac);

おい、これは単純な問題に対する非常に複雑な答えです。受け入れられた答えを見てみましたか?
グレー

1
これで、反対票を投じた人(私ではありません)は、なぜ反対票があったのを説明しているはずです。それは良いことではありません。しかし、私たち全員が、どこかで1のスコアを持っていました。
灰色

2
@Grayの質問は、3.25を「3」と「25」に分離することでした。受け入れられた回答は「25」を決して与えず、常に「2599999999」を与えます
OnePunchMan

@Gray誰が反対票を投じたのか知っています。このブログに投稿するコメント、回答、質問のすべてをあざけっているEji(旧ユーザー)の名前でした。最後にモデレーターに文句を言います。
OnePunchMan 2013年

2
小数部を整数として使用する場合、この回答は非常に役立ちます
ギル

5

IEEE倍精度浮動小数点数の仮数と指数は、次のような値です。

value = sign * (1 + mantissa) * pow(2, exponent)

仮数の形式が0.101010101_base 2(つまり、その最も重要なビットが2進小数点の後ろになるようにシフトされている)であり、指数がバイアス用に調整されている場合。

1.6以降、java.lang.Mathは不偏指数を取得する直接メソッド(getExponent(double)と呼ばれる)も提供します

ただし、求めている数値は、数値の整数部分と小数部分であり、次のようにして取得できます。

integral = Math.floor(x)
fractional = x - Math.floor(x)

ただし(floor(-3.5) == -4.0)、2つの部分が必要な理由に応じて、負の数を異なる方法で処理することもできます。

これらの仮数と指数を呼び出さないことを強くお勧めします。


4

これが速いかどうかわかりませんが、私は使用しています

float fp = ip % 1.0f;

3

[編集:最初は、仮数と指数を取得する方法を質問しました。]

ここで、nは、実数の仮数/指数を取得するための数です。

exponent = int(log(n))
mantissa = n / 10^exponent

または、あなたが探していた答えを得るために:

exponent = int(n)
mantissa = n - exponent

これらは正確にはJavaではありませんが、簡単に変換できるはずです。


3

整数部分は単純なキャストから得られ、分数-文字列分割:

double value = 123.004567890

int integerPart = (int) value; // 123

int fractionPart = 
  Integer.valueOf(String.valueOf(value)
      .split(".")[1]); // 004567890

/**
* To control zeroes omitted from start after parsing.
*/
int decimals =
  String.valueOf(value)
      .split(".")[1].length(); // 9

1

番号が2.39999999999999の場合はどうなりますか。正確な10進数値を取得したいと思います。次にBigDecimalを使用します。

Integer x,y,intPart;
BigDecimal bd,bdInt,bdDec;
bd = new BigDecimal("2.39999999999999");
intPart = bd.intValue();
bdInt = new BigDecimal(intPart);
bdDec = bd.subtract(bdInt);
System.out.println("Number : " + bd);
System.out.println("Whole number part : " + bdInt);
System.out.println("Decimal number part : " + bdDec);

0

以来fmt:formatNumber、タグは常に正しい結果が得られない、ここでは別のJSPのみのアプローチである:それは簡単ですし、さらに浮動小数点を必要としないので、それはちょうど、文字列として番号をフォーマットし、文字列の計算の残りの部分はありません算術。

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

<%
  double[] numbers = { 0.0, 3.25, 3.75, 3.5, 2.5, -1.5, -2.5 };
  pageContext.setAttribute("numbers", numbers);
%>

<html>
  <body>
    <ul>
      <c:forEach var="n" items="${numbers}">
        <li>${n} = ${fn:substringBefore(n, ".")} + ${n - fn:substringBefore(n, ".")}</li>
      </c:forEach>
    </ul>
  </body>
</html>

私の例のすべての数値を試してください。fmt:formatNumberこの場合は不要な引数を丸めます。
Roland Illig

0

これらの回答の多くは、数値をあるタイプから別のタイプにキャストしているため、恐ろしい丸め誤差があります。どうですか:

double x=123.456;
double fractionalPart = x-Math.floor(x);
double wholePart = Math.floor(x);

@justshams使用についてはどうMath.absですか?
ステファン

0

受け入れられた回答は、-0から-1.0の間の負の数ではうまく機能しません。また、小数部を負にしてください。

例:数値-0,35の場合

戻り値

整数部= 0分数部= -0.35

wouがGPS座標を使用している場合、整数部分の符号が次のような結果になるようにすることをお勧めします。

整数部= -0分数部= 0.35

これらの数値は、たとえばGPS座標に使用されます。この場合、緯度または経度の位置の記号が重要です。

コードを提案する:

    double num;
    double iPart;
    double fPart;

    // Get user input
    num = -0.35d;
    iPart = (long) num;
    //Correct numbers between -0.0 and -1.0
    iPart = (num<=-0.0000001 && num>-1.0)? -iPart : iPart ;
    fPart = Math.abs(num - iPart);
    System.out.println(String.format("Integer part = %01.0f",iPart));
    System.out.println(String.format("Fractional part = %01.04f",fPart));

出力:

Integer part = -0
Fractional part = 0,3500


0

ソリューションにはBigDecimalを使用します。このような:

    double value = 3.25;
    BigDecimal wholeValue = BigDecimal.valueOf(value).setScale(0, BigDecimal.ROUND_DOWN);
    double fractionalValue = value - wholeValue.doubleValue();

0
String value = "3.06";

if(!value.isEmpty()){
    if(value.contains(".")){    
        String block = value.substring(0,value.indexOf("."));
        System.out.println(block);
    }else{
        System.out.println(value);
    }
}

この回答には低品質のフラグが付けられています。それが質問に答える場合は、それがどのように機能するかを説明するテキストを少し追加することを検討してください。
lmo

0
// target float point number
double d = 3.025;

// transfer the number to string
DecimalFormat df = new DecimalFormat();
df.setDecimalSeparatorAlwaysShown(false);
String format = df.format(d);

// split the number into two fragments
int dotIndex = format.indexOf(".");
int iPart = Integer.parseInt(format.substring(0, dotIndex)); // output: 3
double fPart = Double.parseDouble(format.substring(dotIndex)); // output: 0.025

0

OKこれは多分遅いですが、最良かつより正確なアプローチはBigDecimalを使用することです

double d = 11.38;

BigDecimal bigD = BigDecimal.valueOf(d);
int intPart = bigD.intValue();
double fractionalPart = bigD.subtract(BigDecimal.valueOf(intPart)).doubleValue();

System.out.println(intPart); // 11
System.out.println(fractionalPart ); //0.38

あなたがダブルを持っている場合、それは浮動小数点の不正確さを持っています。これをBigDecimalに変換しても、魔法のように精度が回復するわけではありません。
Taschi

@Taschi問題はintと小数部を分離することであり、精度を復元することではありません!
Omar Elashry

オマール、あなたのアプローチは「より正確」であると具体的に話しましたが、私はそうではないと思います。あなたの答えは完全に受け入れられますが、その表現は私にとって誤解を招くようです。そのため、私はそれにコメントしました。
Taschi

@ Taschi、私は多くの答えであなたが出力を得るときあなたは価値を失うので、例えばinput (5.03) output int = 5 , fractional = 0.0299999私たちは入力と出力について話しているので、あなたは値を入れてそれの0.001%を失うことなくあなたの価値を取り戻します!そして、これは正確で、誤解を招きません!
Omar Elashry

はい。最初に何かをdoubleとして格納すると、精度が失われます。BigDecimalに変換するときの丸めも精度を失います。精度のこれら2つの損失は互いに相殺される可能性がありますが、精度の復元は数学的に不可能であるため、精度は「復元」されません。薄い空気から情報を引き出すことはできません。
タスキ

-2
public class MyMain2 {
    public static void main(String[] args) {
        double myDub;
        myDub=1234.5678;
        long myLong;
        myLong=(int)myDub;
        myDub=(myDub%1)*10000;
        int myInt=(int)myDub;
        System.out.println(myLong + "\n" + myInt);
    }
}

これは、数値の小数点以下の桁数が4桁の場合にのみ機能します。そうでなければ。
ローンの侯爵
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.