অপ্রয়োজনীয় দশমিক 0 ছাড়াই স্ট্রিংয়ে ভাসমান সংখ্যাগুলি কীভাবে সুন্দরভাবে ফর্ম্যাট করবেন?


495

একটি 64-বিট ডাবল হুবহু পুরোপুরি +/- 2 53 উপস্থাপন করতে পারে

আমার সবচেয়ে বড় পূর্ণসংখ্যা 32-বিট স্বাক্ষরিত না হওয়ায় এই সত্যটি দেওয়া, আমি আমার সমস্ত প্রকারের জন্য একক প্রকার হিসাবে একটি দ্বৈত প্রকার ব্যবহার করতে পছন্দ করি।

তবে এখন আমাকে এই ছদ্ম পূর্ণসংখ্যাটি মুদ্রণ করতে হবে তবে সমস্যাটি হ'ল এগুলিও প্রকৃত দ্বিগুণের সাথে মিশে গেছে।

তাহলে আমি এই ডাবলগুলি জাভাতে কীভাবে প্রিন্ট করব?

আমি চেষ্টা করেছি String.format("%f", value), যা নিকটতম, বাদে আমি ছোট মানগুলির জন্য অনেক পিছনে জিরো পাই get

এর উদাহরণ আউটপুট এখানে %f

232.00000000
0,18000000000
1237875192,0
4,5800000000
0.00000000
1.23450000

আমি যা চাই তা হ'ল:

232
0.18
1237875192
4.58
0
1,2345

অবশ্যই আমি এই শূন্যগুলি ছাঁটাতে কোনও ফাংশন লিখতে পারি, তবে স্ট্রিংয়ের কারসাজির কারণে এটি অনেক কার্যকারিতা হ্রাস পেয়েছে। আমি অন্য ফর্ম্যাট কোড দিয়ে আরও ভাল করতে পারি?

সম্পাদনা

টম ই এবং জেরেমি এস এর উত্তরগুলি গ্রহণযোগ্য নয় কারণ তারা উভয়ই নির্বিচারে 2 দশমিক স্থানে ঘোরাফেরা করে। উত্তর দেওয়ার আগে দয়া করে সমস্যাটি বুঝতে পারেন।

সম্পাদনা 2

দয়া করে মনে রাখবেন String.format(format, args...)হয় লোকেল নির্ভর (নীচে উত্তর দেখুন)।


আপনি যদি চান সমস্তগুলি পূর্ণসংখ্যা হয় তবে কেন দীর্ঘ ব্যবহার করবেন না? আপনি 2 ^ 63-1 এ আরও বিশৃঙ্খলা পাবেন, কোনও বিশ্রী বিন্যাস এবং আরও ভাল পারফরম্যান্স পাবেন।
বাসেরো

14
কারণ কিছু মান প্রকৃতপক্ষে দ্বিগুণ
পাইরিওলিস্টিকাল

2
কিছু ক্ষেত্রে যেখানে এই সমস্যা ঘটেছে একটি বাগ JDK 7 সংশোধন ছিল: stackoverflow.com/questions/7564525/...
Pyrolistical

এটি কি আমি বা জাভা স্ক্রিপ্ট জাভা থেকে স্ট্রিং রূপান্তরকরণের ক্ষেত্রে 100% ভাল?
অ্যান্ডি

System.out.println("YOUR STRING" + YOUR_DOUBLE_VARIABLE);
শায়ান আমানী

উত্তর:


399

যদি ধারণাটি থাকে যে সংখ্যাগুলি সঞ্চিত পূর্ণসংখ্যাগুলি ডাবল হিসাবে যেমন তারা পূর্ণসংখ্যা হয় এবং অন্যথায় নূন্যতম প্রয়োজনীয় নির্ভুলতার সাথে ডাবলগুলি মুদ্রণ করে:

public static String fmt(double d)
{
    if(d == (long) d)
        return String.format("%d",(long)d);
    else
        return String.format("%s",d);
}

উত্পাদন:

232
0.18
1237875192
4.58
0
1.2345

এবং স্ট্রিং ম্যানিপুলেশন উপর নির্ভর করে না।


9
সম্মত, এটি একটি খারাপ উত্তর, এটি ব্যবহার করবেন না। এটি doubleসর্বোচ্চ intমানের চেয়ে বৃহত্তর সাথে কাজ করতে ব্যর্থ । এমনকি longএটি বিপুল সংখ্যক জন্য ব্যর্থ হবে। আরও এটি বৃহত্তর মানগুলির জন্য সূচকযুক্ত আকারে যেমন একটি স্ট্রিং প্রদান করবে, যেমন "1.0E10", যা সম্ভবত প্রশ্নকারী চান না। এটি ঠিক করতে দ্বিতীয় ফর্ম্যাট স্ট্রিংয়ের %fপরিবর্তে ব্যবহার করুন %s
jlh

26
ওপি স্পষ্টভাবে বলেছে যে তারা আউটপুটটি ফর্ম্যাট করে ব্যবহার করতে চায় না %f। উত্তর বর্ণিত পরিস্থিতির সাথে সুনির্দিষ্ট এবং পছন্দসই আউটপুট। ওপি পরামর্শ দিয়েছে যে তাদের সর্বোচ্চ মানটি 32-বিট স্বাক্ষরবিহীন অন্তর্নিহিত অন্তর্ভুক্ত ছিল, যার অর্থ আমি intগ্রহণযোগ্য তা গ্রহণ করেছি (জাভাতে স্বাক্ষরবিহীন আসলে নেই, এবং কোনও উদাহরণই সমস্যাযুক্ত ছিল না), তবে পরিস্থিতি ভিন্ন হলে এটি পরিবর্তন intকরা longএকটি তুচ্ছ সংশোধন।
জেসনডি

1
প্রশ্নে কোথায় বলা হয়েছে যে এটি করা উচিত নয়?
জেসনডি

6
String.format("%s",d)??? অপ্রয়োজনীয় ওভারহেড সম্পর্কে কথা বলুন। ব্যবহার Double.toString(d)। অপরের জন্য একই: Long.toString((long)d)
Andreas

15
সমস্যাটি হ'ল %sলোকালগুলির সাথে কাজ করে না। জার্মান ভাষায়, আমরা "" এর পরিবর্তে "," ব্যবহার করি। দশমিক সংখ্যায় যদিও String.format(Locale.GERMAN, "%f", 1.5)আয় "1,500000", String.format(Locale.GERMAN, "%s", 1.5)আয় "1.5" - "।" একটি সঙ্গে, যা জার্মান ভাষায় মিথ্যা। "% S" এর লোকেল-নির্ভর সংস্করণও কি আছে?
ফেলিক্স এডেলম্যান

414
new DecimalFormat("#.##").format(1.199); //"1.2"

মন্তব্যে নির্দেশিত হিসাবে, এটি মূল প্রশ্নের সঠিক উত্তর নয়।
এটি বলেছিল, অপ্রয়োজনীয় ট্রেইলিং জিরো ছাড়াই সংখ্যার ফর্ম্যাট করা এটি খুব কার্যকর উপায়।


16
এখানে একটি গুরুত্বপূর্ণ নোটটি হ'ল 1.1 সঠিকভাবে কোনও "পিছনে জিরো" ছাড়াই "1.1" হিসাবে ফর্ম্যাট করা হবে।
স্টিভ পোমেরো

53
এবং যদি আপনি কোনও নির্দিষ্ট সংখ্যক পেছনের শূন্যগুলি দেখতে চান (যেমন আপনি যদি অর্থের পরিমাণ মুদ্রণ করছেন) তবে আপনি '#' এর পরিবর্তে '0' ব্যবহার করতে পারেন (যেমন নতুন দশমিক ফরম্যাট ("0.00")। ফর্ম্যাট (পরিমাণ);) এটি ওপি যা চেয়েছিল তা নয়, তবে এটি রেফারেন্সের জন্য কার্যকর হতে পারে।
টিজে এলিস

22
হ্যাঁ, প্রশ্নের মূল লেখক হিসাবে এটি হ'ল রাউং উত্তর। মজাদার কত আপ ভোট আছে। এই সমাধানটির সমস্যাটি হ'ল এটি নির্বিচারে 2 দশমিক জায়গায় s
পাইরোলিস্টিকাল

11
@ মাইযোড কারণ আপনি সবসময় বিন্যাসের চেয়ে বেশি দশমিকের সাথে ভাসমান পয়েন্টিংয়ে পাস করতে পারেন। এটি কোড লিখন যা বেশিরভাগ সময় কাজ করবে তবে সমস্ত প্রান্তের কেসটি কভার করবে না।
পাইরোলিস্টিকাল

15
@ পাইরোলিস্টিকাল - আইএমএইচও, অনেকগুলি আপোভেট রয়েছে কারণ যদিও এটি আপনার পক্ষে ভুল সমাধান, তবে যারা এই প্রশ্নোত্তর খুঁজে পান তাদের 99% + এর জন্য এটি সঠিক সমাধান: সাধারণত, দ্বিগুণের চূড়ান্ত কয়েকটি অঙ্ক হ'ল "শব্দ", যে আউটপুট বিশৃঙ্খল, পাঠযোগ্যতার সাথে হস্তক্ষেপ। সুতরাং প্রোগ্রামার নির্ধারণ করে যে আউটপুটটি পড়া ব্যক্তিটির পক্ষে কতগুলি সংখ্যা উপকারী এবং এটির জন্য নির্দিষ্ট করে। একটি সাধারণ পরিস্থিতি হ'ল ছোট অঙ্কের ত্রুটিগুলি জমা হয়েছে, সুতরাং একটি মান হতে পারে 12.000000034, তবে এটি 12 এর চেয়ে বেশি পছন্দ করে এবং "12" হিসাবে সংক্ষিপ্তভাবে প্রদর্শন করবে। এবং "12.340000056" => "12.34"।
টুলমেকারস্টেভ

227
String.format("%.2f", value) ;

13
এটি সঠিক তবে ভগ্নাংশের কোনও অংশ না থাকলেও সর্বদা জিরোগুলি অনুসরণ করে প্রিন্ট করে। স্ট্রিং.ফর্ম্যাট ("%। 2f, 1.0005) প্রিন্ট করে 1.00 এবং 1 টি নয় 1. ভগ্নাংশের অস্তিত্ব না থাকলে মুদ্রণ না করার জন্য কোনও ফর্ম্যাট স্পেসিফায়ার আছে কি?
এমরে ইয়াজিসি

86
ডাউন ভোট দিয়েছে যেহেতু প্রশ্নটি সমস্ত চলমান শূন্যগুলি ছিনিয়ে নিতে বলছে এবং এই উত্তরটি সর্বদা দুটি ভাসমান পয়েন্ট ছেড়ে যাবে শূন্য নির্বিশেষে।
জুলাক্সিয়া

ডেসিমালফর্ম্যাটটি একটি দুর্দান্ত কৌশল ছিল - যদিও আমি আমার পরিস্থিতির জন্য এটি ব্যবহার করে শেষ করেছি (গেম লেভেল টাইমার) যেহেতু পিছনের শূন্যগুলি আরও ভাল দেখছিল।
টিমোথি লি রাসেল

2
আমি মনে করি আপনি চ এর পরিবর্তে জি ব্যবহার করে পিছনে শূন্যগুলি সঠিকভাবে পরিচালনা করতে পারেন।
পিটার আজতাই 4'12

3
আমি "% .5f" সঙ্গে একটি প্রকাশনা সিস্টেমের মধ্যে এই সমাধান ব্যবহৃত, এবং এটা সত্যিই সত্যিই খারাপ, এটি ব্যবহার করবেন না ... কারণ এটি এই মুদ্রিত: 5.12E -4 পরিবর্তে 0,000512
হামিশ

87

সংক্ষেপে:

আপনি যদি পিছনের শূন্যগুলি এবং স্থানীয় সমস্যাগুলি থেকে মুক্তি পেতে চান তবে আপনার ব্যবহার করা উচিত:

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 এর সমান হলে বৈজ্ঞানিক স্বরলিপি ব্যবহার করে

    double myValue = 0.00000021d;
    String.format("%s", myvalue); //output: 2.1E-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
    
  • ডেসিমালফর্ম্যাট ব্যবহার করে আপনি স্থানীয় নির্ভর। ফরাসি লোকালে দশমিক বিভাজক কমা, বিন্দু নয়:

    double myValue = 0.00000021d;
    DecimalFormat df = new DecimalFormat("0");
    df.setMaximumFractionDigits(340);
    System.out.println(df.format(myvalue));//output: 0,00000021
    

    ENGLISH লোকেল ব্যবহার করা নিশ্চিত করে যে আপনি যেখানেই প্রোগ্রাম চালাবেন দশমিক বিভাজকের জন্য একটি পয়েন্ট পেয়েছেন

340 এর জন্য কেন ব্যবহার করছেন setMaximumFractionDigits?

দুটি কারণ:

  • setMaximumFractionDigitsএকটি পূর্ণসংখ্যা গ্রহণ করে তবে এর বাস্তবায়নে সর্বাধিক সংখ্যা রয়েছে DecimalFormat.DOUBLE_FRACTION_DIGITSযার মধ্যে 340 সমান
  • Double.MIN_VALUE = 4.9E-324 সুতরাং 340 সংখ্যার সাথে আপনি নিজের ডাবল এবং আলগা নির্ভুলতাটি গোল করবেন না তা নিশ্চিত

এটি পূর্ণসংখ্যার জন্য কাজ করে না, যেমন "2" "" "হয়ে যায়" "
কেপ

ধন্যবাদ, আমি 0পরিবর্তে প্যাটার্নটি ব্যবহার করে উত্তরটি ঠিক করেছি#.
JBE

আপনি ধ্রুবকটি ব্যবহার করছেন না DecimalFormat.DOUBLE_FRACTION_DIGITSতবে আপনি 340 মানটি ব্যবহার করছেন যা এর পরে এটি সমান হয় তা দেখানোর জন্য আপনি একটি মন্তব্য সরবরাহ করেন DecimalFormat.DOUBLE_FRACTION_DIGITS। কেন শুধু ধ্রুবক ব্যবহার করবেন না ???
মার্টেন বোদেউইস

1
কারণ এই বৈশিষ্ট্যটি সর্বজনীন নয় ... এটি "প্যাকেজ বান্ধব"
জেবিই

4
ধন্যবাদ! প্রকৃতপক্ষে, এই উত্তরটি কেবলমাত্র এটিই যা প্রশ্নে বর্ণিত সমস্ত প্রয়োজনীয়তার সাথে সত্যিই মেলে - এটি অপ্রয়োজনীয় শূন্যগুলি দেখায় না, সংখ্যাগুলির সাথে গোল করে না এবং স্থানীয়ভাবে নির্ভর। গ্রেট!
ফেলিক্স এডেলমান

26

কেন না:

if (d % 1.0 != 0)
    return String.format("%s", d);
else
    return String.format("%.0f",d);

এটি ডাবল দ্বারা সমর্থিত চরম মানগুলির সাথে কাজ করবে। উৎপাদনের:

0.12
12
12.144252
0

2
আমি এই উত্তরটি পছন্দ করি যার দ্বারা আমাদের ধরণের রূপান্তর করার দরকার নেই।
জেফ টি।

সংক্ষিপ্ত ব্যাখ্যা: "%s"মূলত কল করে d.toString()তবে এটি দিয়ে intবা যদি কাজ করে না d==null!
নেফ

24

আমার মেশিনে, নীচের ফাংশনটি জেসনডি এর উত্তর সরবরাহিত ফাংশনের চেয়ে প্রায় 7 গুণ দ্রুত , কারণ এটি এড়ানো হয় String.format:

public static String prettyPrint(double d) {
  int i = (int) d;
  return d == i ? String.valueOf(i) : String.valueOf(d);
}

1
হুঁ, এটি লোকেলগুলিকে বিবেচনায় নেয় না, তবে জেসনডিও দেয় না।
TWiStErRob


11

না, কিছু মনে করবেন না।

স্ট্রিং ম্যানিপুলেশনের কারণে কর্মক্ষমতা হ্রাস শূন্য।

এবং এখানে শেষে ট্রিম কোড %f

private static String trimTrailingZeros(String number) {
    if(!number.contains(".")) {
        return number;
    }

    return number.replaceAll("\\.?0*$", "");
}

7
আমি হ্রাস পেয়েছি কারণ আপনার সমাধানটি যাওয়ার সর্বোত্তম উপায় নয়। স্ট্রিং.ফর্ম্যাট দেখুন। আপনার সঠিক ফর্ম্যাট প্রকারটি ব্যবহার করতে হবে, এই পরিস্থিতিতে ভাসা। আমার উপরের উত্তর দেখুন।
jjnguy

6
আমি ভোট দিয়েছি কারণ আমারও একই সমস্যা রয়েছে এবং এখানে কেউ সমস্যা বুঝতে পারে বলে মনে হয় না।
ওবাই

1
টমের পোস্টে উল্লিখিত ডেসিমালফর্ম্যাট হিসাবে ডাউনভোটেড হ'ল আপনি যা খুঁজছিলেন ঠিক তেমন। এটি বেশ কার্যকরভাবে জিরোগুলি ফেলা করে।
স্টিভ পোমেরো

4
উপরের দিকে, সম্ভবত তিনি গোলটি ছাড়া শূন্যগুলি ট্রিম করতে চান? পিএস @ পাইরোলিস্টিকাল, অবশ্যই আপনি কেবল নাম্বার.রেপসএল ("।? 0 * $", "") ব্যবহার করতে পারেন; (এর পরে অবশ্যই ("।") রয়েছে)
রেহনো লিন্ডেক

1
ঠিক আছে, তাহলে আপনি কীভাবে ডেসিমালফর্ম্যাট দিয়ে আমার উদ্দেশ্য অর্জন করতে সক্ষম হবেন?
পাইরোলিস্টিকাল

8

একটি DecimalFormatএবং ব্যবহার করুনsetMinimumFractionDigits(0)


আমি যুক্ত করব setMaximumFractionDigits(2)এবং setGroupingUsed(false)(ওপি'র উল্লেখ নেই তবে উদাহরণ থেকে মনে হয় এটি প্রয়োজনীয়)। এছাড়াও, একটি ছোট পরীক্ষার ক্ষেত্রে এই ক্ষেত্রে তুচ্ছ হওয়ার পরে আঘাত লাগে না। তবুও, যেহেতু আমি এটির সহজ সমাধান বলে মনে করি, তাই একটি
উত্সাহটি

6
if (d == Math.floor(d)) {
    return String.format("%.0f", d);
} else {
    return Double.toString(d);
}

1
আমি মনে করি আমি এতে আপনাকে অনুসরণ করব: ডি
অ্যারাকোড

5

দয়া করে নোট করুন যে String.format(format, args...)এটি স্থানীয়-নির্ভর কারণ এটি ব্যবহারকারীর ডিফল্ট লোকেল ব্যবহার করে ফর্ম্যাট করে, এটি সম্ভবত কমা এবং এমনকি স্পেসের সাথে 123 456,789 বা 123,456.789 এর মতো , যা আপনার প্রত্যাশাটি ঠিক এটি নাও হতে পারে।

আপনি ব্যবহার করতে পছন্দ করতে পারেন String.format((Locale)null, format, args...)

উদাহরণ স্বরূপ,

    double f = 123456.789d;
    System.out.println(String.format(Locale.FRANCE,"%f",f));
    System.out.println(String.format(Locale.GERMANY,"%f",f));
    System.out.println(String.format(Locale.US,"%f",f));

কপি করে প্রিন্ট

123456,789000
123456,789000
123456.789000

এবং এটি String.format(format, args...)বিভিন্ন দেশে কি করবে ।

সম্পাদনা ঠিক আছে, যেহেতু আনুষ্ঠানিকতা নিয়ে আলোচনা হয়েছে:

    res += stripFpZeroes(String.format((Locale) null, (nDigits!=0 ? "%."+nDigits+"f" : "%f"), value));
    ...

protected static String stripFpZeroes(String fpnumber) {
    int n = fpnumber.indexOf('.');
    if (n == -1) {
        return fpnumber;
    }
    if (n < 2) {
        n = 2;
    }
    String s = fpnumber;
    while (s.length() > n && s.endsWith("0")) {
        s = s.substring(0, s.length()-1);
    }
    return s;
}

1
আপনার গ্রহণযোগ্য উত্তরের মন্তব্য হিসাবে এটি যুক্ত করা উচিত
পাইরোলিস্টিকাল

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

5

আমি DoubleFormatterএকটি দুর্দান্ত সংখ্যক দ্বৈত মানকে দক্ষ / উপস্থাপনযোগ্য স্ট্রিংয়ে দক্ষতার সাথে রূপান্তর করতে একটি করেছি:

double horribleNumber = 3598945.141658554548844; 
DoubleFormatter df = new DoubleFormatter(4,6); //4 = MaxInteger, 6 = MaxDecimal
String beautyDisplay = df.format(horribleNumber);
  • যদি ভি এর পূর্ণসংখ্যার অংশটি বৈজ্ঞানিক ফর্ম্যাটে (1.2345e + 30) ম্যাক্সইন্টিজার => ডিসপ্লে ভি এর চেয়ে বেশি থাকে তবে অন্যথায় 124.45678 ফর্ম্যাটে প্রদর্শিত হবে।
  • ম্যাক্সডেসিমাল দশমিক অঙ্কের সংখ্যা নির্ধারণ করে (ব্যাঙ্কারের গোলাকার সাথে ছাঁটাই)

এখানে কোড:

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

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;

/**
 * Convert a double to a beautiful String (US-local):
 * 
 * double horribleNumber = 3598945.141658554548844; 
 * DoubleFormatter df = new DoubleFormatter(4,6);
 * String beautyDisplay = df.format(horribleNumber);
 * String beautyLabel = df.formatHtml(horribleNumber);
 * 
 * Manipulate 3 instances of NumberFormat to efficiently format a great number of double values.
 * (avoid to create an object NumberFormat each call of format()).
 * 
 * 3 instances of NumberFormat will be reused to format a value v:
 * 
 * if v < EXP_DOWN, uses nfBelow
 * if EXP_DOWN <= v <= EXP_UP, uses nfNormal
 * if EXP_UP < v, uses nfAbove
 * 
 * nfBelow, nfNormal and nfAbove will be generated base on the precision_ parameter.
 * 
 * @author: DUONG Phu-Hiep
 */
public class DoubleFormatter
{
    private static final double EXP_DOWN = 1.e-3;
    private double EXP_UP; // always = 10^maxInteger
    private int maxInteger_;
    private int maxFraction_;
    private NumberFormat nfBelow_; 
    private NumberFormat nfNormal_;
    private NumberFormat nfAbove_;

    private enum NumberFormatKind {Below, Normal, Above}

    public DoubleFormatter(int maxInteger, int maxFraction){
        setPrecision(maxInteger, maxFraction);
    }

    public void setPrecision(int maxInteger, int maxFraction){
        Preconditions.checkArgument(maxFraction>=0);
        Preconditions.checkArgument(maxInteger>0 && maxInteger<17);

        if (maxFraction == maxFraction_ && maxInteger_ == maxInteger) {
            return;
        }

        maxFraction_ = maxFraction;
        maxInteger_ = maxInteger;
        EXP_UP =  Math.pow(10, maxInteger);
        nfBelow_ = createNumberFormat(NumberFormatKind.Below);
        nfNormal_ = createNumberFormat(NumberFormatKind.Normal);
        nfAbove_ = createNumberFormat(NumberFormatKind.Above);
    }

    private NumberFormat createNumberFormat(NumberFormatKind kind) {
        final String sharpByPrecision = Strings.repeat("#", maxFraction_); //if you do not use Guava library, replace with createSharp(precision);
        NumberFormat f = NumberFormat.getInstance(Locale.US);

        //Apply banker's rounding:  this is the rounding mode that statistically minimizes cumulative error when applied repeatedly over a sequence of calculations
        f.setRoundingMode(RoundingMode.HALF_EVEN);

        if (f instanceof DecimalFormat) {
            DecimalFormat df = (DecimalFormat) f;
            DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();

            //set group separator to space instead of comma

            //dfs.setGroupingSeparator(' ');

            //set Exponent symbol to minus 'e' instead of 'E'
            if (kind == NumberFormatKind.Above) {
                dfs.setExponentSeparator("e+"); //force to display the positive sign in the exponent part
            } else {
                dfs.setExponentSeparator("e");
            }

            df.setDecimalFormatSymbols(dfs);

            //use exponent format if v is out side of [EXP_DOWN,EXP_UP]

            if (kind == NumberFormatKind.Normal) {
                if (maxFraction_ == 0) {
                    df.applyPattern("#,##0");
                } else {
                    df.applyPattern("#,##0."+sharpByPrecision);
                }
            } else {
                if (maxFraction_ == 0) {
                    df.applyPattern("0E0");
                } else {
                    df.applyPattern("0."+sharpByPrecision+"E0");
                }
            }
        }
        return f;
    } 

    public String format(double v) {
        if (Double.isNaN(v)) {
            return "-";
        }
        if (v==0) {
            return "0"; 
        }
        final double absv = Math.abs(v);

        if (absv<EXP_DOWN) {
            return nfBelow_.format(v);
        }

        if (absv>EXP_UP) {
            return nfAbove_.format(v);
        }

        return nfNormal_.format(v);
    }

    /**
     * format and higlight the important part (integer part & exponent part) 
     */
    public String formatHtml(double v) {
        if (Double.isNaN(v)) {
            return "-";
        }
        return htmlize(format(v));
    }

    /**
     * This is the base alogrithm: create a instance of NumberFormat for the value, then format it. It should
     * not be used to format a great numbers of value 
     * 
     * We will never use this methode, it is here only to understanding the Algo principal:
     * 
     * format v to string. precision_ is numbers of digits after decimal. 
     * if EXP_DOWN <= abs(v) <= EXP_UP, display the normal format: 124.45678
     * otherwise display scientist format with: 1.2345e+30 
     * 
     * pre-condition: precision >= 1
     */
    @Deprecated
    public String formatInefficient(double v) {

        final String sharpByPrecision = Strings.repeat("#", maxFraction_); //if you do not use Guava library, replace with createSharp(precision);

        final double absv = Math.abs(v);

        NumberFormat f = NumberFormat.getInstance(Locale.US);

        //Apply banker's rounding:  this is the rounding mode that statistically minimizes cumulative error when applied repeatedly over a sequence of calculations
        f.setRoundingMode(RoundingMode.HALF_EVEN);

        if (f instanceof DecimalFormat) {
            DecimalFormat df = (DecimalFormat) f;
            DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();

            //set group separator to space instead of comma

            dfs.setGroupingSeparator(' ');

            //set Exponent symbol to minus 'e' instead of 'E'

            if (absv>EXP_UP) {
                dfs.setExponentSeparator("e+"); //force to display the positive sign in the exponent part
            } else {
                dfs.setExponentSeparator("e");
            }
            df.setDecimalFormatSymbols(dfs);

            //use exponent format if v is out side of [EXP_DOWN,EXP_UP]

            if (absv<EXP_DOWN || absv>EXP_UP) {
                df.applyPattern("0."+sharpByPrecision+"E0");
            } else {
                df.applyPattern("#,##0."+sharpByPrecision);
            }
        }
        return f.format(v);
    }

    /**
     * Convert "3.1416e+12" to "<b>3</b>.1416e<b>+12</b>"
     * It is a html format of a number which highlight the integer and exponent part
     */
    private static String htmlize(String s) {
        StringBuilder resu = new StringBuilder("<b>");
        int p1 = s.indexOf('.');

        if (p1>0) {
            resu.append(s.substring(0, p1));
            resu.append("</b>");
        } else {
            p1 = 0;
        }

        int p2 = s.lastIndexOf('e');
        if (p2>0) {
            resu.append(s.substring(p1, p2));
            resu.append("<b>");
            resu.append(s.substring(p2, s.length()));
            resu.append("</b>");
        } else {
            resu.append(s.substring(p1, s.length()));
            if (p1==0){
                resu.append("</b>");
            }
        }
        return resu.toString();
    }
}

দ্রষ্টব্য: আমি GUAVA লাইব্রেরি থেকে 2 ফাংশন ব্যবহার করেছি। আপনি যদি GUAVA ব্যবহার না করেন তবে নিজেই কোড করুন:

/**
 * Equivalent to Strings.repeat("#", n) of the Guava library: 
 */
private static String createSharp(int n) {
    StringBuilder sb = new StringBuilder(); 
    for (int i=0;i<n;i++) {
        sb.append('#');
    }
    return sb.toString();
}

1
আপনি যদি নির্ভুলতাটি জানেন তবে একটি বিগডিসিমাল ব্যবহার করুন। ডকস.ওরকল
জাভাজেস /

5

এই একজনটি কাজটি সুন্দরভাবে সম্পন্ন করবেন, আমি জানি বিষয়টি পুরানো, তবে আমি এদিকে না আসা পর্যন্ত আমি একই সমস্যা নিয়ে লড়াই করে যাচ্ছিলাম। আমি আশা করি যে কেউ এটি দরকারী হবে।

    public static String removeZero(double number) {
        DecimalFormat format = new DecimalFormat("#.###########");
        return format.format(number);
    }

5
new DecimalFormat("00.#").format(20.236)
//out =20.2

new DecimalFormat("00.#").format(2.236)
//out =02.2
  1. সংখ্যার সর্বনিম্ন সংখ্যার জন্য 0
  2. রেন্ডার # টি সংখ্যা

যদিও এটি প্রশ্নের সমাধান দিতে পারে, সম্প্রদায়টির উত্তর থেকে উপকার পেতে (এবং শিখতে) একটি সংক্ষিপ্ত ব্যাখ্যা যুক্ত করা ভাল অনুশীলন
ব্লারফাস

4
String s = String.valueof("your int variable");
while (g.endsWith("0") && g.contains(".")) {
    g = g.substring(0, g.length() - 1);
    if (g.endsWith("."))
    {
        g = g.substring(0, g.length() - 1);
    }
}

পরিবর্তে আপনার ডান থেকে প্রথম অ-শূন্য-অঙ্কের সন্ধান করা উচিত এবং তারপরে সাবস্ট্রিংটি ব্যবহার করুন (এবং অবশ্যই স্ট্রিংটিতে "।" রয়েছে কিনা তা যাচাই করে নিন)। এই পথে, আপনি পথে এতগুলি অস্থায়ী স্ট্রিং তৈরি করতে আসবেন না।
অ্যান্ড্রয়েড বিকাশকারী

3

দেরিতে উত্তর কিন্তু ...

আপনি বলেছিলেন যে আপনি আপনার সংখ্যাগুলি দ্বৈত প্রকারের সাথে সঞ্চয় করতে পছন্দ করেছেন । আমি মনে করি এটি সমস্যার মূল কারণ হতে পারে কারণ এটি আপনাকে দ্বিগুণে পূর্ণসংখ্যা সংরক্ষণ করতে বাধ্য করে (এবং সুতরাং মানটির প্রকৃতি সম্পর্কে প্রাথমিক তথ্য হারাতে পারে)। সংখ্যা বর্গের উদাহরণগুলিতে (ডাবল এবং পূর্ণসংখ্যার উভয়ের সুপারক্লাস) আপনার সংখ্যাগুলি সংরক্ষণ করার এবং প্রতিটি সংখ্যার সঠিক ফর্ম্যাট নির্ধারণ করার জন্য বহুবর্ষে নির্ভর?

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

উদাহরণ:

import java.util.ArrayList;
import java.util.List;

public class UseMixedNumbers {

    public static void main(String[] args) {
        List<Number> listNumbers = new ArrayList<Number>();

        listNumbers.add(232);
        listNumbers.add(0.18);
        listNumbers.add(1237875192);
        listNumbers.add(4.58);
        listNumbers.add(0);
        listNumbers.add(1.2345);

        for (Number number : listNumbers) {
            System.out.println(number);
        }
    }

}

নিম্নলিখিত আউটপুট উত্পাদন করবে:

232
0.18
1237875192
4.58
0
1.2345

জাভাস্ক্রিপ্ট উপায় দ্বারা একই পছন্দ করেছেন :)
পাইরোলিস্টিকাল

@ পাইরোলিস্টিকাল আপনি কি আপনার বক্তব্যকে আরও কিছুটা ব্যাখ্যা করতে পারেন? এটি আমার পক্ষে একেবারে পরিষ্কার নয় ... :)
স্পটড

2

এটিই আমি নিয়ে এসেছি:

  private static String format(final double dbl) {
    return dbl % 1 != 0 ? String.valueOf(dbl) : String.valueOf((int) dbl);
  }

সহজ একটি লাইনার, যদি সত্যিই প্রয়োজন হয় তবে কেবলমাত্র কাস্ট করুন


1
ফেলিক্স এডেলম্যান অন্য কোথাও যা বলেছে তার পুনরাবৃত্তি: এটি একটি লোকেল-স্বতন্ত্র স্ট্রিং তৈরি করবে, যা ব্যবহারকারীর পক্ষে সর্বদা উপযুক্ত নাও হতে পারে।
জেজে ব্রাউন

সুস্পষ্ট পয়েন্ট, আমার ব্যবহারের ক্ষেত্রে এটি কোনও সমস্যা ছিল না, আমি এখনই পুরোপুরি নিশ্চিত নই তবে আমি মনে করি যে কেউ স্ট্রিং.ফর্ম্যাট ব্যবহার করতে পারে (পছন্দসই লোকেলের সাথে) মান ওফের পরিবর্তে
কেইসার

2

দলবদ্ধকরণ, বৃত্তাকার, কোনও অপ্রয়োজনীয় জিরো (ডাবল) সহ ফর্ম্যাট মূল্য।

নিয়মাবলী:

  1. শেষে কোনও শূন্য নেই ( 2.0000 = 2; 1.0100000 = 1.01)
  2. বিন্দুর পরে সর্বোচ্চ দুটি অঙ্ক ( 2.010 = 2.01; 0.20 = 0.2)
  3. পয়েন্ট ( 1.994 = 1.99; 1.995 = 2; 1.006 = 1.01; 0.0006 -> 0) পরে দ্বিতীয় অঙ্কের পরে গোলাকার
  4. রিটার্ন 0( null/-0 = 0)
  5. যোগ $( = $56/-$56)
  6. দলবদ্ধকরণ ( 101101.02 = $101,101.02)

আরও উদাহরণ:

-99.985 = -$99.99

10 = $10

10.00 = $10

20.01000089 = $20.01

কোটলিনে ডাবল (অ্যান্ড্রয়েডে ব্যবহৃত কারণ) এর মজাদার এক্সটেনশন হিসাবে লেখা, তবে জাভাতে সহজেই রূপান্তরিত হতে পারে, কারণ জাভা ক্লাস ব্যবহার করা হয়েছিল।

/**
 * 23.0 -> $23
 *
 * 23.1 -> $23.1
 *
 * 23.01 -> $23.01
 *
 * 23.99 -> $23.99
 *
 * 23.999 -> $24
 *
 * -0.0 -> $0
 *
 * -5.00 -> -$5
 *
 * -5.019 -> -$5.02
 */
fun Double?.formatUserAsSum(): String {
    return when {
        this == null || this == 0.0 -> "$0"
        this % 1 == 0.0 -> DecimalFormat("$#,##0;-$#,##0").format(this)
        else -> DecimalFormat("$#,##0.##;-$#,##0.##").format(this)
    }
}

ব্যবহারবিধি:

var yourDouble: Double? = -20.00
println(yourDouble.formatUserAsSum()) // will print -$20

yourDouble = null
println(yourDouble.formatUserAsSum()) // will print $0

ডেসিমালফর্ম্যাট সম্পর্কে : https://docs.oracle.com/javase/6/docs/api/java/text/Decimal Format.html


1
public static String fmt(double d) {
    String val = Double.toString(d);
    String[] valArray = val.split("\\.");
    long valLong = 0;
    if(valArray.length == 2){
        valLong = Long.parseLong(valArray[1]);
    }
    if (valLong == 0)
        return String.format("%d", (long) d);
    else
        return String.format("%s", d);
}

আমাকে এই কারণটি ব্যবহার করতে d == (long)dহয়েছিল তা সোনার রিপোর্টে লঙ্ঘন করছিল


1
float price = 4.30;
DecimalFormat format = new DecimalFormat("0.##"); // Choose the number of decimal places to work with in case they are different than zero and zero value will be removed
format.setRoundingMode(RoundingMode.DOWN); // choose your Rounding Mode
System.out.println(format.format(price));

এটি কিছু পরীক্ষার ফলাফল:

4.30     => 4.3
4.39     => 4.39  // Choose format.setRoundingMode(RoundingMode.UP) to get 4.4
4.000000 => 4
4        => 4

1.23450000 সম্পর্কে কি?
অ্যালেক্স 78191

1.23450000 => 1.23
আহমেদ মিহৌব

0

এটি অর্জনের দুটি উপায় এখানে। প্রথমত, ছোট (এবং সম্ভবত আরও ভাল) উপায়:

public static String formatFloatToString(final float f)
  {
  final int i=(int)f;
  if(f==i)
    return Integer.toString(i);
  return Float.toString(f);
  }

এবং এখানে দীর্ঘ এবং সম্ভবত আরও খারাপ উপায়:

public static String formatFloatToString(final float f)
  {
  final String s=Float.toString(f);
  int dotPos=-1;
  for(int i=0;i<s.length();++i)
    if(s.charAt(i)=='.')
      {
      dotPos=i;
      break;
      }
  if(dotPos==-1)
    return s;
  int end=dotPos;
  for(int i=dotPos+1;i<s.length();++i)
    {
    final char c=s.charAt(i);
    if(c!='0')
      end=i+1;
    }
  final String result=s.substring(0,end);
  return result;
  }

1
কখনও কখনও, আপনি যখন জিনিসগুলিকে আরও সহজ করে
তোলেন তখন

1
আপনার সাধারণের সাথে শুরু করা উচিত এবং একবার আপনি নির্ধারণ করে ফেলেছিলেন যে আপনার পারফরম্যান্স সমস্যা রয়েছে, তারপরে এবং কেবল তখনই আপনার অনুকূলিত হওয়া উচিত। কোডটি মানুষের বারবার পড়ার জন্য। এটিকে দ্রুত চালানো গৌণ is যখনই সম্ভব সম্ভব স্ট্যান্ডার্ড এপিআই ব্যবহার না করে আপনি বাগগুলি প্রবর্তন করার সম্ভাবনা বেশি থাকেন এবং কেবল ভবিষ্যতে পরিবর্তন করা আরও কঠিন করে তোলে।
পাইরোলিস্টিকাল

3
আমি আপনার মত কোড লিখি তর্ক করব যে কোনও দ্রুত হতে চলেছে না। জেভিএম খুব স্মার্ট এবং আপনি যতক্ষণ না কিছু প্রচার করেন ততক্ষণ আপনি জানেন না যে কতটা দ্রুত বা ধীর। পারফরম্যান্স সমস্যাগুলি সনাক্ত হয়ে এটি ঠিক হয়ে যায় যখন এটি কোনও সমস্যা হয়ে যায়। আপনার অকাল সময়ের জন্য এটির জন্য অনুকূলিত করা উচিত নয়। লোকেরা পড়ার জন্য কোড লিখুন, আপনি কীভাবে কল্পনা করেন যে মেশিনটি এটি চালাচ্ছে। এটি একবার পারফরম্যান্স সমস্যা হয়ে গেলে, প্রোফাইলারের সাহায্যে কোডটি পুনরায় লিখুন।
পাইরোলিস্টিকাল

2
কোড ফর্ম্যাটিংয়ের উন্নতি করার জন্য অন্য কেউ উত্তর সম্পাদনা করেছেন। আমি অনুমোদনের জন্য কয়েক ডজন সম্পাদনা পর্যালোচনা করছি এবং তাদের সম্পাদনাগুলি এখানে অনুমোদনের জন্য যাচ্ছিলাম, তবে সম্পাদনাগুলি অসঙ্গত ছিল তাই আমি সেগুলি স্থির করেছিলাম। আমি পাঠ্য স্নিপেটগুলির ব্যাকরণও উন্নত করেছি।
স্টিভ বিনোস্কি

1
আমি বুঝতে পারছি না। আপনি যদি বলেছিলেন যে ফর্ম্যাটিংয়ের কোনও গুরুত্ব নেই, তবে কেন আপনি এটিটি ফিরিয়ে দেওয়ার জন্য সময় ব্যয় করলেন?
OrhanC1

0

কোটলিনের জন্য আপনি এক্সটেনশনটি ব্যবহার করতে পারেন:

fun Double.toPrettyString() =
    if(this - this.toLong() == 0.0)
        String.format("%d", this.toLong())
    else
        String.format("%s",this)

0

দশমিক শূন্য না হলে কেবলমাত্র দশমিক সংযোজনের একটি বিকল্প রয়েছে এমন আরও একটি উত্তর এখানে ।

   /**
     * Example: (isDecimalRequired = true)
     * d = 12345
     * returns 12,345.00
     *
     * d = 12345.12345
     * returns 12,345.12
     *
     * ==================================================
     * Example: (isDecimalRequired = false)
     * d = 12345
     * returns 12,345 (notice that there's no decimal since it's zero)
     *
     * d = 12345.12345
     * returns 12,345.12
     *
     * @param d float to format
     * @param zeroCount number decimal places
     * @param isDecimalRequired true if it will put decimal even zero,
     * false will remove the last decimal(s) if zero.
     */
    fun formatDecimal(d: Float? = 0f, zeroCount: Int, isDecimalRequired: Boolean = true): String {
        val zeros = StringBuilder()

        for (i in 0 until zeroCount) {
            zeros.append("0")
        }

        var pattern = "#,##0"

        if (zeros.isNotEmpty()) {
            pattern += ".$zeros"
        }

        val numberFormat = DecimalFormat(pattern)

        var formattedNumber = if (d != null) numberFormat.format(d) else "0"

        if (!isDecimalRequired) {
            for (i in formattedNumber.length downTo formattedNumber.length - zeroCount) {
                val number = formattedNumber[i - 1]

                if (number == '0' || number == '.') {
                    formattedNumber = formattedNumber.substring(0, formattedNumber.length - 1)
                } else {
                    break
                }
            }
        }

        return formattedNumber
    }

-1

এখানে একটি উত্তর যা আসলে কাজ করে (এখানে বিভিন্ন উত্তরের সংমিশ্রণ)

public static String removeTrailingZeros(double f)
{
    if(f == (int)f) {
        return String.format("%d", (int)f);
    }
    return String.format("%f", f).replaceAll("0*$", "");
}

1
আপনি পয়েন্ট প্রতিস্থাপন করেন নি, উদাহরণস্বরূপ, "100.0" "100" তে রূপান্তরিত হবে will
ভিন্সস্টাইলিং

যদি (f == (int) চ) এর যত্ন নেয়।
মার্টিন ক্লোসি

2
F = 9999999999.00.00 এ ব্যর্থ
দাউদ ইবনে কেরেম

-4

আমি জানি এটি একটি সত্যই পুরানো থ্রেড .. তবে আমি মনে করি এটি করার সর্বোত্তম উপায়টি নীচের মতো:

public class Test {

    public static void main(String args[]){
        System.out.println(String.format("%s something",new Double(3.456)));
        System.out.println(String.format("%s something",new Double(3.456234523452)));
        System.out.println(String.format("%s something",new Double(3.45)));
        System.out.println(String.format("%s something",new Double(3)));
    }
}

আউটপুট:

3.456 something
3.456234523452 something
3.45 something
3.0 something

একমাত্র ইস্যুটি সর্বশেষটি যেখানে .0 সরানো হয় না। তবে আপনি যদি এটির সাথে থাকতে সক্ষম হন তবে এটি সবচেয়ে ভাল কাজ করে। % .2f এটিকে শেষ 2 দশমিক অঙ্কের দিকে নিয়ে যাবে। সুতরাং ডেসিমালফর্ম্যাট হবে। আপনার যদি দশমিক সব জায়গাগুলির দরকার হয় তবে পিছনের শূন্যগুলি নয় তবে এটি সবচেয়ে ভাল কাজ করে।


2
"#। ##" ফর্ম্যাট সহ ডেসিমাল ফর্ম্যাট তাদের প্রয়োজন না থাকলে অতিরিক্ত 0 রাখবে না: System.out.println(new java.text.DecimalFormat("#.##").format(1.0005));মুদ্রণ করবে1
আলেকস জি

আমার বক্তব্য। আপনি যদি 0.0005 দেখতে চান তবে সেখানে কিছু আছে। আপনি এটি 2 দশমিক অঙ্কের বৃত্তাকার হবেন।
সেতু

ওপিতে জিজ্ঞাসা করা হচ্ছে কীভাবে ডাবলে সঞ্চিত পূর্ণসংখ্যার মানগুলি প্রিন্ট করতে হবে :)
আলেকস জি

-8
String s = "1.210000";
while (s.endsWith("0")){
    s = (s.substring(0, s.length() - 1));
}

এটি স্ট্রিংটি টেলিং 0-গুলি ছাড়বে।


1
এটি প্রশ্নের একটি ভাল সমাধান, যদি তারা কেবল শূন্যগুলি ফেলে দেওয়ার পিছনে আগ্রহী ছিল, তবে আপনি কীভাবে আপনার কোডটিকে দশমিক পয়েন্টটি ট্রিম করতে পরিবর্তন করবেন? যেমন "১।"
বকোয়ারো

29
সতর্কতা অবলম্বন করুন, আপনার সমাধান 1000 কে 1 তে রূপান্তর করবে যা ভুল।
আলেক্স জি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.