ฉันจะตัดทศนิยมสองตำแหน่งให้เหลือเพียงสองตำแหน่งใน Java ได้อย่างไร


98

ตัวอย่างเช่นฉันมีตัวแปร 3.545555555 ซึ่งฉันต้องการตัดให้เหลือเพียง 3.54


21
นี่ไม่ใช่รายการที่ซ้ำกัน การตัดทอนและการปัดเศษเป็นสองสิ่งที่แตกต่างกันอย่างสิ้นเชิง
markthegrea

ตกลงไม่รู้ว่าทำไมถึงถูกตั้งค่าสถานะว่าซ้ำกัน
Bassinator

คำตอบ:


147

หากคุณต้องการเพื่อการแสดงผลให้ใช้java.text.DecimalFormat:

 new DecimalFormat("#.##").format(dblVar);

หากคุณต้องการใช้ในการคำนวณให้ใช้java.lang.Math:

 Math.floor(value * 100) / 100;

50
สิ่งนี้จะไม่แสดง 3.545555555 เป็น 3.54 ที่ถูกตัดปลาย แต่ปัดเป็น 3.55 DecimalFormat.setRoundingMode () จำเป็นต้องตั้งค่าเป็น RoundingMode.FLOOR;
Christian García

9
สิ่งนี้ใช้ไม่ได้สำหรับฉัน Math.floor (9.62 * 100) / 100 ให้ 9.61
Mani

4
การใช้floorเพื่อตัดทอนใช้ได้กับค่าบวกเท่านั้น
Dev

4
@ ChristianGarcía Truncation ทำได้อย่างถูกต้องโดยRoundingMode.DOWNให้RoudingMode.FLOORปัดเศษเป็นค่าอนันต์เชิงลบเสมอ
Dev

46
DecimalFormat df = new DecimalFormat(fmt);
df.setRoundingMode(RoundingMode.DOWN);
s = df.format(d);

ตรวจสอบที่มีอยู่RoundingModeและDecimalFormat.


ไม่ได้กล่าวถึงคำถามซึ่งขอให้มีการตัดทอนแทนที่จะปัดเศษ
Basil Bourque

8
@BasilBourque RoundingMode.DOWN คือการตัดทอน เปรียบเทียบกับคำตอบอื่น ๆ ที่แนะนำฟังก์ชันพื้นอย่างไม่ถูกต้อง (ชั้นจะตัดทอนจำนวนบวกเท่านั้น) สิ่งนี้ใช้ได้กับทั้งค่าบวกและค่าลบ
Dev

1
@ เดฟฉันยืนแก้ไข ตอนนี้ฉันเห็นแล้วว่าDOWNมีผลของการตัดทอนจำนวนทั้งบวกและลบ เท่าที่เห็นในตารางตัวอย่างในเอกสาร
Basil Bourque

25

Bit Old Forum ไม่มีคำตอบใดที่ใช้ได้กับทั้งค่าบวกและค่าลบ (ฉันหมายถึงการคำนวณและเพียงแค่ตัดทอนโดยไม่ต้องปัดเศษ) จากลิงก์How to round a decimal places to n decimal places in Java link

private static BigDecimal truncateDecimal(double x,int numberofDecimals)
{
    if ( x > 0) {
        return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_FLOOR);
    } else {
        return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_CEILING);
    }
}

วิธีนี้ใช้ได้ผลดีสำหรับฉัน

System.out.println(truncateDecimal(0, 2));
    System.out.println(truncateDecimal(9.62, 2));
    System.out.println(truncateDecimal(9.621, 2));
    System.out.println(truncateDecimal(9.629, 2));
    System.out.println(truncateDecimal(9.625, 2));
    System.out.println(truncateDecimal(9.999, 2));
    System.out.println(truncateDecimal(-9.999, 2));
    System.out.println(truncateDecimal(-9.0, 2));

ผล :

0.00
9.62
9.62
9.62
9.62
9.99
-9.99
-9.00

นี่คือคำตอบที่ปรับขนาดได้สำหรับกรณีทดสอบเพิ่มเติม
diego matos - คิคิ

ส่งคืน BigDecimal (x) .setScale ใหม่ (numberofDecimals, RoundingMode.DOWN) .doubleValue ();
Shimon Doodkin

ดูเหมือนว่าการปัดเศษลงจะเหมือนกับสิ่งที่คุณหมายถึง: docs.oracle.com/javase/7/docs/api/java/math/RoundingMode.html
Shimon Doodkin

9

หมายเหตุแรกที่doubleเป็นส่วนไบนารีและไม่ได้จริงๆมีตำแหน่งทศนิยม

หากคุณต้องการตำแหน่งทศนิยมให้ใช้ a BigDecimalซึ่งมีsetScale()วิธีการตัดทอนหรือใช้DecimalFormatเพื่อรับ a String.


7

ถ้าด้วยเหตุผลใด ๆ ก็ตามที่คุณไม่ต้องการที่จะใช้BigDecimalคุณสามารถโยนของคุณdoubleไปยังintที่จะตัดมัน

หากคุณต้องการตัดทอนไปยังตำแหน่งOnes :

  • เพียงแค่ส่งไปที่ int

ไปยังสถานที่ที่สิบ :

  • คูณด้วยสิบ
  • ส่งไปที่ int
  • ส่งกลับไปที่ double
  • แล้วหารด้วยสิบ

สถานที่Hundreths

  • คูณและหารด้วย 100 เป็นต้น

ตัวอย่าง:

static double truncateTo( double unroundedNumber, int decimalPlaces ){
    int truncatedNumberInt = (int)( unroundedNumber * Math.pow( 10, decimalPlaces ) );
    double truncatedNumber = (double)( truncatedNumberInt / Math.pow( 10, decimalPlaces ) );
    return truncatedNumber;
}

ในตัวอย่างนี้decimalPlacesจะเป็นจำนวนสถานที่ PAST สถานที่ที่คุณต้องการไปดังนั้น 1 จะปัดเศษเป็นอันดับที่สิบ 2 ถึงที่ร้อยและอื่น ๆ (0 รอบไปยังตำแหน่งที่หนึ่งและลบหนึ่งถึงสิบ ฯลฯ )


3
นี่เป็นวิธีแก้ปัญหาทั่วไปที่น่ากลัว ทั้งการทวีคูณและการร่ายจะจบลงด้วยการทิ้งข้อมูลและส่งผลให้ตัวเลขสุ่มที่มีประสิทธิภาพunroundedNumberนั้นมีขนาดใหญ่พอ มันอาจจะทำงานเช่นในคำถาม doubleแต่การแก้ปัญหาทั่วไปควรจะทำงานใด ๆ
blm

6

การจัดรูปแบบเป็นสตริงและการแปลงกลับเป็นสองเท่าฉันคิดว่าจะให้ผลลัพธ์ที่คุณต้องการ

ค่าสองเท่าจะไม่เป็น round (), floor () หรือ ceil ()

การแก้ไขอย่างรวดเร็วอาจเป็น:

 String sValue = (String) String.format("%.2f", oldValue);
 Double newValue = Double.parseDouble(sValue);

คุณสามารถใช้ sValue เพื่อวัตถุประสงค์ในการแสดงผลหรือค่า newValue สำหรับการคำนวณ


1
มันปัดเศษให้ฉันเป็นค่าที่ใกล้ที่สุด เช่น: 0.018 จะถูกแปลงเป็น 0.02 เมื่อฉันทำสิ่งนี้
karan patel


3

คุณสามารถใช้ออบเจ็กต์ NumberFormat Class เพื่อทำงานให้สำเร็จ

// Creating number format object to set 2 places after decimal point
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(2);            
nf.setGroupingUsed(false);

System.out.println(nf.format(precision));// Assuming precision is a double type variable

3

3.545555555 จะได้ 3.54 ลองติดตามสิ่งนี้:

    DecimalFormat df = new DecimalFormat("#.##");

    df.setRoundingMode(RoundingMode.FLOOR);

    double result = new Double(df.format(3.545555555);

สิ่งนี้จะให้ = 3.54!


แต่ฉันจะได้รับ 3.5 ถ้าฉันตั้งค่านั้นเป็น 3.50123
Cyrus

1

นี่คือวิธีที่ฉันใช้:

double a=3.545555555; // just assigning your decimal to a variable
a=a*100;              // this sets a to 354.555555
a=Math.floor(a);      // this sets a to 354
a=a/100;              // this sets a to 3.54 and thus removing all your 5's

สิ่งนี้สามารถทำได้:

a=Math.floor(a*100) / 100;

0

อาจจะดังต่อไปนี้:

double roundTwoDecimals(double d) { 
      DecimalFormat twoDForm = new DecimalFormat("#.##"); 
      return Double.valueOf(twoDForm.format(d));
}  

ดูคำตอบอื่น ๆ คุณไม่สามารถทำได้อย่างน่าเชื่อถือหากคำตอบคือการแสดงเป็นทศนิยม
Marquis of Lorne

0

การตรวจสอบอย่างรวดเร็วคือการใช้เมธอด Math.floor ฉันสร้างวิธีการตรวจสอบสองตำแหน่งสำหรับทศนิยมสองตำแหน่งหรือน้อยกว่าด้านล่าง:

public boolean checkTwoDecimalPlaces(double valueToCheck) {

    // Get two decimal value of input valueToCheck 
    double twoDecimalValue = Math.floor(valueToCheck * 100) / 100;

    // Return true if the twoDecimalValue is the same as valueToCheck else return false
    return twoDecimalValue == valueToCheck;
}

-1

ผมมีรุ่นที่ปรับเปลี่ยนเล็กน้อยมณี 's

private static BigDecimal truncateDecimal(final double x, final int numberofDecimals) {
    return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_DOWN);
}

public static void main(String[] args) {
    System.out.println(truncateDecimal(0, 2));
    System.out.println(truncateDecimal(9.62, 2));
    System.out.println(truncateDecimal(9.621, 2));
    System.out.println(truncateDecimal(9.629, 2));
    System.out.println(truncateDecimal(9.625, 2));
    System.out.println(truncateDecimal(9.999, 2));
    System.out.println(truncateDecimal(3.545555555, 2));

    System.out.println(truncateDecimal(9.0, 2));
    System.out.println(truncateDecimal(-9.62, 2));
    System.out.println(truncateDecimal(-9.621, 2));
    System.out.println(truncateDecimal(-9.629, 2));
    System.out.println(truncateDecimal(-9.625, 2));
    System.out.println(truncateDecimal(-9.999, 2));
    System.out.println(truncateDecimal(-9.0, 2));
    System.out.println(truncateDecimal(-3.545555555, 2));

}

เอาท์พุต:

0.00
9.62
9.62
9.62
9.62
9.99
9.00
3.54
-9.62
-9.62
-9.62
-9.62
-9.99
-9.00
-3.54

-2

สิ่งนี้ใช้ได้ผลสำหรับฉัน:

double input = 104.8695412  //For example

long roundedInt = Math.round(input * 100);
double result = (double) roundedInt/100;

//result == 104.87

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


1
คำถามเดิมเกี่ยวกับการตัดทอนไม่ใช่การปัดเศษ นอกจากนี้การแปลงคู่เป็น long จะไม่ได้ผลเลยหากคู่มีขนาดใหญ่พอ
blm

-2
//if double_v is 3.545555555
String string_v= String.valueOf(double_v);
int pointer_pos = average.indexOf('.');//we find the position of '.'
string_v.substring(0, pointer_pos+2));// in this way we get the double with only 2 decimal in string form
double_v = Double.valueOf(string_v);//well this is the final result

มันอาจจะดูอึดอัดเล็กน้อย แต่ฉันคิดว่ามันสามารถแก้ปัญหาของคุณได้ :)


รหัสนี้ทำให้งานเสร็จ แต่ไม่หรูหราและมีประสิทธิภาพต่ำ อาจเป็นเรื่องปกติในโครงการของโรงเรียน แต่ไม่ใช่วิธีแก้ปัญหาที่ใครบางคนจะใช้ในการผลิตสำหรับระบบใด ๆ เว้นแต่คุณจะต้องปวดหัวในภายหลัง
cbaldan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.