Kayan yeri n ondalık basamağa biçimlendir


220

Bir kayan nokta "n" ondalık basamaklara biçimlendirmek gerekiyor.

BigDecimal için çalışıyor, ancak dönüş değeri doğru değil ...

public static float Redondear(float pNumero, int pCantidadDecimales) {
    // the function is call with the values Redondear(625.3f, 2)
    BigDecimal value = new BigDecimal(pNumero);
    value = value.setScale(pCantidadDecimales, RoundingMode.HALF_EVEN); // here the value is correct (625.30)
    return value.floatValue(); // but here the values is 625.3
}

Belirttiğim ondalık basamak sayısı ile bir kayan nokta değeri döndürmem gerekiyor.

FloatDeğeri iade etmeye ihtiyacım yokDouble

.

Yanıtlar:


561

Ayrıca kayan nokta değerini iletebilir ve şunları kullanabilirsiniz:

String.format("%.2f", floatValue);

belgeleme


70
Lütfen String.format geçerli Yerel yapılandırmanıza bağlı olduğundan dikkatli olun, ayırıcı olarak nokta alamayabilirsiniz. Kullanmayı tercih etString.format(java.util.Locale.US,"%.2f", floatValue);
Gomino

6
Bu cevap bir kayan değer değil, bir String değeri verir, iyi bir cevap sanmıyorum.
ZhaoGang

3
Bir noktayı neden ayırıcı olarak zorlasın ki?
Mark Buikema

1
@MarkBuikema Bence standartlar tarafından yönlendirilen belge formatlarını derlerken, örneğin kesinlikle gerekli olacak durumlar vardır. PDF belgeleri.
Tjaart

39

DecimalFormat'a bir göz atın . Bir sayı almak ve belirli sayıda ondalık basamak vermek için bunu kolayca kullanabilirsiniz.

Düzenle : Örnek


1
+1. İşte esasen aynı olması gereken Android'e özel belgeler .
Zach L

ama sonuç bir kayan sayı, bir dize gerekir.
seba123neo

Şamandırayı yuvarlamak istediğini mi söylüyorsun? Normalde bir şamandıra için önemli olan tek zaman hassasiyeti görüntüleme içindir.
Nick Campion

Üzgünüm, haklısın, kafam karıştı, sadece ekranda gösterilen sayıyı biçimlendir, daha önce değil, bu benim sorumdu, çok teşekkür ederim, sorun çözüldü.
seba123neo

Unutmayın, DecimalFormatyapıcı kullanımı önerilmez, doğru kullanımı için cevabımı görün NumberFormat.
FBB

17

Bunu dene bu bana çok yardımcı oldu

BigDecimal roundfinalPrice = new BigDecimal(5652.25622f).setScale(2,BigDecimal.ROUND_HALF_UP);

Sonuç yuvarlak olacakFiyat -> 5652.26


2
Bu, yuvarlamak ve onunla daha fazla hesaplama yapmak isteyenler için daha yararlıdır, aksi takdirde Arve'nin cevabı muhtemelen en iyisidir.
Gerard

Bu GWT ile de çalışır. String.format () - yapmaz.
AlexV

15

Dikkat edilmesi gereken, DecimalFormatyapıcı kullanımı önerilmez. Bu sınıf için javadoc şunları belirtir:

NumberFormat fabrika yöntemleri DecimalFormat dışındaki alt sınıfları döndürebileceğinden, genel olarak DecimalFormat yapıcılarını doğrudan çağırmayın.

https://docs.oracle.com/javase/8/docs/api/java/text/DecimalFormat.html

Yapmanız gereken şey (örneğin):

NumberFormat formatter = NumberFormat.getInstance(Locale.US);
formatter.setMaximumFractionDigits(2);
formatter.setMinimumFractionDigits(2);
formatter.setRoundingMode(RoundingMode.HALF_UP); 
Float formatedFloat = new Float(formatter.format(floatValue));

(Örneğin) floatValue = 8.499 olduğunda bu çalışmaz. 8.5 veriyor.
Shiva krishna Chippa

3
@ShivakrishnaChippa: evet, çünkü burada virgülden sonra 2 basamak istediğimizi ve yukarı yuvarlama yapacağımızı belirtiyoruz. Bu durumda 8.499, 8.5'e yuvarlanır. 8.499'un görüntülenmesini istiyorsanız, 3'ü maksimum kesir basamağı olarak ayarlamanız yeterlidir.
FBB

6

İşte DecimalFormatNick'in bahsettiği sınıfı kullanan hızlı bir örnek .

float f = 12.345f;
DecimalFormat df = new DecimalFormat("#.00");
System.out.println(df.format(f));

Print deyiminin çıktısı 12.35 olacaktır. Sizin için yuvarlayacağına dikkat edin.


Unutmayın, DecimalFormatyapıcı kullanımı önerilmez, doğru kullanımı için cevabımı görün NumberFormat.
FBB

5

Kinda kimsenin bunu yapmanın doğrudan yolunu işaret etmediğine şaşırdım, ki bu yeterince kolay.

double roundToDecimalPlaces(double value, int decimalPlaces)
{
      double shift = Math.pow(10,decimalPlaces);
      return Math.round(value*shift)/shift;
}

Ancak bunun yarım hatta yuvarlanmadığından eminim.

Değer için, ikili tabanlı kayan nokta değerlerini base-10 aritmetiği ile karıştırdığınızda, yarım çift yuvarlama kaotik ve tahmin edilemez olacaktır. Eminim bu yapılamaz. Temel sorun, 1.105 gibi bir değerin kayan noktada tam olarak temsil edilememesidir. Kayan nokta değeri 1.105000000000001 veya 1.104999999999999 gibi bir şey olacaktır. Bu nedenle, yarım çift yuvarlama gerçekleştirme girişimleri, temsili kodlama hatalarında artar.

IEEE kayan nokta uygulamaları yarım yuvarlama yapar, ancak ondalık yarım yuvarlama değil ikili yarı yuvarlama yaparlar. Yani muhtemelen iyisin


Ben de bir süre bu yöntemi kullandım, ama powyuvarlama için kullanmak için çok pahalı bir işlem olduğunu düşünürdüm ?
Xerus

Performans probleminiz olana kadar asla optimizasyon yapmayın. Doğru olmak hızlı olmaktan daha önemlidir. Visa veya Mastercard (daha fazla makine atacak olan) olmadıkça, kontrollü yuvarlama performansının sorun olacağı bir uygulamayı dürüstçe hayal edemiyorum. Ve pow () muhtemelen round () 'dan daha hızlıdır.
Robin Davies

2
public static double roundToDouble(float d, int decimalPlace) {
        BigDecimal bd = new BigDecimal(Float.toString(d));
        bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
        return bd.doubleValue();
    }

2

Bu çok daha az profesyonel ve çok daha pahalı bir yoldur, ancak yeni başlayanlar için anlaşılması daha kolay ve daha yararlı olmalıdır.

public static float roundFloat(float F, int roundTo){

    String num = "#########.";

    for (int count = 0; count < roundTo; count++){
        num += "0";
    }

    DecimalFormat df = new DecimalFormat(num);

    df.setRoundingMode(RoundingMode.HALF_UP);

    String S = df.format(F);
    F = Float.parseFloat(S);

    return F;
}

1

Bence ne istiyorsun

return value.toString();

ve görüntülemek için dönüş değerini kullanın.

value.floatValue();

her zaman 625.3 döndürür çünkü esas olarak bir şey hesaplamak için kullanılır.


ama sonuç bir kayan sayı, bir dize gerekir.
seba123neo

2
kullanıcıya göstermek için bir şamandıra gerekiyorsa, uygulamanın tasarımı ile ilgili bir sorun olabilir. Genellikle şamandıra hesaplamak için kullanılır ve bunu kullanıcıya göstermek için bir dize kullanılır.
n3utrino

Üzgünüm, haklısın, kafam karıştı, sadece ekranda gösterilen sayıyı biçimlendir, daha önce değil, bu benim sorumdu, çok teşekkür ederim, sorun çözüldü.
seba123neo

1

Bu soruya bir cevap arıyordum ve daha sonra bir yöntem geliştirdim! :) Adil bir uyarı, değeri yuvarlıyor.

private float limitDigits(float number) {
    return Float.valueOf(String.format(Locale.getDefault(), "%.2f", number));
}
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.