আমাকে কিছু ভাসমান বিন্দু ভেরিয়েবল গণনা করতে হবে এবং আমার সহকর্মী আমাকে আরও ব্যবহার BigDecimal
করার পরামর্শ দিচ্ছেন double
এটি যেহেতু এটি আরও সুনির্দিষ্ট হবে। তবে আমি জানতে চাই যে এটি কী এবং কীভাবে সবচেয়ে বেশি ব্যবহার করা যায় BigDecimal
?
আমাকে কিছু ভাসমান বিন্দু ভেরিয়েবল গণনা করতে হবে এবং আমার সহকর্মী আমাকে আরও ব্যবহার BigDecimal
করার পরামর্শ দিচ্ছেন double
এটি যেহেতু এটি আরও সুনির্দিষ্ট হবে। তবে আমি জানতে চাই যে এটি কী এবং কীভাবে সবচেয়ে বেশি ব্যবহার করা যায় BigDecimal
?
উত্তর:
একটি BigDecimal
সংখ্যার প্রতিনিধিত্ব একটি সঠিক উপায়। এ- Double
এর একটি নির্দিষ্ট নির্ভুলতা রয়েছে। দ্বিগুণ বিভিন্ন মাত্রার সাথে কাজ করার ফলে (বলুন d1=1000.0
এবং d2=0.001
) 0.001
পরিমাপের পার্থক্য এত বড় হওয়ায় সংক্ষিপ্তসার ঘটলে সামগ্রিকভাবে বাদ পড়তে পারে । BigDecimal
এই সঙ্গে ঘটবে না।
এর অসুবিধা BigDecimal
হ'ল এটি ধীর গতির এবং এ ভাবে অ্যালগরিদমগুলি প্রোগ্রাম করা ( ওভারলোড হওয়ার কারণে +
-
*
এবং /
না হওয়া) কিছুটা বেশি কঠিন ।
আপনি যদি অর্থের সাথে লেনদেন করছেন, বা নির্ভুলতা ব্যবহার করা আবশ্যক BigDecimal
। অন্যথায় Doubles
যথেষ্ট ভাল হতে থাকে।
আমি পড়া সুপারিশ করবেন javadoc এর BigDecimal
হিসাবে তারা জিনিষ ভাল চেয়ে আমি এখানে করতে বর্ণনা করি :)
if (Math.abs(loadPerServer - maxLoadPerServer) < 0.000001d) {
BigDecimal
", একটি ডাবলটির আরও "নির্ভুলতা" (আরও অঙ্ক) থাকবে।
আমার ইংরেজি ভাল নয় তাই আমি এখানে একটি সাধারণ উদাহরণ লিখব।
double a = 0.02;
double b = 0.03;
double c = b - a;
System.out.println(c);
BigDecimal _a = new BigDecimal("0.02");
BigDecimal _b = new BigDecimal("0.03");
BigDecimal _c = _b.subtract(_a);
System.out.println(_c);
প্রোগ্রাম আউটপুট:
0.009999999999999998
0.01
কেউ এখনও ডাবল ব্যবহার করতে চান? ;)
System.out.println(0.003f - 0.002f);
অপ্রচলিত : বিগডিসিমাল সঠিক:System.out.println(new BigDecimal("0.003").subtract(new BigDecimal("0.002")));
ডাবল থেকে দুটি প্রধান পার্থক্য রয়েছে:
মুদ্রা গণনার জন্য আপনার বিগডিসিমাল ব্যবহার করার কারণ এটি নয় যে এটি কোনও সংখ্যাকে উপস্থাপন করতে পারে, তবে এটি দশমিক ধারণায় প্রতিনিধিত্ব করা যায় এমন সমস্ত সংখ্যাকে উপস্থাপন করতে পারে এবং আর্থিক জগতের কার্যত সমস্ত সংখ্যা অন্তর্ভুক্ত করে (আপনি কখনই স্থানান্তর করেন না 1/3 $ কারো প্রতি).
আপনি যদি 1 / 7
দশমিক মান হিসাবে ভগ্নাংশের মান লিখেন
1/7 = 0.142857142857142857142857142857142857142857...
অসীম অনুক্রম সঙ্গে 142857
। যেহেতু আপনি কেবল অঙ্কের একটি সীমাবদ্ধ সংখ্যা লিখতে পারেন তাই আপনি অনিবার্যভাবে একটি বৃত্তাকার (বা ছাঁটাই) ত্রুটি প্রবর্তন করবেন।
ভগ্নাংশের সাথে বাইনারি সংখ্যার মতো 1/10
বা 1/100
প্রকাশিত সংখ্যাগুলির দশমিক বিন্দুর পরেও অসীম সংখ্যা থাকে:
1/10 = binary 0.0001100110011001100110011001100110...
Doubles
বাইনারি হিসাবে স্টোরের মানগুলি এবং তাই কোনও গাণিতিক না করে দশমিক সংখ্যাটিকে বাইনারি সংখ্যায় রূপান্তর করে কেবল ত্রুটি প্রবর্তন করতে পারে।
BigDecimal
অন্যদিকে দশমিক সংখ্যা (যেমন ) প্রতিটি দশমিক অঙ্ক যেমন থাকে তেমন সংরক্ষণ করুন। এর অর্থ হ'ল একটি দশমিক প্রকারটি বাইনারি ভাসমান বিন্দু বা সাধারণ অর্থে স্থির বিন্দুর ধরণের চেয়ে বেশি সুনির্দিষ্ট নয় ( 1/7
তবে এটি নির্ভুলতার ক্ষতি ছাড়াই সঞ্চয় করতে পারে না ) তবে এটি সংখ্যার জন্য আরও সঠিক যা দশমিক সংখ্যা হিসাবে সীমাবদ্ধ সংখ্যা রয়েছে অর্থ গণনার ক্ষেত্রে প্রায়শই কেস হয়।
জাভা এর BigDecimal
অতিরিক্ত সুবিধা রয়েছে যে এটি কেবলমাত্র উপলব্ধ স্মৃতি দ্বারা সীমাবদ্ধ দশমিক পয়েন্টের উভয় পক্ষের একটি স্বেচ্ছাসেবী (তবে সসীম) সংখ্যা থাকতে পারে।
বিগডিসিমাল হ'ল ওরাকলের স্বেচ্ছাসেবী-নির্ভুলতার সংখ্যাসূচক গ্রন্থাগার। বিগডিসিমাল জাভা ভাষার অংশ এবং এটি আর্থিক থেকে শুরু করে বৈজ্ঞানিক পর্যন্ত বিভিন্ন অ্যাপ্লিকেশনের জন্য কার্যকর (সেখানকার প্রকারের am)।
নির্দিষ্ট গণনার জন্য ডাবল ব্যবহারে কোনও ভুল নেই। মনে করুন, তবে আপনি ম্যাথ গণনা করতে চেয়েছিলেন i পাই * ম্যাথ.পি / 6, অর্থাৎ, দুটি আসল যুক্তির জন্য রিমন জেটা ফাংশনের মান (আমি বর্তমানে একটি প্রকল্প যা নিয়ে কাজ করছি) ভাসমান-পয়েন্ট বিভাগটি আপনাকে রাউন্ডিং ত্রুটির বেদনাদায়ক সমস্যার সাথে উপস্থাপন করে।
অন্যদিকে বিগডিসিমালে স্বেচ্ছাসেবীর নির্ভুলতার জন্য এক্সপ্রেশন গণনা করার জন্য অনেকগুলি বিকল্প অন্তর্ভুক্ত করে। +, *, এবং / বিগডিসিমাল জাভা ওয়ার্ল্ডে "স্থান নিন" এর নীচে ওরাকল ডকুমেন্টেশনে বর্ণিত পদ্ধতিগুলি যুক্ত করুন, গুণ করুন এবং ভাগ করুন:
http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html
তুলনামূলক পদ্ধতিটি যখন এবং লুপগুলির জন্য বিশেষত কার্যকর।
বিগডিসিমালের জন্য আপনার কনস্ট্রাক্টর ব্যবহারের ক্ষেত্রে অবশ্যই সাবধান হন। স্ট্রিং কনস্ট্রাক্টর অনেক ক্ষেত্রেই খুব কার্যকর। উদাহরণস্বরূপ, কোড
বিগডিসিমাল অনেথার্ড = নতুন বিগডিসিমাল ("0.33333333333");
সেই অসীম-পুনরাবৃত্তি সংখ্যাকে নির্ভুলতার নির্দিষ্ট ডিগ্রিতে প্রতিনিধিত্ব করতে 1/3 এর স্ট্রিং প্রতিনিধিত্ব ব্যবহার করে। রাউন্ড-অফ ত্রুটিটি সম্ভবত জেভিএম-এর ভিতরে কোথাও এত গভীর ছিল যে রাউন্ড-অফ ত্রুটিগুলি আপনার বেশিরভাগ ব্যবহারিক গণনাগুলিকে বিরক্ত করবে না। আমি অবশ্য ব্যক্তিগত অভিজ্ঞতা থেকে দেখেছি, তবে গোল চক্কর মেরে উঠছে। ওরেটল ডকুমেন্টেশন থেকে দেখা যায়, এই সম্পর্কিত ক্ষেত্রে সেটস্কেল পদ্ধতিটি গুরুত্বপূর্ণ।
/* * Portions Copyright IBM Corporation, 2001. All Rights Reserved. */
আপনি যদি গণনা নিয়ে কাজ করছেন, আপনার কীভাবে গণনা করা উচিত এবং কোন নির্ভুলতা আপনার ব্যবহার করা উচিত সে সম্পর্কে আইন রয়েছে। যদি আপনি ব্যর্থ হন তবে আপনি কিছু অবৈধ কাজ করবেন। একমাত্র আসল কারণ হ'ল দশমিক মামলার বিট উপস্থাপনা সুনির্দিষ্ট নয়। যেমন তুলসী সহজভাবে বলা যায়, একটি উদাহরণ সর্বোত্তম ব্যাখ্যা। কেবল তার উদাহরণ পরিপূরক করতে, এখানে যা ঘটেছিল তা এখানে:
static void theDoubleProblem1() {
double d1 = 0.3;
double d2 = 0.2;
System.out.println("Double:\t 0,3 - 0,2 = " + (d1 - d2));
float f1 = 0.3f;
float f2 = 0.2f;
System.out.println("Float:\t 0,3 - 0,2 = " + (f1 - f2));
BigDecimal bd1 = new BigDecimal("0.3");
BigDecimal bd2 = new BigDecimal("0.2");
System.out.println("BigDec:\t 0,3 - 0,2 = " + (bd1.subtract(bd2)));
}
আউটপুট:
Double: 0,3 - 0,2 = 0.09999999999999998
Float: 0,3 - 0,2 = 0.10000001
BigDec: 0,3 - 0,2 = 0.1
এছাড়াও আমাদের তা আছে:
static void theDoubleProblem2() {
double d1 = 10;
double d2 = 3;
System.out.println("Double:\t 10 / 3 = " + (d1 / d2));
float f1 = 10f;
float f2 = 3f;
System.out.println("Float:\t 10 / 3 = " + (f1 / f2));
// Exception!
BigDecimal bd3 = new BigDecimal("10");
BigDecimal bd4 = new BigDecimal("3");
System.out.println("BigDec:\t 10 / 3 = " + (bd3.divide(bd4)));
}
আমাদের আউটপুট দেয়:
Double: 10 / 3 = 3.3333333333333335
Float: 10 / 3 = 3.3333333
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion
কিন্তু:
static void theDoubleProblem2() {
BigDecimal bd3 = new BigDecimal("10");
BigDecimal bd4 = new BigDecimal("3");
System.out.println("BigDec:\t 10 / 3 = " + (bd3.divide(bd4, 4, BigDecimal.ROUND_HALF_UP)));
}
আউটপুট আছে:
BigDec: 10 / 3 = 3.3333