ฉันต้องการพิมพ์ค่าสองเท่าใน Java โดยไม่มีแบบฟอร์มชี้แจง
double dexp = 12345678;
System.out.println("dexp: "+dexp);
มันแสดงให้เห็นโน้ต E 1.2345678E7
นี่:
ฉันต้องการพิมพ์แบบนี้: 12345678
วิธีที่ดีที่สุดในการป้องกันสิ่งนี้คืออะไร?
ฉันต้องการพิมพ์ค่าสองเท่าใน Java โดยไม่มีแบบฟอร์มชี้แจง
double dexp = 12345678;
System.out.println("dexp: "+dexp);
มันแสดงให้เห็นโน้ต E 1.2345678E7
นี่:
ฉันต้องการพิมพ์แบบนี้: 12345678
วิธีที่ดีที่สุดในการป้องกันสิ่งนี้คืออะไร?
คำตอบ:
คุณสามารถใช้printf()
กับ%f
:
double dexp = 12345678;
System.out.printf("dexp: %f\n", dexp);
dexp: 12345678.000000
นี้จะพิมพ์ หากคุณไม่ต้องการส่วนที่เป็นเศษส่วนให้ใช้
System.out.printf("dexp: %.0f\n", dexp);
การใช้ภาษานี้รูปแบบตัวระบุที่อธิบายไว้ในเอกสาร
เริ่มต้นtoString()
รูปแบบที่ใช้ในรหัสเดิมของคุณถูกสะกดออกมาที่นี่
%.0f
ควรมีวรรคเกี่ยวกับ
%.0f
ปัดเศษตัวเลข มีวิธีการทิ้งศูนย์ต่อท้ายหรือไม่?
วิธีที่แตกต่างกันห้าวิธีในการแปลง double เป็นหมายเลขปกติ:
import java.math.BigDecimal;
import java.text.DecimalFormat;
public class Runner {
public static void main(String[] args) {
double myvalue = 0.00000021d;
//Option 1 Print bare double.
System.out.println(myvalue);
//Option2, use decimalFormat.
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(8);
System.out.println(df.format(myvalue));
//Option 3, use printf.
System.out.printf("%.9f", myvalue);
System.out.println();
//Option 4, convert toBigDecimal and ask for toPlainString().
System.out.print(new BigDecimal(myvalue).toPlainString());
System.out.println();
//Option 5, String.format
System.out.println(String.format("%.12f", myvalue));
}
}
โปรแกรมนี้พิมพ์:
2.1E-7
.00000021
0.000000210
0.000000210000000000000001085015324114868562332958390470594167709350585
0.000000210000
ซึ่งมีค่าเหมือนกันทั้งหมด
protip: ถ้าคุณกำลังสับสนว่าทำไมผู้ที่ตัวเลขสุ่มปรากฏเกินกว่าเกณฑ์ที่กำหนดในมูลค่าคู่วิดีโอนี้อธิบาย: computerphile ทำไม0.1
+ 0.2
เท่ากับ0.30000000000001
?
ในระยะสั้น:
หากคุณต้องการกำจัดค่าศูนย์ต่อท้ายและปัญหาโลแคลคุณควรใช้:
double myValue = 0.00000021d;
DecimalFormat df = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(340); // 340 = DecimalFormat.DOUBLE_FRACTION_DIGITS
System.out.println(df.format(myValue)); // Output: 0.00000021
คำอธิบาย:
ทำไมคำตอบอื่น ๆ ไม่เหมาะกับฉัน:
Double.toString()
หรือSystem.out.println
หรือFloatingDecimal.toJavaFormatString
ใช้สัญลักษณ์ทางวิทยาศาสตร์ถ้าสองครั้งมีค่าน้อยกว่า 10 ^ -3 หรือมากกว่าหรือเท่ากับ 10 ^ 7โดยการใช้%f
ความแม่นยำทศนิยมเริ่มต้นคือ 6 มิฉะนั้นคุณสามารถฮาร์ดโค้ดได้ แต่จะส่งผลให้มีค่าศูนย์เพิ่มถ้าคุณมีทศนิยมน้อยลง ตัวอย่าง:
double myValue = 0.00000021d;
String.format("%.12f", myvalue); // Output: 0.000000210000
โดยการใช้setMaximumFractionDigits(0);
หรือ%.0f
คุณลบความแม่นยำทศนิยมใด ๆ ซึ่งเป็นเรื่องปกติสำหรับจำนวนเต็ม / ยาว แต่ไม่ใช่สำหรับสองเท่า:
double myValue = 0.00000021d;
System.out.println(String.format("%.0f", myvalue)); // Output: 0
DecimalFormat df = new DecimalFormat("0");
System.out.println(df.format(myValue)); // Output: 0
โดยใช้ DecimalFormat คุณจะขึ้นอยู่กับท้องถิ่น ในโลแคลฝรั่งเศสตัวคั่นทศนิยมคือเครื่องหมายจุลภาคไม่ใช่จุด:
double myValue = 0.00000021d;
DecimalFormat df = new DecimalFormat("0");
df.setMaximumFractionDigits(340);
System.out.println(df.format(myvalue)); // Output: 0,00000021
การใช้ภาษาอังกฤษให้แน่ใจว่าคุณได้รับจุดสำหรับตัวคั่นทศนิยมทุกที่ที่โปรแกรมของคุณจะทำงาน
ทำไมใช้ 340 แล้วsetMaximumFractionDigits
?
เหตุผลสองประการ:
setMaximumFractionDigits
ยอมรับจำนวนเต็ม แต่การนำไปปฏิบัติมีจำนวนสูงสุดที่อนุญาตDecimalFormat.DOUBLE_FRACTION_DIGITS
ซึ่งเท่ากับ 340Double.MIN_VALUE = 4.9E-324
ดังนั้นด้วยตัวเลข 340 คุณแน่ใจว่าจะไม่ปัดเศษของคุณและสูญเสียความแม่นยำnew BigDecimal(myvalue).toPlainString()
จากคำอธิบายที่docs.oracle.com/javase/7/docs/api/java/math/ ...... ) มันไม่ชัดเจนในทันทีว่ามันจะทำงานอย่างไรเมื่อได้รับตัวเลขประเภทต่าง ๆ แต่จะกำจัดสัญกรณ์ทางวิทยาศาสตร์ .
new BigDecimal(0.00000021d).toPlainString()
การส่งออก0.0000002100000000000000010850153241148685623329583904705941677093505859375
ที่ไม่ได้เป็นสิ่งที่คุณคาดหวัง ...
BigDecimal.valueOf(0.00000021d).toPlainString()
ทำงานได้เป็นอย่างดี (ใช้ตัวสร้างสตริงของ BigDecimal นั่นเป็นสาเหตุ)
DecimalFormat
คุณสามารถลองกับ ด้วยคลาสนี้คุณจะสามารถแยกวิเคราะห์ตัวเลขได้อย่างยืดหยุ่น
คุณสามารถกำหนดรูปแบบที่คุณต้องการใช้
ในกรณีของคุณเช่น:
double test = 12345678;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(0);
System.out.println(df.format(test)); //12345678
ฉันมีวิธีแก้ไขปัญหาอื่นที่เกี่ยวข้องกับ toPlainString () ของ BigDecimal แต่คราวนี้ใช้ String-constructor ซึ่งแนะนำใน javadoc:
ตัวสร้างนี้เข้ากันได้กับค่าที่ส่งกลับโดย Float.toString และ Double.toString นี่เป็นวิธีที่นิยมใช้ในการแปลง float หรือ double เป็น BigDecimal เนื่องจากไม่ได้รับความทุกข์ยากจากตัวสร้าง BigDecimal (double)
ดูเหมือนว่าในรูปแบบที่สั้นที่สุด:
return new BigDecimal(myDouble.toString()).stripTrailingZeros().toPlainString();
ก่อน Java 8 จะให้ผลลัพธ์เป็น "0.0" สำหรับ Doubles ที่มีค่าเป็นศูนย์ใด ๆ ดังนั้นคุณจะต้องเพิ่ม:
if (myDouble.doubleValue() == 0)
return "0";
ต้องมีการตรวจสอบ NaN และค่าที่ไม่สิ้นสุด
ผลสุดท้ายของการพิจารณาทั้งหมดเหล่านี้:
public static String doubleToString(Double d) {
if (d == null)
return null;
if (d.isNaN() || d.isInfinite())
return d.toString();
// Pre Java 8, a value of 0 would yield "0.0" below
if (d.doubleValue() == 0)
return "0";
return new BigDecimal(d.toString()).stripTrailingZeros().toPlainString();
}
นอกจากนี้ยังสามารถคัดลอก / วางเพื่อทำงานได้ดีกับโฟลท
d.doubleValue() == 0
แทนd == 0
?
วิธีนี้จะใช้ได้ตราบใดที่หมายเลขของคุณเป็นจำนวนเต็ม:
double dnexp = 12345678;
System.out.println("dexp: " + (long)dexp);
หากตัวแปรสองตัวมีความแม่นยำหลังจากจุดทศนิยมมันจะตัดทอน
ฉันต้องการแปลงค่าสองเท่าเป็นค่าเงินและพบว่าโซลูชันส่วนใหญ่นั้นใช้ได้ แต่ไม่ใช่สำหรับฉัน
DecimalFormat
ที่สุดก็ทางที่ผมดังนั้นนี่คือสิ่งที่ผมเคยทำ:
public String foo(double value) //Got here 6.743240136E7 or something..
{
DecimalFormat formatter;
if(value - (int)value > 0.0)
formatter = new DecimalFormat("0.00"); // Here you can also deal with rounding if you wish..
else
formatter = new DecimalFormat("0");
return formatter.format(value);
}
อย่างที่คุณเห็นถ้าจำนวนนั้นเป็นธรรมชาติที่ฉันได้รับ - พูด - 20000000 แทน 2E7 (ฯลฯ ) - ไม่มีจุดทศนิยม
และถ้าเป็นทศนิยมฉันจะได้ทศนิยมสองหลักเท่านั้น
คอมไพเลอร์ Java / Kotlin แปลงค่าใด ๆ ที่มากกว่า 9999999 (มากกว่าหรือเท่ากับ 10 ล้าน) เป็นสัญกรณ์ทางวิทยาศาสตร์เช่น สัญกรณ์ Epsilion
เช่น 12345678 ถูกแปลงเป็น 1.2345678E7
ใช้รหัสนี้เพื่อหลีกเลี่ยงการแปลงโดยอัตโนมัติเป็นเครื่องหมายทางวิทยาศาสตร์:
fun setTotalSalesValue(String total) {
var valueWithoutEpsilon = total.toBigDecimal()
/* Set the converted value to your android text view using setText() function */
salesTextView.setText( valueWithoutEpsilon.toPlainString() )
}
รหัสต่อไปนี้จะตรวจสอบว่าหมายเลขที่ให้ไว้แสดงในรูปแบบทางวิทยาศาสตร์หรือไม่ ถ้าเป็นเช่นนั้นมันจะแสดงในงานนำเสนอปกติที่มีตัวเลขสูงสุด '25'
static String convertFromScientificNotation(double number) {
// Check if in scientific notation
if (String.valueOf(number).toLowerCase().contains("e")) {
System.out.println("The scientific notation number'"
+ number
+ "' detected, it will be converted to normal representation with 25 maximum fraction digits.");
NumberFormat formatter = new DecimalFormat();
formatter.setMaximumFractionDigits(25);
return formatter.format(number);
} else
return String.valueOf(number);
}
ฉันคิดว่าทุกคนมีความคิดที่ถูกต้อง แต่คำตอบทั้งหมดไม่ตรงไปตรงมา ฉันเห็นว่านี่เป็นโค้ดที่มีประโยชน์มาก นี่คือตัวอย่างของสิ่งที่จะทำงาน:
System.out.println(String.format("%.8f", EnterYourDoubleVariableHere));
".8"
เป็นที่ที่คุณกำหนดจำนวนตำแหน่งทศนิยมที่คุณต้องการจะแสดง
ฉันกำลังใช้ Eclipse และทำงานได้ไม่มีปัญหา
หวังว่านี่จะเป็นประโยชน์ ฉันขอขอบคุณข้อเสนอแนะใด ๆ !
ฉันมีปัญหาเดียวกันนี้ในรหัสการผลิตของฉันเมื่อฉันใช้เป็นอินพุตสตริงไปยังฟังก์ชัน math.Eval () ซึ่งใช้สตริงเช่น "x + 20/50"
ฉันดูบทความหลายร้อย ... ในที่สุดฉันก็ไปด้วยเพราะความเร็ว และเนื่องจากฟังก์ชั่น Eval จะแปลงกลับเป็นรูปแบบตัวเลขของตัวเองในที่สุดและ math.Eval () ไม่สนับสนุน E-07 ต่อท้ายที่วิธีอื่นกลับมาและสิ่งที่มากกว่า 5 dp นั้นมีรายละเอียดมากเกินไปสำหรับแอปพลิเคชันของฉัน .
ตอนนี้ใช้ในรหัสการผลิตสำหรับแอปพลิเคชันที่มีผู้ใช้มากกว่า 1,000 ราย ...
double value = 0.0002111d;
String s = Double.toString(((int)(value * 100000.0d))/100000.0d); // Round to 5 dp
s display as: 0.00021
นี่อาจจะเป็นแทนเจนต์ .... แต่ถ้าคุณต้องการใส่ค่าตัวเลขเป็นจำนวนเต็ม (ที่ใหญ่เกินไปที่จะเป็นจำนวนเต็ม) ใน serializer (JSON เป็นต้น) คุณอาจต้องการ "BigInterger"
ตัวอย่าง: value เป็นสตริง - 7515904334
เราจำเป็นต้องแสดงมันเป็นตัวเลขในข้อความ Json: {"contact_phone": "800220-3333", "servicer_id": 7515904334, "servicer_name": "SOME CORPORATION"}
เราไม่สามารถพิมพ์ได้หรือเราจะได้รับสิ่งนี้: {"contact_phone": "800220-3333", "servicer_id": "7515904334", "servicer_name": "SOME CORPORATION"}
การเพิ่มค่าให้กับโหนดเช่นนี้ทำให้เกิดผลลัพธ์ที่ต้องการ: BigInteger.valueOf (Long.parseLong (value, 10))
ฉันไม่แน่ใจว่านี่เป็นหัวข้อจริงๆ แต่เนื่องจากคำถามนี้เป็นคำถามยอดนิยมของฉันเมื่อฉันค้นหาวิธีแก้ปัญหาของฉันฉันคิดว่าฉันจะแบ่งปันที่นี่เพื่อประโยชน์ของผู้อื่นโกหกฉันผู้ค้นหาไม่ดี : D
สำหรับค่าจำนวนเต็มที่แทนด้วย a double
คุณสามารถใช้รหัสนี้ซึ่งเร็วกว่าวิธีอื่น ๆ
public static String doubleToString(final double d) {
// check for integer, also see https://stackoverflow.com/a/9898613/868941 and
// https://github.com/google/guava/blob/master/guava/src/com/google/common/math/DoubleMath.java
if (isMathematicalInteger(d)) {
return Long.toString((long)d);
} else {
// or use any of the solutions provided by others
return Double.toString(d);
}
}
// Java 8+
public static boolean isMathematicalInteger(final double d) {
return StrictMath.rint(d) == d && Double.isFinite(d);
}
โซลูชันของฉัน: String str = String.format ("% .0f", yourDouble);
dexp: 12345681.000000
เป็นค่าที่ผิดและจริง ๆ แล้วหลังจากนั้นฉันต้องการที่จะแสดงมันบนหน้าเว็บของฉันที่มันแสดงเช่นนี้1.2345678E7
มันมีอยู่แล้วที่ฉันสามารถจัดเก็บไว้ในคู่เหมือน12345678
และวิธีอื่น ๆ ?