जावा में एन दशमलव स्थानों के लिए एक संख्या को गोल कैसे करें


1259

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

मैं यह भी बताना चाहूंगा कि केवल महत्वपूर्ण अंक ही प्रदर्शित होने चाहिए - यानी कोई अनुगामी शून्य नहीं होना चाहिए।

मुझे पता है कि इस विधि का उपयोग करने की एक String.formatविधि है:

String.format("%.5g%n", 0.912385);

रिटर्न:

0.91239

जो महान है, हालांकि यह हमेशा 5 दशमलव स्थानों के साथ संख्या प्रदर्शित करता है, भले ही वे महत्वपूर्ण न हों:

String.format("%.5g%n", 0.912300);

रिटर्न:

0.91230

एक और तरीका है DecimalFormatter:

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

रिटर्न:

0.91238

हालाँकि जैसा कि आप देख सकते हैं कि यह आधी-अधूरी गोलाई का उपयोग करता है। यदि यह पिछले अंक भी है तो यह नीचे की ओर होगा। मुझे यह पसंद है:

0.912385 -> 0.91239
0.912300 -> 0.9123

जावा में इसे प्राप्त करने का सबसे अच्छा तरीका क्या है?

जवाबों:


751

उपयोग करें setRoundingMode, RoundingModeस्पष्ट रूप से अपनी समस्या को अर्ध-समांतर दौर से निपटने के लिए सेट करें , फिर अपने आवश्यक आउटपुट के लिए प्रारूप पैटर्न का उपयोग करें।

उदाहरण:

DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.CEILING);
for (Number n : Arrays.asList(12, 123.12345, 0.23, 0.1, 2341234.212431324)) {
    Double d = n.doubleValue();
    System.out.println(df.format(d));
}

आउटपुट देता है:

12
123.1235
0.23
0.1
2341234.2125

संपादित करें : मूल उत्तर दोहरे मान की सटीकता को संबोधित नहीं करता है। यह ठीक है अगर आप ज्यादा परवाह नहीं करते हैं चाहे वह ऊपर या नीचे गोल हो। लेकिन अगर आप सटीक गोलाई चाहते हैं, तो आपको मूल्यों की अपेक्षित सटीकता को ध्यान में रखना होगा। फ्लोटिंग पॉइंट वैल्यू में आंतरिक रूप से एक बाइनरी प्रतिनिधित्व होता है। इसका मतलब है कि 2.7735 जैसे मूल्य में वास्तव में आंतरिक रूप से सटीक मूल्य नहीं है। यह थोड़ा बड़ा या थोड़ा छोटा हो सकता है। यदि आंतरिक मूल्य थोड़ा छोटा है, तो यह 2.7740 तक नहीं होगा। उस स्थिति को मापने के लिए, आपको उन मूल्यों की सटीकता के बारे में पता होना चाहिए जो आप के साथ काम कर रहे हैं, और गोलाई से पहले उस मूल्य को जोड़ते या घटाते हैं। उदाहरण के लिए, जब आप जानते हैं कि आपके मान 6 अंकों तक सटीक हैं, तो आधे-अधूरे मानों को गोल करने के लिए, उस सटीकता को मान में जोड़ें:

Double d = n.doubleValue() + 1e-6;

राउंड डाउन करने के लिए, सटीकता घटाएं।


9
यह शायद अब तक प्रस्तुत सबसे अच्छा समाधान है। जब मैंने पहली बार DecimalFormat क्लास को देखा था, तब मैंने इस सुविधा को स्पॉट नहीं किया था, यह केवल जावा 1.6 में पेश किया गया था। दुर्भाग्य से मैं 1.5 का उपयोग करने के लिए प्रतिबंधित हूं, लेकिन भविष्य के लिए जानना उपयोगी होगा।
एलेक्स स्परिंग 13

1
मैं के साथ इस की कोशिश की: "#.##", गोलाई HALF_UP256.335f-> "256.33"... (उदाहरण @ asterite के जवाब के लिए टिप्पणियों से आता है)।
बिगस्टोन्स

6
कृपया ध्यान रखें कि DecimalFormat आपके वर्तमान स्थानीय कॉन्फ़िगरेशन पर निर्भर करता है, आपको एक विभाजक के रूप में एक डॉट नहीं मिल सकता है। मैं नीचे Asterite के जवाब को व्यक्तिगत रूप से पसंद करता हूं
Gomino

1
यह भी ध्यान रखें कि आपको DecimalFormat के थ्रेड-सुरक्षित होने की उम्मीद नहीं करनी चाहिए। जावा डॉक्स के अनुसार : दशमलव प्रारूप आमतौर पर सिंक्रनाइज़ नहीं किए जाते हैं। प्रत्येक थ्रेड के लिए अलग प्रारूप इंस्टेंसेस बनाने की अनुशंसा की जाती है। यदि कई सूत्र समवर्ती रूप से एक प्रारूप का उपयोग करते हैं, तो इसे बाह्य रूप से सिंक्रनाइज़ किया जाना चाहिए।
सीजीके

1
मैं इसे कैसे

471

यह मानते हुए valueकि doubleआप कर सकते हैं:

(double)Math.round(value * 100000d) / 100000d

यह 5 अंकों की सटीकता के लिए है। शून्य की संख्या दशमलव की संख्या को दर्शाती है।


71
अद्यतन: मैंने अभी पुष्टि की है कि ऐसा करने से डेसीमलफार्मेट का उपयोग करने की तुलना में तेजी से होता है। मैंने 200 बार DecimalFormat और इस विधि का उपयोग करके लूप किया। DecimalFormat ने 200 लूप को पूरा करने के लिए 14ms लिया, इस विधि में 1ms से भी कम समय लगा। जैसा कि मुझे संदेह था, यह तेज है। यदि आप घड़ी के चक्र से भुगतान करते हैं, तो आपको यही करना चाहिए। मुझे आश्चर्य है कि क्रिस कूडमोर ने भी वही कहा जो उन्होंने ईमानदार होने के लिए कहा। ऑब्जेक्ट्स को आवंटित करना प्राथमिक प्रिमिटिव्स की तुलना में हमेशा अधिक महंगा होता है और स्थैतिक तरीकों (Math.round () का उपयोग करके दशमलवफ़ॉर्मैट.फॉर्मैट ()) के विपरीत होता है।
एंडी जे

99
यह तकनीक 90% से अधिक मामलों में विफल रहती है। -1।
user207421

25
वास्तव में, यह विफल रहता है Math.round(0.1 * Math.pow(10,20))/Math.pow(10,20) == 0.09223372036854775:।
रॉबर्ट टुपेलो-श्नाइक

54
इस विधि का उपयोग करते समय बहुत सावधान रहें (या फ़्लोटिंग पॉइंट के किसी भी गोलाई)। यह 265.335 के रूप में सरल रूप में कुछ के लिए विफल रहता है। 265.335 * 100 (2 अंकों की शुद्धता) का मध्यवर्ती परिणाम 26533.499999999996 है। इसका मतलब है कि यह 265.33 पर गोल हो जाता है। फ़्लोटिंग पॉइंट नंबरों से वास्तविक दशमलव संख्याओं में परिवर्तित होने पर बस अंतर्निहित समस्याएं हैं। ईजेपी का जवाब यहां देखें stackoverflow.com/a/12684082/144578
सेबेस्टियन वैन डेन ब्रोक

6
@ एसबेस्टियनवैनडेनब्रोक: वाह मुझे कभी नहीं पता था कि यह गलत उत्तर पाने में आसान था। हालांकि, यदि कोई गैर-सटीक संख्याओं के साथ काम कर रहा है, तो किसी को यह मान लेना चाहिए कि कोई भी मूल्य सटीक नहीं है265.335वास्तव में इसका मतलब है 265.335 += tolerance, जहां सहिष्णुता पिछले संचालन और इनपुट मूल्यों की सीमा पर निर्भर करती है। हम सही, सटीक मूल्य नहीं जानते हैं। किनारे के मूल्यों पर, या तो जवाब यकीनन सही है। अगर हमें सटीक होना चाहिए, तो हमें दोहरे काम नहीं करने चाहिए। failयहां डबल करने के लिए वापस परिवर्तित करने में नहीं है। इसकी ओपी सोच में वह आने वाले पर भरोसा कर सकता 265.335है कि वास्तव में ऐसा ही है।
टूलमेकरस्टेव

191
new BigDecimal(String.valueOf(double)).setScale(yourScale, BigDecimal.ROUND_HALF_UP);

आपको मिल जाएगा BigDecimal। स्ट्रिंग यह से बाहर निकलने के लिए, बस उस फोन BigDecimalकी toStringविधि, या toPlainStringएक सादे प्रारूप स्ट्रिंग के लिए जावा के लिए विधि 5 +।

नमूना कार्यक्रम:

package trials;
import java.math.BigDecimal;

public class Trials {

    public static void main(String[] args) {
        int yourScale = 10;
        System.out.println(BigDecimal.valueOf(0.42344534534553453453-0.42324534524553453453).setScale(yourScale, BigDecimal.ROUND_HALF_UP));
    }

38
यही मेरा पसंदीदा उपाय है। इससे भी छोटा: BigDecimal.valueOf (doubleVar) .setScale (yourScaleHere, BigDecimal.ROUND_HALF_UP); BigDecimal.valueOf (डबल वैल) वास्तव में हूड के तहत Double.toString ();) को बुलाता है
एटिएन

4
अच्छा लगा। कोनों को काटें और उपयोग न करें new BigDecimal(doubleVar)क्योंकि आप फ्लोटिंग पॉइंट्स के
चक्कर

8
@ ईडीडी, दिलचस्प बात यह है कि इस मामले में गोलाई मुद्दा तब होता है जब सेबेस्टियावैनडेनब्रोक में तारांकन के उत्तर के बारे में टिप्पणी की जाती है। double val = 265.335;, BigDecimal.valueOf(val).setScale(decimals, BigDecimal.ROUND_HALF_UP).toPlainString();=> 265.34, लेकिन (new BigDecimal(val)).setScale(decimals, BigDecimal.ROUND_HALF_UP).toPlainString();=> 265.33
टूलमेकरस्टेव

7
@ToolmakerSteve ऐसा इसलिए है क्योंकि डबल के साथ नए बिगडेसिमल का उपयोग करने से सीधे डबल वैल्यू का उपयोग होता है और बिगडेसिमल बनाने के लिए उपयोग करने का प्रयास करता है, जबकि बिगडिमल का उपयोग करते समय। ओवेल्यूऑफ या टोस्टिंग फॉर्म इसे रूपांतरण से पहले स्ट्रिंग (पहले एक अधिक सटीक प्रतिनिधित्व) तक पहुंचाता है। ।
MetroidFan2002

116

आप भी उपयोग कर सकते हैं

DecimalFormat df = new DecimalFormat("#.00000");
df.format(0.912385);

यह सुनिश्चित करने के लिए कि आपके पास 0 है।


25
मेरा मानना ​​है कि प्रश्न का एक लक्ष्य यह था कि "कोई भी पीछे नहीं चलना चाहिए "।
लंचबॉक्स

7
इस सवाल के लिए, ऑप्स शून्य नहीं चाहता था, लेकिन यह वही है जो मैं चाहता था। यदि आपके पास 3 दशमलव स्थानों के साथ संख्याओं की सूची है, तो आप चाहते हैं कि सभी के अंक समान हों, भले ही यह 0. है
टॉम किन्किड

आप निर्दिष्ट करना भूल गएRoundingMode.
इगोरगानापोलस्की

1
डिफ़ॉल्ट रूप से @IgorGanapolsky Decimal modeका उपयोग करता हैRoundingMode.HALF_EVEN.
EndermanAPM

87

जैसा कि कुछ अन्य ने नोट किया है, सही उत्तर DecimalFormatया तो उपयोग करना है या BigDecimal। फ़्लोटिंग-पॉइंट में दशमलव स्थान नहीं हैं, इसलिए आप पहली बार में उनमें से किसी विशेष संख्या को गोल / छोटा नहीं कर सकते हैं। आपको एक दशमलव मूलांक में काम करना होगा, और यही वह है जो दो वर्ग करते हैं।

मैं इस धागे में सभी उत्तरों और वास्तव में StackOverflow (और अन्य जगहों) पर एक काउंटर-उदाहरण के रूप में निम्नलिखित कोड पोस्ट कर रहा हूं जो कि विभाजन के बाद गुणन के बाद गुणा की सलाह देते हैं। यह इस तकनीक के पैरोकारों पर निर्भर है कि यह समझाने के लिए कि निम्न कोड 92% से अधिक मामलों में गलत उत्पादन क्यों करता है।

public class RoundingCounterExample
{

    static float roundOff(float x, int position)
    {
        float a = x;
        double temp = Math.pow(10.0, position);
        a *= temp;
        a = Math.round(a);
        return (a / (float)temp);
    }

    public static void main(String[] args)
    {
        float a = roundOff(0.0009434f,3);
        System.out.println("a="+a+" (a % .001)="+(a % 0.001));
        int count = 0, errors = 0;
        for (double x = 0.0; x < 1; x += 0.0001)
        {
            count++;
            double d = x;
            int scale = 2;
            double factor = Math.pow(10, scale);
            d = Math.round(d * factor) / factor;
            if ((d % 0.01) != 0.0)
            {
                System.out.println(d + " " + (d % 0.01));
                errors++;
            }
        }
        System.out.println(count + " trials " + errors + " errors");
    }
}

इस कार्यक्रम का आउटपुट:

10001 trials 9251 errors

संपादित करें: नीचे दिए गए कुछ टिप्पणियों को संबोधित करने के लिए मैं परीक्षण लूप के मापांक भाग का उपयोग करते हुए BigDecimalऔर new MathContext(16)मापांक ऑपरेशन के लिए निम्नानुसार करता हूं :

public static void main(String[] args)
{
    int count = 0, errors = 0;
    int scale = 2;
    double factor = Math.pow(10, scale);
    MathContext mc = new MathContext(16, RoundingMode.DOWN);
    for (double x = 0.0; x < 1; x += 0.0001)
    {
        count++;
        double d = x;
        d = Math.round(d * factor) / factor;
        BigDecimal bd = new BigDecimal(d, mc);
        bd = bd.remainder(new BigDecimal("0.01"), mc);
        if (bd.multiply(BigDecimal.valueOf(100)).remainder(BigDecimal.ONE, mc).compareTo(BigDecimal.ZERO) != 0)
        {
            System.out.println(d + " " + bd);
            errors++;
        }
    }
    System.out.println(count + " trials " + errors + " errors");
}

परिणाम:

10001 trials 4401 errors

8
चाल यह है कि आपकी सभी 9251 त्रुटियों में, मुद्रित परिणाम अभी भी सही है।
डिडियर एल

7
@DidierL यह मुझे आश्चर्य नहीं करता है। मुझे अपने पहले कंप्यूटिंग कोर्स के रूप में 'न्यूमेरिकल मेथड्स' करने का बहुत सौभाग्य प्राप्त हुआ और शुरू-शुरू में जो सही था उसे फ्लोटिंग-पॉइंट कर सकते हैं और नहीं कर सकते। अधिकांश प्रोग्रामर इसके बारे में बहुत अस्पष्ट हैं।
user207421

15
आप जो कुछ भी कर रहे हैं वह इस बात का खंडन कर रहा है कि फ्लोटिंग कई दशमलव मानों का प्रतिनिधित्व नहीं करता है, जो मुझे उम्मीद है कि हम सभी को समझेंगे। ऐसा नहीं है कि गोलाई समस्या का कारण बनती है। जैसा कि आप स्वीकार करते हैं, संख्या अभी भी उम्मीद के मुताबिक प्रिंट होती है।
पीटर लॉरी

8
आपका परीक्षण टूट गया है, राउंड () आउट करें और परीक्षण समय का 94% विफल रहता है। ideone.com/1y62CY प्रिंट 100 trials 94 errorsआपको एक परीक्षण से शुरू करना चाहिए जो पास हो जाता है, और दिखाता है कि राउंडिंग शुरू करने से परीक्षण टूट जाता है।
पीटर लॉरी

6
प्रतिनियुक्ति, यहाँ मना। doubleकोई त्रुटि ideone.com/BVCHh3
पीटर लॉरी

83

मान लो तुम्हारे पास है

double d = 9232.129394d;

आप उपयोग कर सकते हैं BigDecimal

BigDecimal bd = new BigDecimal(d).setScale(2, RoundingMode.HALF_EVEN);
d = bd.doubleValue();

या BigDecimal के बिना

d = Math.round(d*100)/100.0d;

दोनों समाधानों के साथ d == 9232.13


2
मुझे लगता है कि यह जावा 1.5 उपयोगकर्ताओं (और नीचे) के लिए सबसे अच्छा समाधान है। एक टिप्पणी थियो, HALF_EVEN राउंडिंग मोड का उपयोग न करें क्योंकि इसमें विषम और सम संख्या (2.5 राउंड टू 2 जबकि 5.5 राउंड टू 6, उदाहरण के लिए) के लिए अलग व्यवहार है, जब तक कि यह वही नहीं है जो आप चाहते हैं।
इडेडेंटे जूल

4
पहला समाधान सही है: दूसरा काम नहीं करता है। प्रमाण के लिए यहाँ देखें ।
user207421

1
@ ईजेपी: यहां तक ​​कि पहला समाधान RoundingMode.HALF_UPभी गलत है। इसके साथ प्रयास करें 1.505। सही तरीका उपयोग करना है BigDecimal.valueOf(d)
मथायस ब्रौन

माथियास ब्रौन, समाधान ठीक है, इसलिए 31 अप .. 1.505 दशमलव को 1.50499998 के रूप में फ़्लोटिंग पॉइंट डबल में संग्रहीत किया जाता है। यदि आप 1.505 लेना चाहते हैं और डबल से दशमलव में परिवर्तित करना चाहते हैं, तो आपको इसे पहले डबल-रेस्ट्रिंग (x) में बदलना होगा। फिर इसे एक BigDecimal () में डालें, लेकिन यह बहुत धीमा है, और पहले स्थान पर गति के लिए डबल का उपयोग करने के उद्देश्य को पराजित करता है।
१३:१४ पर

1
BigDecimal के साथ 100k का लूप दौड़ा (225 ms लिया) और Math.round (2 ms) तरीके से और यहां टाइमिंग है ... Time Taken: 225 milli सेकंड का उपयोग कर कन्वर्ट करने के लिए: 9232.13 Time Taken: 2 मिलि सेकंड में कनवर्ट करें : 9232.13 techiesinfo.com
user1114134

59

आप DecimalFormat वर्ग का उपयोग कर सकते हैं।

double d = 3.76628729;

DecimalFormat newFormat = new DecimalFormat("#.##");
double twoDecimal =  Double.valueOf(newFormat.format(d));

किसी भी कारण से क्यों Double.valueOf()चुना गया Double.parseDouble()? valueOf()विधि एक रिटर्न Doubleवस्तु है, जबकि parseDouble()एक वापस आ जाएगी doubleआदिम। जिस तरह से वर्तमान कोड लिखा गया है, आप उस ऑटो को भी प्री-अनबॉक्सिंग के लिए लागू करते हैं, ताकि यह उस आदिम को कास्ट किया जा सके जो आपके twoDoubleवैरिएबल को उम्मीद है, एक अतिरिक्त बायोटेक ऑपरेशन। मैं parseDouble()इसके बजाय उपयोग करने के लिए उत्तर बदलूंगा।
इकोब्रोडी

Double.parseDouble()Stringइनपुट चाहिए
राइड

38

रियल के जावा हाउ-टू इस समाधान को पोस्ट करता है, जो जावा 1.6 से पहले संस्करणों के लिए भी अनुकूल है।

BigDecimal bd = new BigDecimal(Double.toString(d));
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();

33
double myNum = .912385;
int precision = 10000; //keep 4 digits
myNum= Math.floor(myNum * precision +.5)/precision;

2
हाँ यह वही है जो धनात्मक संख्याओं के लिए math.round करता है, लेकिन क्या आपने इसे नकारात्मक संख्याओं के साथ आज़माया है? लोग नेगेटिव नंबर्स के केस को कवर करने के लिए दूसरे सॉल्यूशंस में math.round का इस्तेमाल कर रहे हैं।
१३:१४

नोट:Math.floor(x + 0.5)Math.round(x)
पीटर लॉरी

30

@ विल्कुल: गोलाई के लिए दशमलव प्रारूप उत्कृष्ट है:

आप भी उपयोग कर सकते हैं

DecimalFormat df = new DecimalFormat("#.00000");
df.format(0.912385);

यह सुनिश्चित करने के लिए कि आपके पास 0 है।

मैं जोड़ूंगा कि यह विधि एक वास्तविक संख्यात्मक, गोल तंत्र प्रदान करने में बहुत अच्छी है - न केवल नेत्रहीन, बल्कि प्रसंस्करण के दौरान भी।

Hypothetical: आपको एक GUI प्रोग्राम में एक गोलाई तंत्र को लागू करना होगा। परिणाम आउटपुट की सटीकता / सटीकता को बदलने के लिए बस कैरेट प्रारूप (यानी कोष्ठक के भीतर) बदलें। इसलिए कि:

DecimalFormat df = new DecimalFormat("#0.######");
df.format(0.912385);

आउटपुट के रूप में लौटेगा: 0.912385

DecimalFormat df = new DecimalFormat("#0.#####");
df.format(0.912385);

आउटपुट के रूप में लौटेगा: 0.91239

DecimalFormat df = new DecimalFormat("#0.####");
df.format(0.912385);

आउटपुट के रूप में लौटेगा: 0.9124

[संपादित करें: यदि कैरेट प्रारूप भी ऐसा है ("# 0। ############")) और आप एक दशमलव दर्ज करते हैं, जैसे 3.1415926, तर्क के लिए, DecimalFormat कोई कचरा उत्पन्न नहीं करता है ( जैसे जीरो को पीछे करना) और वापस आएगा: 3.1415926.. अगर आप इस तरह से झुके हैं। दी, यह कुछ देवों की पसंद के लिए एक छोटी सी क्रिया है - लेकिन हे, इसे प्रसंस्करण के दौरान कम स्मृति पदचिह्न मिला है और इसे लागू करना बहुत आसान है।]

तो अनिवार्य रूप से, डेसीमलफॉर्म की सुंदरता यह है कि यह एक साथ स्ट्रिंग उपस्थिति को संभालती है - साथ ही साथ सटीक सेटिंग का स्तर भी। एर्गो: आपको एक कोड कार्यान्वयन की कीमत के लिए दो लाभ मिलते हैं। ;)


2
क्या तुम सच में दशमलव संख्या गणना के लिए (और न केवल उत्पादन के लिए), चाहते हैं एक द्विआधारी आधारित चल बिन्दु प्रारूप का उपयोग नहीं करते की तरह double। BigDecimal या किसी अन्य दशमलव-आधारित प्रारूप का उपयोग करें।
19lo में पाओलो एबरमन जू

20

यदि आप स्ट्रिंग के रूप में परिणाम चाहते हैं, तो आप इसका उपयोग कर सकते हैं इसका एक सारांश है:

  1. DecimalFormat # setRoundingMode () :

    DecimalFormat df = new DecimalFormat("#.#####");
    df.setRoundingMode(RoundingMode.HALF_UP);
    String str1 = df.format(0.912385)); // 0.91239
  2. BigDecimal # setScale ()

    String str2 = new BigDecimal(0.912385)
        .setScale(5, BigDecimal.ROUND_HALF_UP)
        .toString();

यहां एक सुझाव दिया गया है कि यदि आप doubleपरिणाम के रूप में चाहते हैं तो आप किन पुस्तकालयों का उपयोग कर सकते हैं । मैं इसे स्ट्रिंग रूपांतरण के लिए अनुशंसित नहीं करूंगा, हालांकि, जैसा कि आप जो चाहते हैं उसका दोहरा प्रतिनिधित्व नहीं कर सकते (उदाहरण के लिए यहां देखें ):

  1. अपाचे कॉमन्स मठ से परिशुद्धता

    double rounded = Precision.round(0.912385, 5, BigDecimal.ROUND_HALF_UP);
  2. बछेड़ा से कार्य

    double rounded = Functions.round(0.00001).apply(0.912385)
  3. वीका से बर्तन

    double rounded = Utils.roundDouble(0.912385, 5)

18

आप निम्नलिखित उपयोगिता विधि का उपयोग कर सकते हैं-

public static double round(double valueToRound, int numberOfDecimalPlaces)
{
    double multipicationFactor = Math.pow(10, numberOfDecimalPlaces);
    double interestedInZeroDPs = valueToRound * multipicationFactor;
    return Math.round(interestedInZeroDPs) / multipicationFactor;
}

@mariolpantunes: यह विफल हो जाएगा। यह कोशिश करें: round(1.005,2);याround(0.50594724957626620092, 20);
मथायस ब्रौन

यह काम करता हैं। लेकिन uninformatively फ्लोट और डबल्स सन्निकटन हैं। आइए हम आपके पहले उदाहरण पर विचार करें। यदि आप Math.round से पहले interestInZeroDPs का आउटपुट प्रिंट करते हैं तो यह 100.49999999999999 पर प्रिंट होगा। आप इस तरह के Math.round राउंड के रूप में इसे 100 के रूप में सटीक खो देते हैं। प्रकृति या फ़्लोट्स और डबल्स के कारण बॉर्डरलाइन केस होते हैं जब यह ठीक से काम नहीं करता है (अधिक जानकारी यहाँ en.wikipedia.org/wiki/Floating_point#Accitacy_problems )
mariolpantunes

डबल एक उपवास है! दशमलव धीमा है। कंप्यूटर दशमलव संकेतन में अपनी सोच को संसाधित करने से परेशान नहीं होते हैं। आपको फ़्लोटिंग पॉइंट डबल फास्ट रखने के लिए कुछ दशमलव परिशुद्धता छोड़नी होगी।
१३'१४ को सुबह

@ प्रश्न प्रश्न सटीकता के बारे में है, गति के बारे में नहीं।
user207421 10



7

इसे आज़माएँ: org.apache.commons.math3.util.Preaches.round (डबल एक्स, इंट स्केल)

देखें: http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/Preults.html

Apache Commons Mathematics लाइब्रेरी का मुखपृष्ठ है: http://commons.apache.org/proper/commons-math/index.html

इस विधि का आंतरिक गुणन है:

public static double round(double x, int scale) {
    return round(x, scale, BigDecimal.ROUND_HALF_UP);
}

public static double round(double x, int scale, int roundingMethod) {
    try {
        return (new BigDecimal
               (Double.toString(x))
               .setScale(scale, roundingMethod))
               .doubleValue();
    } catch (NumberFormatException ex) {
        if (Double.isInfinite(x)) {
            return x;
        } else {
            return Double.NaN;
        }
    }
}

7

चूंकि मुझे इस विषय पर कोई पूर्ण उत्तर नहीं मिला है, इसलिए मैंने एक वर्ग को एक साथ रखा है जिसे इसके लिए समर्थन के साथ ठीक से संभालना चाहिए:

  • स्वरूपण : दशमलव स्थानों की एक निश्चित संख्या के साथ आसानी से डबल टू स्ट्रिंग
  • पार्सिंग : फॉर्मेट किए गए मान को दोगुना करने के लिए पार्स करें
  • लोकेल : डिफ़ॉल्ट लोकेल का उपयोग करके फॉर्मेट और पार्स करें
  • घातीय संकेतन : एक निश्चित सीमा के बाद घातीय संकेतन का उपयोग करना शुरू करें

उपयोग बहुत सरल है :

(इस उदाहरण के लिए मैं एक कस्टम लोकेल का उपयोग कर रहा हूँ)

public static final int DECIMAL_PLACES = 2;

NumberFormatter formatter = new NumberFormatter(DECIMAL_PLACES);

String value = formatter.format(9.319); // "9,32"
String value2 = formatter.format(0.0000005); // "5,00E-7"
String value3 = formatter.format(1324134123); // "1,32E9"

double parsedValue1 = formatter.parse("0,4E-2", 0); // 0.004
double parsedValue2 = formatter.parse("0,002", 0); // 0.002
double parsedValue3 = formatter.parse("3423,12345", 0); // 3423.12345

यहाँ वर्ग है :

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.util.Locale;

public class NumberFormatter {

    private static final String SYMBOL_INFINITE           = "\u221e";
    private static final char   SYMBOL_MINUS              = '-';
    private static final char   SYMBOL_ZERO               = '0';
    private static final int    DECIMAL_LEADING_GROUPS    = 10;
    private static final int    EXPONENTIAL_INT_THRESHOLD = 1000000000; // After this value switch to exponential notation
    private static final double EXPONENTIAL_DEC_THRESHOLD = 0.0001; // Below this value switch to exponential notation

    private DecimalFormat decimalFormat;
    private DecimalFormat decimalFormatLong;
    private DecimalFormat exponentialFormat;

    private char groupSeparator;

    public NumberFormatter(int decimalPlaces) {
        configureDecimalPlaces(decimalPlaces);
    }

    public void configureDecimalPlaces(int decimalPlaces) {
        if (decimalPlaces <= 0) {
            throw new IllegalArgumentException("Invalid decimal places");
        }

        DecimalFormatSymbols separators = new DecimalFormatSymbols(Locale.getDefault());
        separators.setMinusSign(SYMBOL_MINUS);
        separators.setZeroDigit(SYMBOL_ZERO);

        groupSeparator = separators.getGroupingSeparator();

        StringBuilder decimal = new StringBuilder();
        StringBuilder exponential = new StringBuilder("0.");

        for (int i = 0; i < DECIMAL_LEADING_GROUPS; i++) {
            decimal.append("###").append(i == DECIMAL_LEADING_GROUPS - 1 ? "." : ",");
        }

        for (int i = 0; i < decimalPlaces; i++) {
            decimal.append("#");
            exponential.append("0");
        }

        exponential.append("E0");

        decimalFormat = new DecimalFormat(decimal.toString(), separators);
        decimalFormatLong = new DecimalFormat(decimal.append("####").toString(), separators);
        exponentialFormat = new DecimalFormat(exponential.toString(), separators);

        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
        decimalFormatLong.setRoundingMode(RoundingMode.HALF_UP);
        exponentialFormat.setRoundingMode(RoundingMode.HALF_UP);
    }

    public String format(double value) {
        String result;
        if (Double.isNaN(value)) {
            result = "";
        } else if (Double.isInfinite(value)) {
            result = String.valueOf(SYMBOL_INFINITE);
        } else {
            double absValue = Math.abs(value);
            if (absValue >= 1) {
                if (absValue >= EXPONENTIAL_INT_THRESHOLD) {
                    value = Math.floor(value);
                    result = exponentialFormat.format(value);
                } else {
                    result = decimalFormat.format(value);
                }
            } else if (absValue < 1 && absValue > 0) {
                if (absValue >= EXPONENTIAL_DEC_THRESHOLD) {
                    result = decimalFormat.format(value);
                    if (result.equalsIgnoreCase("0")) {
                        result = decimalFormatLong.format(value);
                    }
                } else {
                    result = exponentialFormat.format(value);
                }
            } else {
                result = "0";
            }
        }
        return result;
    }

    public String formatWithoutGroupSeparators(double value) {
        return removeGroupSeparators(format(value));
    }

    public double parse(String value, double defValue) {
        try {
            return decimalFormat.parse(value).doubleValue();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return defValue;
    }

    private String removeGroupSeparators(String number) {
        return number.replace(String.valueOf(groupSeparator), "");
    }

}

7

यदि आप वास्तव में गणना के लिए दशमलव संख्या चाहते हैं (और न केवल आउटपुट के लिए), तो बाइनरी-आधारित फ़्लोटिंग बिंदु प्रारूप जैसे दोहरे का उपयोग न करें।

Use BigDecimal or any other decimal-based format.

मैं गणना के लिए BigDecimal का उपयोग करता हूं, लेकिन ध्यान रखें कि यह उन संख्याओं के आकार पर निर्भर करता है जिनसे आप निपट रहे हैं। मेरे अधिकांश कार्यान्वयनों में, मुझे लगता है कि डबल या पूर्णांक से लेकर लॉन्ग तक पार्सिंग बहुत बड़ी संख्या में गणना के लिए पर्याप्त है।

वास्तव में, मैंने हाल ही में एक GUI में सटीक प्रतिनिधित्व प्राप्त करने के लिए पार्स-टू-लॉन्ग (जैसा कि हेक्स परिणाम के विपरीत) का उपयोग किया है, संख्या में ################ के रूप में बड़ा है। ############## वर्ण (उदाहरण के रूप में)।


6

इसे प्राप्त करने के लिए हम इस फ़ॉर्मेटर का उपयोग कर सकते हैं:

 DecimalFormat df = new DecimalFormat("#.00");
 String resultado = df.format(valor)

या:

DecimalFormat df = new DecimalFormat("0.00"); :

हमेशा दो दशमलव प्राप्त करने के लिए इस विधि का उपयोग करें:

   private static String getTwoDecimals(double value){
      DecimalFormat df = new DecimalFormat("0.00"); 
      return df.format(value);
    }

इस मूल्यों को परिभाषित करना:

91.32
5.22
11.5
1.2
2.6

विधि का उपयोग करके हम यह परिणाम प्राप्त कर सकते हैं:

91.32
5.22
11.50
1.20
2.60

ऑनलाइन डेमो करें।


5

बस मामले में किसी को अभी भी इस के साथ मदद की जरूरत है। यह समाधान मेरे लिए पूरी तरह से काम करता है।

private String withNoTrailingZeros(final double value, final int nrOfDecimals) {
return new BigDecimal(String.valueOf(value)).setScale(nrOfDecimals,  BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString();

}

String वांछित आउटपुट के साथ देता है ।


कृपया कमेंट में अपना कारण बताएं, अन्यथा हम इसे डराना कहते हैं।
अशर। एम। ओ।

4

मैं DecimalFormat--- या वैकल्पिक रूप से उपयोग करने के लिए चुने गए उत्तर से सहमत हूं BigDecimal

पहले अद्यतन नीचे पढ़ें !

हालाँकि यदि आप दोहरे मूल्य को गोल करना चाहते हैं और doubleमूल्य परिणाम प्राप्त करना चाहते हैं , तो आप org.apache.commons.math3.util.Precision.round(..)ऊपर बताए अनुसार उपयोग कर सकते हैं । कार्यान्वयन का उपयोग करता है BigDecimal, धीमा है और कचरा बनाता है।

DoubleRounderदशमलव 4j लाइब्रेरी में उपयोगिता द्वारा एक समान लेकिन तेज और कचरा-मुक्त विधि प्रदान की जाती है :

 double a = DoubleRounder.round(2.0/3.0, 3);
 double b = DoubleRounder.round(2.0/3.0, 3, RoundingMode.DOWN);
 double c = DoubleRounder.round(1000.0d, 17);
 double d = DoubleRounder.round(90080070060.1d, 9);
 System.out.println(a);
 System.out.println(b);
 System.out.println(c);
 System.out.println(d);

उत्पादन करेगा

 0.667
 0.666
 1000.0
 9.00800700601E10

Https://github.com/tools4j/decimal4j/wiki/DoubleRounder-Utility देखें

अस्वीकरण: मैं दशमलव 4j परियोजना में शामिल हूं।

अपडेट: जैसा कि @iaforek ने बताया कि DoubleRounder कभी-कभी काउंटरिंटुइक्टिव परिणाम देता है। कारण यह है कि यह गणितीय रूप से सही गोलाई का प्रदर्शन करता है। उदाहरण के लिए DoubleRounder.round(256.025d, 2), 256.02 को गोल किया जाएगा क्योंकि 256.025d के रूप में दर्शाया गया दोहरा मूल्य तर्कसंगत मान 256.025 से कुछ छोटा है और इसलिए इसे नीचे राउंड किया जाएगा।

टिप्पणियाँ:

  • यह व्यवहार BigDecimal(double)कंस्ट्रक्टर के समान है (लेकिन ऐसा नहीं है valueOf(double)जो स्ट्रिंग कंस्ट्रक्टर का उपयोग करता है)।
  • समस्या को पहले उच्च परिशुद्धता के लिए दोहराए जाने वाले कदम के साथ दरकिनार किया जा सकता है, लेकिन यह जटिल है और मैं यहां विवरण में नहीं जा रहा हूं

उन कारणों और इस पोस्ट में ऊपर बताई गई सभी बातों के लिए मैं DoubleRounder का उपयोग करने की अनुशंसा नहीं कर सकता


क्या आपके पास यह दर्शाने के लिए मैट्रिक्स है कि आपका समाधान अन्य लोगों की तुलना में कितना कुशल है?
.यूरोस्क

मैंने अन्य समाधानों के साथ इसकी तुलना नहीं की है, लेकिन स्रोत कोड में एक जेएमएच बेंचमार्क उपलब्ध है: github.com/tools4j/decimal4j/blob/master/src/jmh/java/org/ ... ने VM पर बेंचमार्क नहीं चलाया परिणाम सीएसवी फ़ाइल के रूप में यहां उपलब्ध हैं: github.com/tools4j/decimal4j/wiki/Performance
marco

1
DoubleRounder निम्नलिखित मामलों के लिए विफल रहता है: DoubleRounder.round (256.025d, 2) - अपेक्षित: 256.03, वास्तविक: 256.02 या DoubleRounder.round (260.775d, 2) के लिए - अपेक्षित: 260.78, वास्तविक: 260.77।
iaforek

@iaforek: यह सही है, क्योंकि DoubleRounder गणितीय रूप से सही राउंडिंग करता है। हालाँकि मैं मानता हूँ कि यह कुछ हद तक उल्टा है और इसलिए मैं अपने उत्तर को तदनुसार अद्यतन करूँगा।
मार्को

3

नीचे दिया गया कोड स्निपेट दिखाता है कि n अंक कैसे प्रदर्शित करें। चाल n शून्य के बाद चर पीपी 1 सेट करने के लिए है। नीचे दिए गए उदाहरण में, चर पीपीपी मान में 5 शून्य हैं, इसलिए 5 अंक प्रदर्शित किए जाएंगे।

double pp = 10000;

double myVal = 22.268699999999967;
String needVal = "22.2687";

double i = (5.0/pp);

String format = "%10.4f";
String getVal = String.format(format,(Math.round((myVal +i)*pp)/pp)-i).trim();

3

यदि आप इसे DecimalFormatबदलने के doubleलिए उपयोग कर रहे हैं String, तो यह बहुत सीधा है:

DecimalFormat formatter = new DecimalFormat("0.0##");
formatter.setRoundingMode(RoundingMode.HALF_UP);

double num = 1.234567;
return formatter.format(num);

RoundingModeआपके द्वारा आवश्यक व्यवहार के आधार पर, चयन करने के लिए कई enum मान हैं।


3

मैं यहाँ आया था कि मैं एक सरल उत्तर चाहता हूँ कि कैसे एक संख्या को गोल किया जाए। यह प्रदान करने के लिए एक पूरक उत्तर है।

जावा में नंबर कैसे राउंड करें

सबसे आम मामला उपयोग करना है Math.round()

Math.round(3.7) // 4

संख्याओं को निकटतम पूर्ण संख्या में गोल किया जाता है। एक .5मान ऊपर दिया गया है। यदि आपको उससे अलग दौर व्यवहार की आवश्यकता है, तो आप अन्य गणित कार्यों में से एक का उपयोग कर सकते हैं । नीचे तुलना देखें।

गोल

जैसा कि ऊपर कहा गया है, यह निकटतम पूर्ण संख्या में गोल है। .5दशमलव गोल। यह विधि एक लौटाती है int

Math.round(3.0); // 3
Math.round(3.1); // 3
Math.round(3.5); // 4
Math.round(3.9); // 4

Math.round(-3.0); // -3
Math.round(-3.1); // -3
Math.round(-3.5); // -3 *** careful here ***
Math.round(-3.9); // -4

प्लस्तर लगाना

किसी भी दशमलव मान को अगले पूर्णांक तक गोल किया जाता है। यह Ceil ing पर जाता है । यह विधि ए रिटर्न double

Math.ceil(3.0); // 3.0
Math.ceil(3.1); // 4.0
Math.ceil(3.5); // 4.0
Math.ceil(3.9); // 4.0

Math.ceil(-3.0); // -3.0
Math.ceil(-3.1); // -3.0
Math.ceil(-3.5); // -3.0
Math.ceil(-3.9); // -3.0

मंज़िल

किसी भी दशमलव मान को अगले पूर्णांक तक गोल किया जाता है। यह विधि ए रिटर्न double

Math.floor(3.0); // 3.0
Math.floor(3.1); // 3.0
Math.floor(3.5); // 3.0
Math.floor(3.9); // 3.0

Math.floor(-3.0); // -3.0
Math.floor(-3.1); // -4.0
Math.floor(-3.5); // -4.0
Math.floor(-3.9); // -4.0

प्रिंट करें

यह उस दशमलव मान में गोल के समान है जो निकटतम पूर्णांक में गोल है। हालाँकि, इसके विपरीत round, .5मान पूर्णांक के लिए भी गोल है। यह विधि ए रिटर्न double

Math.rint(3.0); // 3.0
Math.rint(3.1); // 3.0
Math.rint(3.5); // 4.0 ***
Math.rint(3.9); // 4.0
Math.rint(4.5); // 4.0 ***
Math.rint(5.5); // 6.0 ***

Math.rint(-3.0); // -3.0
Math.rint(-3.1); // -3.0
Math.rint(-3.5); // -4.0 ***
Math.rint(-3.9); // -4.0
Math.rint(-4.5); // -4.0 ***
Math.rint(-5.5); // -6.0 ***

1
आप केवल 0 दशमलव तक गोलाई के विशेष मामले को हल कर रहे हैं। मूल प्रश्न अधिक सामान्य है।
lukas84

3

यदि आप एक ऐसी तकनीक का उपयोग कर रहे हैं जिसमें न्यूनतम JDK हो। यहां बिना किसी जावा लिब के एक तरीका है:

double scale = 100000;    
double myVal = 0.912385;
double rounded = (int)((myVal * scale) + 0.5d) / scale;

यह उन मामलों में विफल होगा जहां myVal 1 से कम नहीं है और स्केल मान से परे दशमलव के बाद शून्य के साथ है। मान लीजिए कि आपके पास myVal = 9.00000000912385 है; उपरोक्त वापस 9.0 होगा। मुझे लगता है कि हमें एक समाधान प्रदान करना चाहिए जो myVal के सभी मामलों में काम करता है। विशेष रूप से आपके द्वारा बताए गए मूल्य के लिए नहीं।
तवलेंदो

@ user102859 आपके उदाहरण में, 9.0 सही परिणाम है। मुझे समझ नहीं आ रहा है कि यह कैसे विफल होगा।
क्रेगो

2

DecimalFormat आउटपुट का सबसे अच्छा तरीका है, लेकिन मैं इसे पसंद नहीं करता। मैं हमेशा यह सब करता हूं, क्योंकि यह दोहरा मूल्य देता है। इसलिए मैं इसे सिर्फ आउटपुट से ज्यादा इस्तेमाल कर सकता हूं।

Math.round(selfEvaluate*100000d.0)/100000d.0;

या

Math.round(selfEvaluate*100000d.0)*0.00000d1;

यदि आपको बड़े दशमलव स्थानों के मूल्य की आवश्यकता है, तो आप इसके बजाय BigDecimal का उपयोग कर सकते हैं। वैसे भी .0महत्वपूर्ण है। इसके बिना 0.33333d5 रिटर्निंग 0.33333 और केवल 9 अंक की अनुमति है। .00.30000 वापसी 0.30000000000000004 के साथ समस्याओं के बिना दूसरा कार्य है ।



1

इसलिए अधिकांश उत्तरों को पढ़ने के बाद, मैंने महसूस किया कि उनमें से अधिकांश सटीक नहीं होंगे, वास्तव में उपयोग BigDecimalकरना सबसे अच्छा विकल्प लगता है, लेकिन यदि आप यह नहीं समझते हैं कि कैसे RoundingModeकाम करता है, तो आप अपरिहार्य रूप से सटीक खो देंगे। मुझे यह पता लगा जब एक परियोजना में बड़ी संख्याओं के साथ काम करना और सोचा कि इससे दूसरों को राउंडिंग नंबर की परेशानी हो सकती है। उदाहरण के लिए।

BigDecimal bd = new BigDecimal("1363.2749");
bd = bd.setScale(2, RoundingMode.HALF_UP);
System.out.println(bd.doubleValue());

आप 1363.28एक आउटपुट के रूप में प्राप्त करने की उम्मीद करेंगे, लेकिन आप के साथ समाप्त हो जाएगा 1363.27, जो कि उम्मीद नहीं है, अगर आपको नहीं पता कि यह क्या RoundingModeकर रहा है। तो Oracle डॉक्स में देख रहे हैं , आप के लिए निम्नलिखित विवरण मिलेगा RoundingMode.HALF_UP

राउंडिंग मोड "निकटतम पड़ोसी" की ओर गोल करने के लिए जब तक कि दोनों पड़ोसी समान नहीं होते हैं, जिस स्थिति में गोल होता है।

इसलिए यह जानकर, हमें एहसास हुआ कि हमें एक सटीक गोलाई नहीं मिलेगी, जब तक कि हम निकटतम पड़ोसी की ओर नहीं बढ़ना चाहते । इसलिए, एक पर्याप्त दौर पूरा करने के लिए, हमें n-1दशमलव से वांछित दशमलव अंकों की ओर लूप करने की आवश्यकता होगी । उदाहरण के लिए।

private double round(double value, int places) throws IllegalArgumentException {

    if (places < 0) throw new IllegalArgumentException();

    // Cast the number to a String and then separate the decimals.
    String stringValue = Double.toString(value);
    String decimals = stringValue.split("\\.")[1];

    // Round all the way to the desired number.
    BigDecimal bd = new BigDecimal(stringValue);
    for (int i = decimals.length()-1; i >= places; i--) {
        bd = bd.setScale(i, RoundingMode.HALF_UP);
    }

    return bd.doubleValue();
}

यह हमें अपेक्षित आउटपुट देगा, जो होगा 1363.28


0

जहाँ dp = दशमलव स्थान आप चाहते हैं, और मान एक डबल है।

    double p = Math.pow(10d, dp);

    double result = Math.round(value * p)/p;

1
का उत्पादन 1.0के लिए value = 1.005और dp = 2। इसकी जगह इसका इस्तेमाल करें
मथायस ब्रौन

यह ठीक है मैट, आपका उदाहरण मान्य नहीं है। क्योंकि 1.005 को वैसे भी फ्लोटिंग पॉइंट डबल में प्रस्तुत नहीं किया जा सकता है। इसे वास्तव में 1.005 से ऊपर या नीचे संग्रहीत करना पड़ता है अर्थात जब आप संकलित करते हैं तो यह दोगुना संग्रहीत होता है: 1.0049998 (यह आपके संकलित कोड में दशमलव के रूप में संग्रहीत नहीं है जैसा कि आप पाठकों को विश्वास होगा) उद्देश्य सही है, वह फ़्लोटिंग बिंदु के रूप में मान संग्रहीत कर रहा है डबल, जहां आपके जैसे फ्रिंज मामले वैसे भी महत्वहीन हैं। यदि यह था, तो आप 3dp का उपयोग कर रहे होंगे, फिर इसे दशमलव में परिवर्तित करेंगे, फिर दशमलव राउंड फंक्शन कर रहे हैं, ठीक उसी तरह जैसे आपने पोस्ट किया था।
१३:१४

1
@ मैमिश मैं नहीं देखता कि माथियास के पाठकों का मानना ​​है कि 'कोई भी चीज ऐसी हो जो मान को दशमलव के रूप में संकलित करे। दूसरे लोगों के मुंह में शब्द न डालें।
user207421

0

ध्यान रखें कि String.format () और DecimalFormat डिफ़ॉल्ट लोकेल का उपयोग करके स्ट्रिंग का उत्पादन करते हैं। इसलिए वे पूर्णांक और दशमलव भागों के बीच विभाजक के रूप में डॉट या अल्पविराम के साथ स्वरूपित संख्या लिख ​​सकते हैं। यह सुनिश्चित करने के लिए कि गोल स्ट्रिंग उस प्रारूप में है जिसे आप java.text.NumberFormat का उपयोग करना चाहते हैं:

  Locale locale = Locale.ENGLISH;
  NumberFormat nf = NumberFormat.getNumberInstance(locale);
  // for trailing zeros:
  nf.setMinimumFractionDigits(2);
  // round to 2 digits:
  nf.setMaximumFractionDigits(2);

  System.out.println(nf.format(.99));
  System.out.println(nf.format(123.567));
  System.out.println(nf.format(123.0));

अंग्रेजी लोकेल में प्रिंट करेगा (आपके लोकेशन का कोई फर्क नहीं पड़ता): 0.99 123.57 123.00

उदाहरण फरेंदा से लिया गया है - डबल को सही ढंग से स्ट्रिंग में कैसे परिवर्तित किया जाए


0

सामान्य तौर पर, गोलाई स्केलिंग द्वारा की जाती है: round(num / p) * p

/**
 * MidpointRounding away from zero ('arithmetic' rounding)
 * Uses a half-epsilon for correction. (This offsets IEEE-754
 * half-to-even rounding that was applied at the edge cases).
 */
double RoundCorrect(double num, int precision) {
    double c = 0.5 * EPSILON * num;
//  double p = Math.pow(10, precision); //slow
    double p = 1; while (precision--> 0) p *= 10;
    if (num < 0)
        p *= -1;
    return Math.round((num + c) * p) / p;
}

// testing edge cases
RoundCorrect(1.005, 2);   // 1.01 correct
RoundCorrect(2.175, 2);   // 2.18 correct
RoundCorrect(5.015, 2);   // 5.02 correct

RoundCorrect(-1.005, 2);  // -1.01 correct
RoundCorrect(-2.175, 2);  // -2.18 correct
RoundCorrect(-5.015, 2);  // -5.02 correct
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.