JSP / Java'da tam ve kesirli parçaları ikiliden nasıl alabilirim?


104

JSP / Java'da tam ve kesirli parçaları ikiliden nasıl alabilirim? Değer 3,25 ise o zaman almak istiyorumfractional =.25 ,whole = 3

Bunu Java'da nasıl yapabiliriz?


4
Mantis ve üssün ne olduğuna dair yanlış bir fikriniz var gibi görünüyor. Bunlar sadece "bütün kısım" ve "kesirli kısım" değildir. Bkz. En.wikipedia.org/wiki/Floating_point
Jon Skeet

Aslında 'hey .. buna üs denmez' gitmeden önce yaklaşık 5 yazı okudum. Beynim kelimeleri attı ve problemi çözmeye başladı .. Programlama şeyler okumak bana verdiği kötü alışkanlıklar :)
Gishu

1
Ayrıca lütfen OP .. sorusunu diğer nedenlerin yanı sıra gelecek nesiller için yeniden ifade edin.
Gishu

1
Şüpheli bir şekilde bir ev ödevi problemine benziyor.
Brian Knoblauch

ohh anlıyorum. Nasıl bu kadar garip sonuçlar elde ettiğini merak
etmiştim

Yanıtlar:


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);

Çıktılar:

Integer part = 2
Fractional part = 0.2999999999999998

61
Aslında bu sayfa, "ikili java'dan kesirli ve tüm parçayı çıkar" =) için bir google aramasının ilk isabeti
Chris

12
Aslında bu cevap yanlıştır, uzun olandan daha büyük değerler için kesirli kısımda çok büyük sayılar verecektir. Aşağıdaki Dan Vinton cevabı da aynı derecede basit ve her zaman doğru sonucu döndürüyor.
arberg

2
yani çıktıda görebileceğiniz gibi aslında bu doğru değil. girdi 3'ün kesri ve çıktı 29999999 ... Double yerine BigDecimal kullanmak hile yapacak
Alex

2
@Alex Hayır, giriş çok yakın 2.3ama kesinlikle olmayan bir sayıdır 2.3. Ve 10'dan fazla geçerli basamak istemediğiniz sürece çıktıda yanlış bir şey yoktur. İhtiyacınız olan tek şey, her çıktıda (örneğin, format %.9f) bir miktar yuvarlamadır ve bu genellikle daha az zahmetlidir BigDecimal. Buradaki tek sorun taşma.
maaartinus

1
Double'ı int'e dönüştürmek neredeyse her zaman kötü bir fikirdir. Çünkü örneğin (long)1.0e100sizin için 0 alacaksınız. Çoğu zaman çift değere ihtiyaç duyduğunuzda basitçe "katlanmış" dır floor(). Hem integral hem de kesir parçalarını istiyorsanız kullanın modf(). Gerçekten, bu kötü bir cevap.
mojuba

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

12
Bu neden reddedildi? İyi çalışıyor ve benim düzenlememle negatif değerlerle de çalışacak.
HRJ

Tamsayı kısmı => long longPart = (long) 3.25
jdurango

2
Neg için işe yaramaz. değerler. Yani% -3.25 1 = 0.75, 0.25 değil. Yani integralPart -3.25 - 0.75 = -4 olacaktır.
WindRider

2
@WindRider, olumsuzlukları kontrol ettim .. ve çalışmalarını .. ancak sayıca az olan ondalık basamaklar için küçük bir hata olacaktır. Örn. -03.0025 için -0.0024999999999999467 ve -3.0 döndürür
justshams

5
Buradaki karışıklık, Python gibi bazı dillerin %modulo ( -3.25 % 1 == 0.75) anlamında kullanılması ve Java, Fortran, C ve C ++ gibi diğerlerinin ise %kalan ( -3.25 % 1 == -0.25) anlamında kullanmasıdır . WindRider, uygun olması için Python REPL'e yazmış olabilir, ancak bu cevap yanıltıcıdır çünkü bu soru JVM ile ilgilidir.
Jim Pivarski

24

Bu 1 yıllık soru, soru konusunu düzelten biri tarafından başlatıldığından ve bu soru etiketlendi jsp ve buradaki hiç kimse JSP hedefli bir cevap veremediğinden, işte benim JSP hedefli katkım.

Kullanım JSTL (sadece damla JSTL-1.2.jar içinde /WEB-INF/lib) fmt taglib. <fmt:formatNumber>Tam olarak istediğinizi yapan ve yardımıyla oldukça kolay bir şekilde bir etiket var maxFractionDigitsvemaxIntegerDigits özniteliklerle .

İşte bir SSCCE , sadece kopyalayıp yapıştırın ve çalıştırın.

<%@ 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>

Çıktı:

Bütün: 3

Kesir: 0,25

Bu kadar. Ham Java kodu yardımıyla masaj yapmaya gerek yok.


8

Orijinal soru, kesirli ve tam kısım yerine üs ve mantis sordu.

Bir ikiliden üs ve mantisi elde etmek için, onu IEEE 754 gösterimine dönüştürebilir ve aşağıdaki gibi bitleri çıkarabilirsiniz:

long bits = Double.doubleToLongBits(3.25);

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

Mantinssa'nın ilk biti örtük olarak 1'e ayarlanmadı, bu nedenle mantis (bit & 0x000fffffffffffffL) | 0x0010000000000000L?
agnul

Rasmus it wasnt a ryt output Çıktı: üs 0 ve mantissa 2814749767106560 ve urs agnul'u seçerseniz mantis 0 olur
Vinayak Bevinakatti

4 yukarı oyla bozuldu :) Kodun ek yerlerinde çift değeri ayırmakla ne yapmaya çalıştığını görmeme rağmen, kod doğru değerleri vermiyor gibi görünüyor.
Gishu

@agnul: Sanırım "mantis" genellikle sadece bitlerin değerini ifade ediyor. Bunu (bazen) başına 1 bit ekleyerek anlamlı hale getirebilirsiniz. Ancak Wikipedia'ya göre mantis kelimesi artık "kesir" lehine kullanımdan kaldırıldı.
Rasmus Faber

5

Temel mantık, önce ondalık noktadan sonra kaç basamak olduğunu bulmanız gerekir.
Bu kod, 16 haneye kadar herhangi bir sayı için çalışır. BigDecimal kullanıyorsanız, sadece 18 haneye kadar çalıştırabilirsiniz. girdi değerini (numaranızı) "num" değişkenine koyun, burada örnek olarak onu sabit kodladım.

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);

Dostum, bu basit bir problem için son derece karmaşık bir cevap. Kabul edilen cevaba baktınız mı?
Gray

1
Şimdi olumsuz oyu veren kişi (btw değil), neden olumsuz oy olduğunu açıklamalıydı. Bu iyi değil. Ama hepimiz bir noktada 1 puan aldık.
Gray

2
@Gray soru 3.25'i '3' ve '25' olarak ayırmaktı ve kabul edilen cevap asla '25' vermeyecek, her zaman '2599999999' verecek
OnePunchMan

@Gray Kimin olumsuz oy verdiğini biliyorum, bu blogda yazdığım yorumların, cevapların ve soruların her biri ile alay eden Eji (eski kullanıcı) adında bir adamdı. Sonunda moderatöre şikayet ediyorum.
OnePunchMan

2
Kesirli kısmı bir tam sayı olarak istiyorsanız bu cevap çok kullanışlıdır
Guilherme Campos Hazan

5

Bir IEEE çift kayan noktalı sayının mantisi ve üssü,

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

mantis 0.101010101_base 2 biçiminde ise (yani en önemli biti ikili noktadan sonra olacak şekilde kaydırılır) ve üs önyargı için ayarlanır.

1.6'dan beri, java.lang.Math ayrıca tarafsız üssü elde etmek için doğrudan bir yöntem sağlar (getExponent (double) olarak adlandırılır)

Bununla birlikte, sorduğunuz sayılar, sayının integral ve kesirli kısımlarıdır ve bunlar kullanılarak elde edilebilir.

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

Negatif sayıları (floor(-3.5) == -4.0)neden iki parçayı istediğinize bağlı olarak farklı şekilde ele almak isteyebilirsiniz.

Bunlara mantis ve üs dememenizi şiddetle öneririm.


4

Daha hızlı mı bilmiyorum ama kullanıyorum

float fp = ip % 1.0f;

3

[Düzenleme: Soru başlangıçta mantis ve üssün nasıl alınacağını sordu.]

Burada n , gerçek mantis / üs elde edilecek sayıdır:

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

Veya aradığınız cevabı almak için:

exponent = int(n)
mantissa = n - exponent

Bunlar tam olarak Java değildir, ancak dönüştürülmesi kolay olmalıdır.


3

Tamsayı kısmı basit dökümden ve kesirli - dizgi bölme işleminden elde edilir:

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

Ya numaranız 2,39999999999999 ise. Sanırım tam ondalık değeri almak istiyorsunuz. Ardından BigDecimal'i kullanın:

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

Yana fmt:formatNumberetiketi her zaman doğru sonuç ortaya koymamıştır, burada başka bir JSP okunur yaklaşımdır: Sadece dize olarak numarasını biçimlendirir ve ipe hesaplama gerisini, yani daha kolaydır ve kayan nokta daha da içermez beri aritmetik.

<%@ 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>

Örneğimdeki tüm sayıları deneyin. fmt:formatNumberbu durumda istenmeyen argümanını yuvarlar.
Roland Illig

0

Bu yanıtların çoğunda korkunç yuvarlama hataları var çünkü sayıları bir türden diğerine çeviriyorlar. Peki ya:

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

@justshams Kullanmaya ne dersiniz Math.abs?
Stephan

0

Kabul edilen cevap -0 ile -1.0 arasındaki negatif sayılar için pek işe yaramıyor. Ayrıca kesirli kısmı negatif veriniz.

Örneğin: -0,35 sayısı için

İadeler

Tamsayı kısmı = 0 Kesirli kısım = -0.35

GPS koordinatları ile çalışıyorsanız, tamsayı kısmında aşağıdaki gibi işaret ile bir sonuç elde etmek daha iyidir:

Tam sayı bölümü = -0 Kesirli bölüm = 0.35

Bu sayılar örneğin GPS koordinatları için kullanılır, burada Enlem veya Uzun konum için işaret önemli

Kod önerin:

    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));

Çıktı:

Integer part = -0
Fractional part = 0,3500


0

Çözüm için BigDecimal kullanırdım. Bunun gibi:

    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);
    }
}

Bu yanıt, düşük kaliteli olarak işaretlendi. Soruyu yanıtlarsa, nasıl çalıştığını açıklamak için biraz metin eklemeyi düşünün.
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

Tamam, bu belki geç olabilir, ancak bence en iyi ve daha doğru yaklaşım BigDecimal kullanmaktır

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

Bir çiftiniz varsa, şamandıra belirsizliği vardır. Bunu bir BigDecimal'e dönüştürmek sihirli bir şekilde hassasiyetini geri getirmez.
Taschi

@Taschi Bence soru int ve kesirli kısmı ayırmakla ilgili, hassasiyetini geri yüklemekle ilgili değil!
Omar Elashry

Omar, yaklaşımının "daha doğru" olduğundan özellikle bahsetmiştin, ki bence bu doğru değil. Cevabınız tamamen kabul edilebilir, ancak bu ifade bana yanıltıcı geliyor, bu yüzden yorum yaptım.
Taschi

@Taschi, çünkü birçok cevapta çıktı aldığınızda değer kaybedersiniz, örneğin input (5.03) output int = 5 , fractional = 0.0299999girdi ve çıktılardan bahsediyoruz, değer koyun ve değerinizi% 0,001 kaybetmeden geri alın dedim! ve bu doğru, yanıltıcı değil!
Omar Elashry

Evet. İlk etapta bir şeyi çift olarak sakladığınızda hassasiyet kaybedersiniz. BigDecimal'e dönüştürürken yuvarlama da hassasiyeti kaybeder. Bu iki hassasiyet kaybı birbirini ortadan kaldırabilir, ancak bu kesinliği "geri getirmez", çünkü hassasiyeti geri yüklemek matematiksel olarak imkansızdır. Bilgileri havadan çekemezsiniz.
Taschi

-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);
    }
}

Bu, yalnızca sayı tam olarak 4 ondalık basamağa sahipse çalışır. Başka türlü.
Marquis of Lorne
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.