मैं जावा का उपयोग करके वैज्ञानिक संकेतन के बिना एक डबल मूल्य कैसे प्रिंट कर सकता हूं?


222

मैं घातीय रूप के बिना जावा में एक डबल मूल्य मुद्रित करना चाहता हूं।

double dexp = 12345678;
System.out.println("dexp: "+dexp);

यह इस ई संकेतन को दर्शाता है 1.2345678E7:।

मैं चाहता हूं कि इसे इस तरह से छापें: 12345678

इससे बचाव का सबसे अच्छा तरीका क्या है?

जवाबों:


116

आप के printf()साथ उपयोग कर सकते हैं %f:

double dexp = 12345678;
System.out.printf("dexp: %f\n", dexp);

यह छपेगा dexp: 12345678.000000। यदि आप भिन्नात्मक भाग नहीं चाहते हैं, तो उपयोग करें

System.out.printf("dexp: %.0f\n", dexp);

यह डॉक्यूमेंटेशन में बताई गई प्रारूप निर्दिष्ट भाषा का उपयोग करता है ।

toString()आपके मूल कोड में उपयोग किए गए डिफ़ॉल्ट प्रारूप को यहाँ वर्तनी दिया गया है


1
लेकिन यह दिखाया गया है dexp: 12345681.000000कि यह गलत मूल्य है। और वास्तव में इसके बाद मैं इसे अपने वेब पेज पर प्रदर्शित करना चाहता हूं, जहां यह इस तरह प्रदर्शित होता है 1.2345678E7। वैसे भी, जिसके माध्यम से मैं इसे किसी भी तरह से 12345678और किसी भी तरह से किसी भी तरह से संग्रहीत कर सकता हूं ?
नीच

1
@ उत्तर: आप उत्तर के पुराने, अधूरे संस्करण को देख रहे होंगे। पृष्ठ को पुनः लोड करने का प्रयास करें। के बारे में एक पैराग्राफ होना चाहिए %.0f
एनपीई

@ कुशल आप एक int के रूप में dexp स्टोर कर सकते हैं ताकि आप इसे आसानी से दोनों तरह से उपयोग कर सकें
जस्टिन

10
यह बंद राउंड संख्या
भ्रमित

6
%.0fनंबर बंद कर देता है। वहाँ एक तरीका है सिर्फ पीछे चल रहे शून्य को त्यागने का?
नूरशोमिक

239

जावा एक डबल में ई नोटेशन को रोकता है:

एक दोहरे को सामान्य संख्या में बदलने के पांच अलग-अलग तरीके:

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: यदि आप इस उलझन में हैं कि उन यादृच्छिक अंकों को दोहरे मान में एक निश्चित सीमा से अधिक क्यों दिखाई देता है, तो यह वीडियो बताता है: कंप्यूटरफाइल क्यों 0.1+ 0.2समान है 0.30000000000001?

http://youtube.com/watch?v=PZRI1IfStY0


उत्तर के लिए बहुत बहुत धन्यवाद और विशेष रूप से टिप .. उस वीडियो ने मेरी उलझन को हल किया।
अनुजदेव

97

संक्षेप में:

यदि आप ट्रेलिंग जीरो और लोकेल समस्याओं से छुटकारा पाना चाहते हैं, तो आपको इसका उपयोग करना चाहिए:

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जिनकी अनुमति 340 के बराबर है
  • Double.MIN_VALUE = 4.9E-324 इसलिए 340 अंकों के साथ आप सुनिश्चित हैं कि अपने दोहरे को गोल न करें और सटीक खोएं।

आपके new BigDecimal(myvalue).toPlainString()विवरण से docs.oracle.com/javase/7/docs/api/java/math/… ) पर आपकी क्या राय है , यह तुरंत स्पष्ट नहीं है कि विभिन्न प्रकार के नंबर दिए जाने पर यह कैसे व्यवहार करता है, लेकिन यह वैज्ञानिक अधिसूचना को समाप्त करता है ।
डेरेक महार

4
new BigDecimal(0.00000021d).toPlainString()उत्पादन 0.0000002100000000000000010850153241148685623329583904705941677093505859375जो आप की उम्मीद नहीं है ...
JBE

किसी भी विचार कैसे scala में अपने जवाब का उपयोग करने के लिए? शायद उचित आयात की बात है लेकिन मैं यहां नया हूं।
जंगोर्की 16

BigDecimal.valueOf(0.00000021d).toPlainString()के रूप में अच्छी तरह से काम करता है (यह क्यों BigDecimal के स्ट्रिंग निर्माता का उपयोग करता है)
marco

27

आप इसके साथ कोशिश कर सकते हैं DecimalFormat। इस वर्ग के साथ आप अपनी संख्या को कम करने में बहुत लचीले हैं।
आप उस पैटर्न को बिल्कुल सेट कर सकते हैं जिसका आप उपयोग करना चाहते हैं।
आपके मामले में उदाहरण के लिए:

double test = 12345678;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(0);
System.out.println(df.format(test)); //12345678

16

मुझे BigDecimal's toPlainString () से युक्त एक और समाधान मिला है, लेकिन इस बार स्ट्रिंग-कंस्ट्रक्टर का उपयोग करके, जिसे javadoc में अनुशंसित किया गया है:

यह कंस्ट्रक्टर फ्लोट.टोस्ट्रिंग और डबल.टोस्ट्रिंग द्वारा लौटाए गए मूल्यों के अनुकूल है। यह आमतौर पर एक फ्लोट या डबल को बिगडेसिमल में बदलने का पसंदीदा तरीका है, क्योंकि यह बिगडेसीमल (डबल) कंस्ट्रक्टर की अप्रत्याशितता से ग्रस्त नहीं है।

यह अपने सबसे छोटे रूप में इस तरह दिखता है:

return new BigDecimal(myDouble.toString()).stripTrailingZeros().toPlainString();

जावा 8 से पहले, किसी भी शून्य-मूल्यवान डबल्स के लिए "0.0" में यह परिणाम है, इसलिए आपको जोड़ना होगा:

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

यह भी फ्लोट के साथ अच्छी तरह से काम करने के लिए कॉपी / पेस्ट किया जा सकता है।


2
मैंने एक स्ट्रिंग के लिए एक डबल मान परिवर्तित करने के लिए अनगिनत योजनाएं पढ़ी हैं और यह सबसे अच्छा है: लघु, सीधी, विन्यास योग्य।
पॉल

महान समाधान, ने वास्तव में मुझे स्ट्रिंग के दोहरे मूल्यों को परिवर्तित करने और वैज्ञानिक संकेतन से बचने में मदद की। धन्यवाद!
pleft

d.doubleValue() == 0इसके बजाय क्यों d == 0?
अलेक्सई फैंडो

क्योंकि यह ऑटो-अनबॉक्सिंग से बचा जाता है, जो मुझे उस स्थिति में बेहतर लगता है, लेकिन इस पर विचार अलग-अलग हो सकते हैं। यदि आप जावा 8 (9 शायद एक ही होंगे) पर हैं, तो आप उन 2 पंक्तियों को पूरी तरह से छोड़ सकते हैं।
मैनुअल

सिर्फ जावा 9 के साथ कोशिश की, उन 2 लाइनों को 9 पर भी छोड़ा जा सकता है।
मैनुअल

8

यह तब तक काम करेगा जब तक आपका नंबर एक पूर्ण संख्या है:

double dnexp = 12345678;
System.out.println("dexp: " + (long)dexp);

यदि दशमलव बिंदु के बाद डबल चर में सटीकता है, तो यह इसे छोटा कर देगा।


4

मुझे मुद्रा के कुछ मूल्यों को बदलने की आवश्यकता थी और पाया कि अधिकांश समाधान ठीक थे, लेकिन मेरे लिए नहीं।

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

जैसा कि आप देख सकते हैं, यदि संख्या स्वाभाविक है, तो मैं कहता हूं - 2E7 (आदि) के बजाय 20000000 - बिना किसी दशमलव बिंदु के।

और अगर यह दशमलव है, तो मुझे केवल दो दशमलव अंक मिलते हैं।


4

जावा / कोटलिन कम्पाइलर 9999999 (10 मिलियन से अधिक या उससे अधिक) से अधिक के किसी भी मूल्य को वैज्ञानिक संकेतन अर्थात् में परिवर्तित करता है। एप्सिलियन संकेतन

Ex: 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() )
    }

3

निम्नलिखित कोड का पता लगाता है यदि प्रदान की गई संख्या को वैज्ञानिक संकेतन में प्रस्तुत किया गया है। यदि ऐसा है तो इसे अधिकतम 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);
}

2

मुझे लगता है कि सभी को सही विचार था, लेकिन सभी जवाब सीधे नहीं थे। मैं इसे कोड का एक बहुत उपयोगी टुकड़ा होने के रूप में देख सकता हूं। यहाँ क्या काम करेगा का एक टुकड़ा है:

System.out.println(String.format("%.8f", EnterYourDoubleVariableHere));

वह जगह ".8"है जहाँ आप दशमलव स्थानों की संख्या निर्धारित करते हैं जिन्हें आप दिखाना चाहते हैं।

मैं ग्रहण का उपयोग कर रहा हूं और इसने कोई समस्या नहीं की।

आशा है कि यह मददगार था। मैं किसी भी प्रतिक्रिया की सराहना करूंगा!


1

मुझे अपने प्रोडक्शन कोड में यही समस्या थी जब मैं इसे एक स्ट्रिंग इनपुट के रूप में मैथ.ईवल () फ़ंक्शन के लिए उपयोग कर रहा था जो "x + 20/50" जैसे स्ट्रिंग लेता है

मैंने सैकड़ों लेखों को देखा ... अंत में मैं गति के कारण इसके साथ गया। और क्योंकि Eval फ़ंक्शन इसे अंततः अपने स्वयं के नंबर स्वरूप में बदलने जा रहा था और math.Eval () ने अनुगामी E-07 का समर्थन नहीं किया जो कि अन्य तरीके वापस आ गए, और 5 डीपी से अधिक कुछ भी मेरे आवेदन के लिए बहुत अधिक विवरण था ।

यह अब एक कोड के लिए उत्पादन कोड में उपयोग किया जाता है जिसमें 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

1

यह एक स्पर्शरेखा हो सकती है .... लेकिन अगर आपको एक धारावाहिक (JSON, आदि) में पूर्णांक के रूप में एक संख्यात्मक मान (जो कि एक पूर्णांक के लिए बहुत बड़ा है) डालने की आवश्यकता है, तो आप शायद "BigInterger" चाहते हैं

उदाहरण: मान एक स्ट्रिंग है - 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 (मान, 10))

मुझे यकीन नहीं है कि यह वास्तव में विषय है, लेकिन चूंकि यह प्रश्न मेरी शीर्ष हिट था जब मैंने अपने समाधान की खोज की, मैंने सोचा कि मैं यहां दूसरों के लाभ के लिए साझा करूंगा, मुझे झूठ बोलें, जो खराब खोज करते हैं। : डी


-1

पूर्णांक मानों का प्रतिनिधित्व करने के लिए 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);
}

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.