จัดรูปแบบลอยไปยังตำแหน่งทศนิยม n


220

ฉันต้องการจัดรูปแบบทศนิยมเป็นทศนิยม "n"

กำลังพยายาม BigDecimal แต่ค่าส่งคืนไม่ถูกต้อง ...

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
}

ฉันต้องการคืนค่าทศนิยมด้วยจำนวนตำแหน่งทศนิยมที่ฉันระบุ

ฉันต้องการFloatผลตอบแทนคุ้มค่าไม่Double

.

คำตอบ:


561

คุณอาจส่งผ่านค่าทศนิยมและใช้:

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

เอกสาร


70
โปรดระวังเป็น String.format ขึ้นอยู่กับการกำหนดค่าปัจจุบันของคุณคุณอาจไม่ได้จุดเป็นตัวคั่น ชอบใช้String.format(java.util.Locale.US,"%.2f", floatValue);
Gomino

6
คำตอบนี้ให้ค่าสตริงไม่ใช่ค่าลอยฉันไม่คิดว่าคำตอบที่ดี
ZhaoGang

3
ทำไมคุณต้องบังคับให้จุดเป็นตัวคั่น
Mark Buikema

1
@ MarkBuikema ฉันคิดว่ามีหลายกรณีที่จำเป็นอย่างยิ่งเช่นเมื่อรวบรวมรูปแบบเอกสารที่ได้แรงหนุนจากมาตรฐานเช่น เอกสาร PDF
Tjaart

39

ลองดูที่DecimalFormat คุณสามารถใช้มันเพื่อจดจำนวนและกำหนดจำนวนตำแหน่งทศนิยมได้อย่างง่ายดาย

แก้ไข : ตัวอย่าง


1
+1 นี่คือเอกสารเฉพาะของAndroidซึ่งควรจะเหมือนกัน
Zach L

แต่ฉันต้องการผลลัพธ์คือเลขทศนิยมไม่ใช่สตริง
seba123neo

คุณกำลังบอกว่าคุณต้องการลอยรอบ? โดยปกติความแม่นยำเวลาเพียงอย่างเดียวของเรื่องลอยสำหรับการแสดงผล
Nick Campion

ขอโทษคุณพูดถูกฉันสับสนเพียงแค่จัดรูปแบบตัวเลขเมื่อแสดงบนหน้าจอไม่ใช่ก่อนหน้านั่นคือคำถามของฉันขอบคุณมากปัญหาได้รับการแก้ไข
seba123neo

ของบันทึกการใช้งานของตัวสร้างเป็นกำลังใจให้ดูคำตอบของฉันสำหรับการใช้งานที่ถูกต้องของDecimalFormat NumberFormat
FBB

17

ลองสิ่งนี้ช่วยฉันได้มาก

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

ผลจะเป็นรอบสุดท้ายราคา -> 5652.26


2
สิ่งนี้มีประโยชน์มากกว่าสำหรับผู้ที่มองหาการปัดเศษและทำการคำนวณเพิ่มเติมด้วยมิฉะนั้นคำตอบของ Arve น่าจะดีที่สุด
เจอราร์ด

ใช้งานได้กับ GWT เช่นกัน String.format () - ไม่
AlexV

15

จากการสังเกตการใช้ตัวDecimalFormatสร้างไม่ได้รับการสนับสนุน javadoc สำหรับคลาสนี้ระบุ:

โดยทั่วไปอย่าเรียกใช้ตัวสร้าง DecimalFormat โดยตรงเนื่องจากวิธีการที่โรงงาน NumberFormat อาจส่งคืนคลาสย่อยอื่นนอกเหนือจาก DecimalFormat

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

ดังนั้นสิ่งที่คุณต้องทำคือ (ตัวอย่าง):

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

สิ่งนี้ไม่ทำงานเมื่อ (เช่น) floatValue = 8.499 มันให้ 8.5
พระอิศวรกฤษณะ Chippa

3
@ShivakrishnaChippa: ใช่เพราะที่นี่เราระบุว่าเราต้องการ 2 หลักหลังเครื่องหมายจุลภาคและทำการปัดเศษขึ้น ในกรณีนั้น 8.499 จะถูกปัดเศษเป็น 8.5 หากคุณต้องการให้แสดง 8.499 เพียงตั้งค่า 3 เป็นหลักเศษส่วนสูงสุด
FBB

6

นี่คือตัวอย่างรวดเร็วโดยใช้DecimalFormatคลาสที่นิคพูดถึง

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

ผลลัพธ์ของคำสั่งพิมพ์จะเป็น 12.35 แจ้งให้ทราบว่ามันจะรอบสำหรับคุณ


ของบันทึกการใช้งานของตัวสร้างเป็นกำลังใจให้ดูคำตอบของฉันสำหรับการใช้งานที่ถูกต้องของDecimalFormat NumberFormat
FBB

5

ค่อนข้างประหลาดใจที่ไม่มีใครชี้ทางตรงให้ทำซึ่งง่ายพอ

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

ค่อนข้างแน่ใจว่านี่ไม่ได้ทำการปัดเศษแบบครึ่งแม้

สำหรับสิ่งที่คุ้มค่าการปัดเศษครึ่งเท่าจะวุ่นวายและไม่สามารถคาดเดาได้ทุกเวลาที่คุณผสมค่าทศนิยมอิงเลขฐานสองกับฐานเลข 10 ฉันค่อนข้างแน่ใจว่ามันไม่สามารถทำได้ ปัญหาพื้นฐานคือค่าเช่น 1.105 ไม่สามารถแสดงได้อย่างแน่นอนในจุดลอย ค่าจุดลอยตัวจะเป็นเช่น 1.105000000000001 หรือ 1.104999999999999 ดังนั้นความพยายามใด ๆ ในการปัดเศษครึ่งแม้จะเกิดขึ้นเมื่อเกิดข้อผิดพลาดในการเข้ารหัสแทน

การใช้งานจุดลอยตัวของ IEEE จะทำการปัดเศษครึ่ง แต่พวกเขาจะทำครึ่งวงกลมแบบไบนารีไม่ใช่การปัดเศษทศนิยมแบบครึ่ง ดังนั้นคุณอาจโอเค


ฉันเคยใช้วิธีนี้มาระยะหนึ่งแล้ว แต่ฉันคิดว่าpowมันเป็นการดำเนินการที่แพงเกินไปสำหรับการปัดเศษ?
Xerus

อย่าปรับให้เหมาะสมจนกว่าคุณจะมีปัญหาเรื่องประสิทธิภาพ สำคัญกว่าที่จะถูกต้องเร็วกว่า และฉันก็ไม่สามารถจินตนาการได้ว่าแอปพลิเคชั่นที่ประสิทธิภาพของการปัดเศษแบบควบคุมจะเป็นปัญหาเว้นแต่ว่าคุณเป็นวีซ่าหรือมาสเตอร์การ์ด และ pow () น่าจะเร็วกว่า round ()
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

นี่เป็นวิธีที่มีความเป็นมืออาชีพน้อยกว่าและแพงกว่ามาก แต่ควรเข้าใจง่ายกว่าและมีประโยชน์สำหรับผู้เริ่มต้น

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

ฉันคิดว่าสิ่งที่คุณต้องการคือ

return value.toString();

และใช้ค่าส่งคืนเพื่อแสดง

value.floatValue();

จะคืนค่า 625.3 เสมอเพราะส่วนใหญ่ใช้เพื่อคำนวณบางสิ่ง


แต่ฉันต้องการผลลัพธ์คือเลขทศนิยมไม่ใช่สตริง
seba123neo

2
หากคุณต้องการทุ่นเพื่อแสดงให้ผู้ใช้เห็นอาจมีบางอย่างผิดปกติในการออกแบบแอปพลิเคชัน โดยปกติแล้ว float จะใช้ในการคำนวณและใช้สตริงเพื่อแสดงให้ผู้ใช้เห็น
n3utrino

ขอโทษคุณพูดถูกฉันสับสนเพียงแค่จัดรูปแบบตัวเลขเมื่อแสดงบนหน้าจอไม่ใช่ก่อนหน้านั่นคือคำถามของฉันขอบคุณมากปัญหาได้รับการแก้ไข
seba123neo

1

ฉันกำลังมองหาคำตอบสำหรับคำถามนี้และต่อมาฉันได้พัฒนาวิธีการ! :) คำเตือนที่เป็นธรรมมันรวมค่า

private float limitDigits(float number) {
    return Float.valueOf(String.format(Locale.getDefault(), "%.2f", number));
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.