জাভাতে দশমিক স্থানে কোনও সংখ্যাকে কীভাবে গোল করবেন


1258

আমি যা চাই তা হল একটি ডাবলকে একটি স্ট্রিংয়ে রূপান্তর করা যা অর্ধ-আপ পদ্ধতিটি ব্যবহার করে বৃত্তাকার হয় - অর্থাত্ যদি দশমিককে বৃত্তাকার করতে হয় তবে এটি সর্বদা পরবর্তী সংখ্যা পর্যন্ত গোল হয়। বেশিরভাগ পরিস্থিতিতে বেশিরভাগ লোকেরা প্রত্যাশা করে এটি হ'ল মানক পদ্ধতি।

আমি উল্লেখ করতে চাই যে কেবলমাত্র উল্লেখযোগ্য অঙ্কগুলি প্রদর্শিত হবে - অর্থাত্ কোনও পিছনে শূন্য হওয়া উচিত নয়।

আমি জানি এটি করার একটি পদ্ধতি হল পদ্ধতিটি ব্যবহার করা 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

তবে আপনি দেখতে পাচ্ছেন এটি অর্ধ-সম-বৃত্তাকার ব্যবহার করে। আগের অঙ্কটি সমান হলে এটি গোল হয়ে যাবে round আমি যা চাই তা হ'ল:

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

সম্পাদনা : মূল উত্তরটি দ্বিগুণ মানগুলির যথার্থতাকে সম্বোধন করে না। এটি যদি ঠিক হয় তবে আপনি যদি এটির উপরে বা নিচে গোল হয়ে যান তবে এটি খুব বেশি যত্নশীল না হন। তবে আপনি যদি সঠিক রাউন্ডিং চান, তবে আপনাকে মানগুলির প্রত্যাশিত নির্ভুলতা গ্রহণ করা উচিত। ভাসমান পয়েন্টের মানগুলির অভ্যন্তরীণভাবে বাইনারি উপস্থাপনা থাকে। এর অর্থ হ'ল ২.77 a৩৫ এর মতো মানটির অভ্যন্তরীণভাবে প্রকৃত মান নেই value এটি কিছুটা বড় বা কিছুটা ছোট হতে পারে। যদি অভ্যন্তরীণ মানটি সামান্য ছোট হয় তবে এটি 2.7740 পর্যন্ত গোল হবে না। এই পরিস্থিতির প্রতিকারের জন্য, আপনি যে মানগুলির সাথে কাজ করছেন তার যথার্থতা সম্পর্কে আপনাকে সচেতন হওয়া উচিত, এবং গোলটি করার আগে সেই মানটি যোগ বা বিয়োগ করতে হবে। উদাহরণস্বরূপ, যখন আপনি জানেন যে আপনার মানগুলি 6 ডিজিট অবধি সঠিক হয়, তারপরে অর্ধপথের মানগুলিকে গোল করার জন্য সেই নির্ভুলতাটিকে মানটিতে যুক্ত করুন:

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

গোল করতে, নির্ভুলতা বিয়োগ করুন।


9
এটি সম্ভবত এখন পর্যন্ত উপস্থাপিত সেরা সমাধান। আমি যখন ডেসিমালফর্ম্যাট ক্লাসে প্রথম দেখলাম তখন এই সুবিধাটি সন্ধান করার কারণটি হ'ল এটি কেবল জাভা ১. introduced এ চালু হয়েছিল। দুর্ভাগ্যক্রমে আমি 1.5 ব্যবহারের মধ্যে সীমাবদ্ধ আছি তবে ভবিষ্যতের জন্য এটি দরকারী হবে।
অ্যালেক্স স্পার্লিং 13

1
আমি এটি দিয়ে চেষ্টা করেছি "#.##":, গোলাকার HALF_UP256.335f-> "256.33"... (উদাহরণগুলি মন্তব্য থেকে @ গ্রহাণুর উত্তরে আসে)।
পাথর

6
আপনার বর্তমান স্থানীয় কনফিগারেশনের উপর নির্ভর করে ডেসিমাল ফর্ম্যাট হিসাবে সাবধান থাকুন, আপনি বিভাজক হিসাবে কোনও বিন্দু নাও পেতে পারেন। আমি ব্যক্তিগতভাবে নীচে অ্যাসেরাইটের উত্তরটি পছন্দ করি
17/01 এ গমনো

1
এছাড়াও সচেতন থাকুন যে আপনি ডেসিমাল ফর্ম্যাটটি থ্রেড-সেফ হওয়ার আশা করবেন না। অনুযায়ী জাভা ডক্স : ডেসিমাল ফরম্যাটের সাধারণত সিঙ্ক্রোনাইজ করা নেই। প্রতিটি থ্রেডের জন্য পৃথক ফর্ম্যাট উদাহরণ তৈরি করার পরামর্শ দেওয়া হয়। যদি একাধিক থ্রেড একই সাথে একটি বিন্যাসে অ্যাক্সেস করে তবে অবশ্যই এটি বাহ্যিকভাবে সিঙ্ক্রোনাইজ করা উচিত।
সিজিকে

1
আমি কীভাবে এটি তৈরি করব যাতে এটি একটি উপযুক্ত গোল হয় তাই এটি 0.0004 থেকে 0.001

471

ধরে valueনেওয়া একটি double, আপনি এটি করতে পারেন:

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

এটি 5 ডিজিটের নির্ভুলতার জন্য। শূন্যের সংখ্যা দশমিকের সংখ্যা নির্দেশ করে।


71
আপডেট: আমি কেবল নিশ্চিত করেছি যে এটি করা ডেসিমালফোর্ম্যাট ব্যবহারের চেয়ে দ্রুত। আমি ডেসিমালফর্ম্যাটটি 200 বার এবং এই পদ্ধতিটি ব্যবহার করে লুপ করেছি। ডেসিমালফর্ম্যাট 200 লুপগুলি সম্পন্ন করতে 14 মিমি নিয়েছে, এই পদ্ধতিটি 1 মিমের চেয়ে কম সময় নিয়েছে। আমি সন্দেহ হিসাবে, এটি দ্রুত। আপনি যদি ঘড়ির চক্র দ্বারা অর্থ প্রদান করে থাকেন তবে আপনার যা করা উচিত তা এটি। আমি অবাক হয়েছি ক্রিস চডমোর এমনকি তিনি যা বলেছিলেন তা সৎ বলেছিলেন। দশমিক ফর্ম্যাট.ফর্ম্যাট ()) এর বিপরীতে স্থায়ী পদ্ধতিগুলি (ম্যাথ.াউন্ড ()) ব্যবহারের চেয়ে অবজেক্ট অবজেক্টগুলি সর্বদা ব্যয়বহুল।
অ্যান্ডি জে

99
এই কৌশলটি 90% এরও বেশি ক্ষেত্রে ব্যর্থ হয়। -1।
ব্যবহারকারী 207421

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 এ গোল হয়ে যায়। ভাসমান পয়েন্ট সংখ্যা থেকে বাস্তব দশমিক সংখ্যায় রূপান্তর করার সময় কেবল সহজাত সমস্যা রয়েছে। EJP এর উত্তরটি এখানে স্ট্যাকওভারফ্লো
সেবাস্তিয়ান ভ্যান ডেন ব্রুক

6
@ সেবাসতিয়ানভানডেন ব্রুক: বাহ আমি কখনই জানতাম না যে ভুল উত্তর পাওয়া এত সহজ। তবে, যদি কেউ অ-নির্ভুল সংখ্যা নিয়ে কাজ করে তবে একজনকে অবশ্যই বুঝতে হবে যে কোনও মান সঠিক নয়265.335সত্যিকারের অর্থ 265.335 += tolerance, যেখানে সহনশীলতা পূর্ববর্তী ক্রিয়াকলাপ এবং ইনপুট মানগুলির ব্যাপ্তির উপর নির্ভর করে। আমরা সত্য, সঠিক মান জানি না। প্রান্ত মান এ পারেন উত্তর তর্কসাপেক্ষে সঠিক। আমাদের যদি নির্ভুল হওয়া দরকার তবে আমাদের দ্বিগুণ কাজ করা উচিত নয়। failএখানে ডবল ফিরে রূপান্তর নেই। ওপিতে এটি ভেবেছিল যে তিনি আগমনটি 265.335ঠিক সেইরকমভাবে নির্ভর করতে পারেন ।
টুলমেকারস্টেভ

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

আপনি একটি পাবেন BigDecimal। এর থেকে স্ট্রিংটি পেতে, কেবল সেই পদ্ধতিটি বা প্লেইন ফর্ম্যাট স্ট্রিংয়ের জন্য জাভা 5+ BigDecimalএর toStringপদ্ধতিটি কল করুন toPlainString

নমুনা প্রোগ্রাম:

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
এটাই আমার পছন্দের সমাধান। এমনকি আরও খাটো: বিগডিসিমাল.ভ্যালুওফ (ডাবলওভার) .সেটস্কেল (আপনার স্কেলহির, বিগডিসিমাল.রোউND_HALF_UP); বিগডিসিমাল.ভ্যালুওফ (ডাবল ভাল) ডাবল টো স্ট্রিংকে () ফণার নীচে ডাকে;)
এতিয়েন নেভু

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
@ টুলমেকারস্টেভ এটি কারণ ডাবলের সাথে নতুন বিগডিসিমাল ব্যবহার করা ডাবল মানকে সরাসরি গ্রহণ করে এবং বিগডিসিমাল তৈরি করার জন্য এটি ব্যবহারের চেষ্টা করে, যখন বিগডিসিমাল.ভ্যালুঅফ বা টোস্টিং ফর্মটি রূপান্তর করার আগে প্রথমে একটি স্ট্রিং (আরও সঠিক উপস্থাপনা) এ পার্স করে থাকে ।
MetroidFan2002

116

আপনি এটি ব্যবহার করতে পারেন

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

আপনার পিছনে 0 এর রয়েছে তা নিশ্চিত করতে।


25
আমি বিশ্বাস করি যে প্রশ্নের অন্যতম লক্ষ্য ছিল যে " কোনও পিছনে জিরো থাকা উচিত নয় "।
লাঞ্চবক্স

7
এই প্রশ্নের জন্য, অপটি জিরোস চায় নি, তবে এটি আমি যা চেয়েছিলাম ঠিক এটি। যদি আপনার 3 দশমিক স্থানের সাথে সংখ্যার একটি তালিকা থাকে তবে আপনি এটি 0 এর পরেও সবার কাছে একই অঙ্কের চান
টম কিনকেড

আপনি উল্লেখ করতে ভুলে গেছেনRoundingMode.
আইগোরগানাপলস্কি

1
ডিফল্ট Decimal modeব্যবহারের মাধ্যমে RoundingMode.HALF_EVEN.
@ ইগরগানাপলস্কি

87

যেমন অন্য কেউ উল্লেখ করেছেন, সঠিক উত্তরটি হয় হয় DecimalFormatবা হয় ব্যবহার করা BigDecimal। ফ্লোটিং পয়েন্ট নেই আছে যাতে আপনি সম্ভবত বৃত্তাকার পারবনা দশমিক স্থান / প্রথম স্থানে তাদের একটি নির্দিষ্ট নম্বরে আরোপ করা। আপনাকে দশমিক র‌্যাডিক্সে কাজ করতে হবে এবং এই দুটি ক্লাসই তা করে।

আমি এই থ্রেডের সমস্ত উত্তর এবং প্রকৃতপক্ষে সমস্ত স্ট্যাকওভারফ্লো (এবং অন্য কোথাও) জুড়ে নীচের কোডটি কাউন্টার-উদাহরণ হিসাবে পোস্ট করছি যা বিভাগ অনুসারে কাটা কাটা দ্বারা বহুবৃত্তির প্রস্তাব দেয়। নিম্নলিখিত কোডটি 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
@ ডিডিএরএল আমাকে অবাক করে না আমার প্রথম কম্পিউটিং কোর্স হিসাবে 'সংখ্যাগত পদ্ধতিগুলি' করার খুব ভাল ভাগ্য আমার ছিল এবং ভাসমান-পয়েন্ট কী করতে পারে এবং কী করতে পারে না তার শুরুতেই শুরু হয়েছিল। বেশিরভাগ প্রোগ্রামাররা এটি সম্পর্কে বেশ অস্পষ্ট।
ব্যবহারকারী 207421

15
আপনি যা করছেন তা খণ্ডন করা হচ্ছে যে ভাসমান অনেকগুলি দশমিক মানকে হুবহু উপস্থাপন করে না, যা আমি আশা করি আমরা সকলেই বুঝতে পারি। রাউন্ডিং কোনও সমস্যার কারণ হয় না। আপনি যেমন স্বীকার করেন, সংখ্যাগুলি এখনও প্রত্যাশার মতো মুদ্রণ করে।
পিটার লরি

8
আপনার পরীক্ষাটি ভেঙে গেছে, গোল করে বেরোন () এবং পরীক্ষার সময় ব্যর্থ হয় 94%। ideone.com/1y62CY প্রিন্ট করে 100 trials 94 errorsআপনার পাস হওয়া একটি পরীক্ষা দিয়ে শুরু করা উচিত, এবং দেখান যে রাউন্ডিংয়ের মাধ্যমে পরীক্ষার বিরতি হয়।
পিটার লরি

6
খ্যাতি, খণ্ডন এখানে। এই সীমার জন্য ম্যাথ.গ্রাউন্ডকে doubleকোনও ত্রুটি হিসাবে বিবেচনা করবেন না আদর্শ
পিটার

83

ধরুন আপনার আছে

double d = 9232.129394d;

তুমি ব্যবহার করতে পার BigDecimal

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

বা বিগডিসিমাল ছাড়াই

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

উভয় সমাধান সঙ্গে d == 9232.13


2
আমি মনে করি এটি জাভা 1.5 ব্যবহারকারীদের (এবং নীচে) জন্য সেরা সমাধান। একটি মন্তব্য, এইচএলএফ_এভিএন রাউন্ডিং মোডটি ব্যবহার করবেন না কারণ এটি বিজোড় এবং এমনকি সংখ্যার জন্য পৃথক আচরণ করে (উদাহরণস্বরূপ, ২.৫ রাউন্ড থেকে ২ এবং ৫.৫ রাউন্ড থেকে।, উদাহরণস্বরূপ), যদি না আপনি এটি চান।
আইসডড্যান্ট

4
প্রথম সমাধানটি সঠিক: দ্বিতীয়টি কাজ করে না। প্রমাণ জন্য এখানে দেখুন ।
ব্যবহারকারী 207421

1
@ এজেপি: এমনকি প্রথম সমাধানটিও RoundingMode.HALF_UPভুল। এটি দিয়ে চেষ্টা করুন 1.505। সঠিক উপায়টি ব্যবহার করা BigDecimal.valueOf(d)
ম্যাথিয়াস ব্রাউন

ম্যাথিয়াস ব্রাউন, সমাধানটি ঠিক আছে, সুতরাং 31 টি আপস .. 1.505 দশমিক ভাসমান পয়েন্টে ডাবল হিসাবে সংরক্ষণ করা হয় 1.50499998 আপনি যদি 1.505 নিতে এবং ডাবল থেকে দশমিক রূপান্তর করতে চান তবে আপনাকে প্রথমে Double.toString (x) এ রূপান্তর করতে হবে তারপরে এটিকে একটি বিগডিসিমাল () এ রাখুন তবে এটি অত্যন্ত ধীর এবং প্রথম স্থানে গতির জন্য দ্বিগুণ ব্যবহারের উদ্দেশ্যকে পরাস্ত করে।
হামিশ

1
বিগডিসিমাল (২২৫ এমএস নিয়েছে) এবং ম্যাথ.াউন্ড (২ এমএস) পথের সাথে ১০০ কেটের একটি লুপ রান করুন এবং সময়টি এখানে এসেছে ... সময় গৃহীত হয়েছে: রূপান্তর করতে 225 মিলি সেকেন্ড: 9232.13 সময় গৃহীত: রূপান্তর করতে 2 মিলি সেকেন্ড : 9232.13 techiesinfo.com
ব্যবহারকারী 1114134

59

আপনি ডেসিমালফর্ম্যাট ক্লাসটি ব্যবহার করতে পারেন।

double d = 3.76628729;

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

কোন কারণে কেন Double.valueOf()বেছে নেওয়া হয়েছিল Double.parseDouble()? valueOf()পদ্ধতি ফেরৎ Doubleবস্তু, যখন parseDouble()একটি ফিরে আসবে doubleআদিম। বর্তমান কোডটি যেভাবে লিখিত হয়েছে, আপনি আপনার twoDoubleচলকটি যে আদিম প্রত্যাশা করে, এটি একটি অতিরিক্ত বাইকোড অপারেশন দ্বারা প্রত্যাবর্তিত আদিতে কাস্ট করতে ফিরতি অটো-আনবক্সিং প্রয়োগ করে apply পরিবর্তে আমি উত্তরটি পরিবর্তন করতে চাই parseDouble()
ecbrodie

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
হ্যাঁ এটিই ঠিক গণিতের জন্য round লোকেরা অন্যান্য সমাধানগুলিতে গণিত.গ্রাউন্ড ব্যবহার করে নেতিবাচক সংখ্যার ক্ষেত্রেও আচ্ছাদন করে।
হামিশ

দ্রষ্টব্য: Math.floor(x + 0.5)এবংMath.round(x)
পিটার লরে

30

@ মিলহৌস: রাউন্ডিংয়ের জন্য দশমিক বিন্যাসটি দুর্দান্ত:

আপনি এটি ব্যবহার করতে পারেন

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

আপনার পিছনে 0 এর রয়েছে তা নিশ্চিত করতে।

আমি যুক্ত করব যে এই পদ্ধতিটি একটি আসল সংখ্যাসূচক, বৃত্তাকার মেকানিজম সরবরাহ করার ক্ষেত্রে খুব ভাল - কেবলমাত্র দৃষ্টিভঙ্গি নয়, প্রক্রিয়াজাতকরণের সময়ও।

হাইপোথিটিক্যাল: আপনাকে একটি জিইউআই প্রোগ্রামে গোল করার প্রক্রিয়াটি প্রয়োগ করতে হবে। ফলাফলের আউটপুটটির যথার্থতা / নির্ভুলতা পরিবর্তন করতে কেবল ক্যারেটের বিন্যাস পরিবর্তন করা (যেমন বন্ধনীগুলির মধ্যে)। যাতে:

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 লিখুন, যুক্তির জন্য, ডেসিমাল ফর্ম্যাট কোনও আবর্জনা তৈরি করে না ( উদাহরণস্বরূপ পিছনে জিরো) এবং ফিরে আসবে: 3.1415926.. আপনি যদি এইভাবে ঝুঁকছেন। মঞ্জুর, এটি কিছু দেবের পছন্দ হিসাবে কিছুটা ভার্জোজ - তবে আরে, এটি প্রক্রিয়া চলাকালীন একটি কম মেমরির পদচিহ্ন পেয়েছে এবং এটি কার্যকর করা খুব সহজ]]

তাই মূলত, ডেসিমালফর্ম্যাটটির সৌন্দর্য হ'ল এটি একই সাথে স্ট্রিং চেহারাটি হ্যান্ডেল করে - পাশাপাশি রাউন্ডিং স্পষ্টতা সেটের স্তরও। ত্রুটি: একটি কোড প্রয়োগের মূল্যের জন্য আপনি দুটি সুবিধা পান। ;)


2
আপনি কি সত্যিই দশমিক সংখ্যার গণনা জন্য (এবং না শুধুমাত্র আউটপুট), চান একটি বাইনারি ভিত্তিক ফ্লোটিং পয়েন্ট বিন্যাস ব্যবহার করবেন না মত double। বিগডিসিমাল বা অন্য কোনও দশমিক-ভিত্তিক ফর্ম্যাট ব্যবহার করুন।
পাওলো ইবারম্যান

20

আপনি যদি স্ট্রিং হিসাবে ফলাফল চান তবে আপনি কী ব্যবহার করতে পারবেন তার একটি সংক্ষিপ্তসার এখানে:

  1. ডেসিমাল ফরম্যাট # সেটরউন্ডিংমোড () :

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

@ এমিরোলপ্যান্টুনস: এটি ব্যর্থ হবে। এটি চেষ্টা করুন: round(1.005,2);বাround(0.50594724957626620092, 20);
ম্যাথিয়াস ব্রাউন

এটা কাজ করে। তবে অজানা ফ্লোট এবং ডাবলগুলি প্রায় অনুমান। আসুন আপনার প্রথম উদাহরণ বিবেচনা করা যাক। আপনি যদি ম্যাথ.াউন্ডের আগে আগ্রহীআইনজিরোডিপিগুলির আউটপুট মুদ্রণ করেন তবে এটি 100.49999999999999 মুদ্রণ করবে। আপনি স্পষ্টতা প্রকৃতি বা ভাসে হিসেবে 100 দরুন এটা বৃত্তাকার যেমন Math.round যেমন হারিয়ে ফেলেছে এবং এখন দ্বিগুণ ভূমিকা ক্ষেত্রে যখন এটি সঠিকভাবে (আরও তথ্য এখানে কাজ করে না আছে en.wikipedia.org/wiki/Floating_point#Accuracy_problems )
mariolpantunes

দ্বিগুণ দ্রুত! দশমিক ধীর। দশমিক স্বীকৃতিতে কম্পিউটারগুলি তাদের চিন্তাভাবনা প্রক্রিয়াকরণ করতে বিরক্ত করে না। ভাসমান পয়েন্টটি দ্বিগুণ রাখতে আপনাকে কিছুটা দশমিক নির্ভুলতা দিতে হবে।
হামিশ

@ হ্যামিশ প্রশ্নটি নির্ভুলতা সম্পর্কে, গতি সম্পর্কে নয়।
ব্যবহারকারী 207421

13

একটি সংক্ষিপ্ত সমাধান:

   public static double round(double value, int precision) {
      int scale = (int) Math.pow(10, precision);
      return (double) Math.round(value * scale) / scale;
  }

এছাড়াও দেখুন, https://stackoverflow.com/a/22186845/212950 এই অফার করার জন্য jpdymond ধন্যবাদ ।



7

এটি ব্যবহার করে দেখুন: org.apache.commons.math3.util.Precision.round (ডাবল এক্স, ইনট স্কেল)

দেখুন: http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/Precision.html

অ্যাপাচি কমন্স গণিতের পাঠাগারটির হোমপেজটি হ'ল: 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.

আমি গণনার জন্য বিগডিসিমাল ব্যবহার করি তবে মনে রাখবেন এটি আপনার সাথে সংখ্যার আকারের উপর নির্ভরশীল। আমার বেশিরভাগ বাস্তবায়নে, আমি ডাবল বা পূর্ণসংখ্যার থেকে লং পর্যন্ত পার্সিং খুব বড় সংখ্যার গণনার জন্য যথেষ্ট is

আসলে, আমি সম্প্রতি একটি জিইউআইতে সঠিক উপস্থাপনা (হেক্স ফলাফলের বিপরীতে) পাওয়ার জন্য পার্সড টু-লং ব্যবহার করেছি #################### ################ অক্ষর (উদাহরণ হিসাবে)।


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দশমিক ৪ জ লাইব্রেরিতে একটি অনুরূপ তবে দ্রুত এবং আবর্জনামুক্ত পদ্ধতি ইউটিলিটি সরবরাহ করেছে :

 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- ইউটিলিটি দেখুন

দাবি অস্বীকার : আমি দশমিক 4j প্রকল্পের সাথে জড়িত।

আপডেট: @ আইফোরক যেমনটি নির্দেশ করেছেন ডাবলরাউন্ডার কখনও কখনও বিপরীত ফলাফল দেয়। কারণ হ'ল এটি গাণিতিকভাবে সঠিক রাউন্ডিং করে। উদাহরণস্বরূপ DoubleRounder.round(256.025d, 2)256.02 এ গোল হয়ে যাবে কারণ 256.025d হিসাবে উপস্থাপিত দ্বৈত মানটি যুক্তিযুক্ত মান 256.025 এর চেয়ে কিছুটা ছোট এবং তাই গোল হয়ে যাবে।

মন্তব্য:

  • এই আচরণটি BigDecimal(double)কনস্ট্রাক্টরের সাথে খুব মিল (তবে valueOf(double)স্ট্রিং কনস্ট্রাক্টর ব্যবহার করে না তবে )।
  • সমস্যাটি প্রথমে একটি উচ্চতর নির্ভুলতার দিকে দ্বৈত বৃত্তাকার পদক্ষেপের সাথে সংশোধন করা যেতে পারে তবে এটি জটিল এবং আমি এখানে বিশদটি নিয়ে যাচ্ছি না

এই কারণগুলিতে এবং এই পোস্টে উপরে উল্লিখিত সমস্ত কিছুর জন্য আমি ডাবল রাউন্ডার ব্যবহার করার পরামর্শ দিতে পারি না


অন্যান্য সমাধানের তুলনায় আপনার সমাধানটি কতটা কার্যকর তা দেখানোর মেট্রিক রয়েছে?
iafork

আমি এটিকে অন্যান্য সমাধানগুলির সাথে তুলনা করি নি তবে উত্স কোডে একটি জেএমএইচ বেঞ্চমার্ক উপলব্ধ রয়েছে: github.com/tools4j/decimal4j/blob/master/src/jmh/java/org/… আমি কোনও ভিএম-তে বেঞ্চমার্ক চালিয়েছি :, ফলাফল CSV ফাইল এখানে পাওয়া যায় github.com/tools4j/decimal4j/wiki/Performance
মার্কো

1
ডাবলরাউন্ডার নিম্নলিখিত ক্ষেত্রে ব্যর্থ: ডাবলরাউন্ডারাউন্ড (256.025 ডি, 2) - প্রত্যাশিত: 256.03, প্রকৃত: 256.02 বা ডাবলরাউন্ডারগ্রাউন্ডের (260.775 ডি, 2) - প্রত্যাশিত: 260.78, প্রকৃত: 260.77।
iaforek

@ আইফোরক: এটি সঠিক, কারণ ডাবলরাউন্ডার গাণিতিকভাবে সঠিক রাউন্ডিং করে। তবে আমি স্বীকার করি যে এটি কিছুটা বিপরীত এবং অতএব সেই অনুসারে আমার উত্তর আপডেট করবে।
মার্কো

3

নীচের কোড স্নিপেটে কীভাবে এন অঙ্কগুলি প্রদর্শিত হবে তা দেখায়। কৌশলটি হ'ল ভেরিয়েবল পিপি 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আপনার প্রয়োজনীয় আচরণের উপর নির্ভর করে নির্বাচন করতে বেশ কয়েকটি এনাম মান রয়েছে।


3

আমি এখানে এসেছি একটি সংখ্যাকে কিভাবে গোল করা যায় তার একটি সহজ উত্তর চাই want এটি সরবরাহের জন্য এটি একটি পরিপূরক উত্তর।

জাভাতে কোনও সংখ্যাকে কিভাবে গোল করবেন

সবচেয়ে সাধারণ ক্ষেত্রে ব্যবহার করা হয় 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

ছাদের নিচের পিঠ নির্মাণ করা

যেকোন দশমিক মান পরবর্তী পূর্ণসংখ্যা পর্যন্ত গোল হয়। এটি সিল ইনিংয়ে যায় । এই পদ্ধতিটি a 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

মেঝে

যে কোনও দশমিক মান পরবর্তী সংখ্যায় গোল হয়। এই পদ্ধতিটি a 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পূর্ণসংখ্যার মানগুলি হয় না। এই পদ্ধতিটি a 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

আপনি যদি এমন কোনও প্রযুক্তি ব্যবহার করছেন যা সর্বনিম্ন জেডিকে রয়েছে। এখানে কোনও জাভা ছাড়াই একটি উপায়:

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

এটি মাইভাল 1 এর চেয়ে কম নয় এবং স্কেল মানের বাইরে দশমিক পরে শূন্যের ক্ষেত্রে ব্যর্থ হবে। বলুন আপনার মাইভাল = 9.00000000912385; উপরেরটি 9.0 এ ফিরে আসবে। আমি মনে করি আমাদের এমন একটি সমাধান সরবরাহ করা উচিত যা মাইওয়ালের সমস্ত ক্ষেত্রে কার্যকর হয়। আপনার বর্ণিত মানটির জন্য বিশেষভাবে নয়।
ট্যাভ্যালেন্ডো

@ user102859 আপনার উদাহরণে, 9.0 সঠিক ফলাফল। আমি বুঝতে পারি না কীভাবে এটি ব্যর্থ হবে।
ক্রেিগো

2

ডেসিমালফর্ম্যাট আউটপুট দেওয়ার সর্বোত্তম উপায় তবে আমি এটিকে পছন্দ করি না। আমি সবসময় এটি করি, কারণ এটি দ্বিগুণ হয়। সুতরাং আমি এটি কেবল আউটপুটের চেয়ে বেশি ব্যবহার করতে পারি।

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

অথবা

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

আপনার যদি বড় দশমিক স্থানের মান প্রয়োজন হয় তবে আপনি এর পরিবর্তে বিগডিসিমাল ব্যবহার করতে পারেন। যাইহোক .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কী করছেন। সুতরাং ওরাকল ডক্স অনুসন্ধান করে , আপনি নিম্নলিখিত বিবরণ পাবেন 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
@ হ্যামিশ আমি দেখতে পাচ্ছি না যেখানে ম্যাথিয়াস 'পাঠকদের বিশ্বাস করতে চাইবে' এমন কোনও বিষয় যেখানে দশমিক হিসাবে মান সংকলিত হয়। অন্য লোকের মুখে শব্দ রাখবেন না।
ব্যবহারকারী 207421

0

মনে রাখবেন যে স্ট্রিং.ফর্ম্যাট () এবং ডেসিমালফর্ম্যাট ডিফল্ট লোকেল ব্যবহার করে স্ট্রিং উত্পাদন করে। সুতরাং তারা পূর্ণসংখ্যা এবং দশমিক অংশগুলির মধ্যে বিভাজক হিসাবে বিন্দু বা কমা দিয়ে ফর্ম্যাট সংখ্যা লিখতে পারে। গোলাকার স্ট্রিংটি যেভাবে আপনি java.text.Number Format ব্যবহার করতে চান সেই ফর্ম্যাটে রয়েছে তা নিশ্চিত করার জন্য:

  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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.