ইন-গেম মুদ্রার জন্য আমার কোন ডেটা-টাইপ ব্যবহার করা উচিত?


96

একটি সাধারণ ব্যবসায়িক সিমুলেশন গেমে (জাভা + স্লিক 2 ডি তে অন্তর্নির্মিত) কোনও খেলোয়াড়ের বর্তমান অর্থের পরিমাণটি একটি floatবা একটি হিসাবে সংরক্ষণ করা উচিত int, বা অন্য কিছু?

আমার ব্যবহারের ক্ষেত্রে, বেশিরভাগ লেনদেনগুলি সেন্ট (will 0.50, $ 1.20 ইত্যাদি) ব্যবহার করবে এবং সাধারণ সুদের হারের গণনা জড়িত থাকবে involved

আমি লোককে বলেছি যে আপনাকে কখনও floatমুদ্রার জন্য ব্যবহার করা উচিত নয় , পাশাপাশি লোকেরা বলে যে আপনার কখনও intমুদ্রার জন্য ব্যবহার করা উচিত নয় । আমার মনে হয় যে intকোনও প্রয়োজনীয় শতাংশের গণনা আমার ব্যবহার করা উচিত round আমার কী ব্যবহার করা উচিত?


2
এই প্রশ্নটি স্ট্যাকওভারফ্লোতে আলোচনা করা হয়েছিল। মনে হচ্ছে বিগডিসিমাল সম্ভবত যাওয়ার উপায়। stackoverflow.com/questions/285680/…
অ্যাডে মিলার

2
জাভাতে কি Currencyডেলফির মতো ধরণ নেই, যা ভাসমান-পয়েন্টের অন্তর্নিহিত যথার্থ সমস্যাগুলি ছাড়াই দশমিক গণিত দেওয়ার জন্য স্কেলড ফিক্সড পয়েন্ট ম্যাথ ব্যবহার করে?
ম্যাসন হুইলারের

1
এটা খেলা। অ্যাকাউন্টিং আপনাকে গোল গোল পয়সের জন্য লঞ্চ করে না এবং এইভাবে মুদ্রার জন্য ভাসমান পয়েন্ট ব্যবহার করার বিরুদ্ধে সাধারণ কারণগুলি গুরুত্বপূর্ণ নয়।
Loren Pechtel

@ মেসনওহিলার: জাভাতে BigDecimalএই জাতীয় সমস্যা রয়েছে।
মার্টিন শ্র্রেডার

উত্তর:


92

আপনি intসেন্ট ব্যবহার করে সমস্ত কিছু বিবেচনা করতে পারেন । 20 1.20 মাত্র 120 সেন্ট। ডিসপ্লেতে, আপনি দশমিকটি যেখানে রাখেন সেখানে রেখে দেন।

সুদের গণনাগুলি কেবল ছাঁটাই বা গোল করা হবে। সুতরাং

newAmt = round( 120 cents * 1.04 ) = round( 124.8 ) = 125 cents

এইভাবে আপনার কাছে সবসময় অগোছালো দশমিক থাকে না। আপনি নিজের ব্যাঙ্ক অ্যাকাউন্টে অর্থহীন (পর্বতমালার কারণে) অ্যাকাউন্ট না করে ধনী হতে পারেন


3
আপনি যদি ব্যবহার roundকরেন তবে নামিয়ে দেওয়ার কোনও সত্য কারণ নেই int, আছে কি?
সাম হোচেভার

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

+1 টি। আমার গেমটি যাওয়ার জন্য ভাল উপায় বলে মনে হচ্ছে। আমি নিজেই কালিগুলিকে গোল করে নিয়ে যাব এবং সমস্ত ভাসমান সমস্যা থেকে দূরে থাকব।
লুকাস তুলিও

কেবলমাত্র একটি দাবি অস্বীকার: আমি এইটির সঠিক উত্তরটি পরিবর্তন করেছি কারণ এটি আমার ব্যবহার হিসাবে শেষ হয়েছিল। এটি অনেক সহজ এবং এই জাতীয় সরল গেমের প্রসঙ্গে, অ্যাকাউন্টবিহীন দশমিকগুলি আসলেই কিছু যায় আসে না।
লুকাস তুলিও

3
তবে, বেসিস পয়েন্টগুলি সেন্ট নয় (যেখানে 100 বেসিস পয়েন্ট = 1 শতাংশ) 100 এর পরিবর্তে 10,000 এর ফ্যাক্টর ব্যবহার করুন all সমস্ত আর্থিক, ব্যাংকিং বা অ্যাকাউন্টিং অ্যাপ্লিকেশনগুলির জন্য এটি জিএএপি দ্বারা প্রয়োজনীয়।
পিটার জেরকেন্স

66

ঠিক আছে, আমি লাফিয়ে যাব।

আমার পরামর্শ: এটি একটি খেলা। এটি সহজ এবং ব্যবহার করুন double

আমার যুক্তি এখানে:

  • floatলক্ষ লক্ষগুলিতে ইউনিট যুক্ত করার সময় উপস্থিত একটি যথার্থ সমস্যা রয়েছে, সুতরাং এটি সৌম্য হলেও, আমি এই ধরণের এড়াতে চাই। doubleকেবল কুইন্টিলন (এক বিলিয়ন বিলিয়ন) এর আশপাশে সমস্যা পেতে শুরু করে।
  • যেহেতু আপনার সুদের হার হতে চলেছে তাই আপনার যেভাবেই তাত্ত্বিক অসীম নির্ভুলতার প্রয়োজন হবে: 4% সুদের হারের সাথে, $ 100 হয়ে যাবে 104 ডলার, তারপরে .1 108.16, তারপরে 2 112.4864 ইত্যাদি। এটি তোলে intএবং longঅকেজো কারণ আপনি কোথায় থামবেন জানেন না with দশমিক
  • BigDecimalআপনি নির্বিচারে নির্ভুলতা দেবেন তবে বেদনাদায়ক ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে। রাউন্ডিং বিধিগুলি কী কী? আপনি কোথায় থামবেন তা বেছে নিন? এর চেয়ে বেশি স্পষ্টতা বিট থাকার কি মূল্য double? আমি বিশ্বাস করি না।

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

ব্যবহারিক উদাহরণ

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

সংরক্ষণ করা : যদি আপনার বেস ইউনিটটি শতাংশ হয় তবে আপনি মানগুলি সংরক্ষণের সময় সম্ভবত নিকটতম শতাংশে গোল করতে চান:

void SetValue(double v) { m_value = round(v * 100.0) / 100.0; }

এই পদ্ধতিটি অবলম্বন করার সময় আপনি পুরোপুরি কোনও গোলটে সমস্যা পাবেন না যা আপনার কোনও পূর্ণসংখ্যার ধরণেরও নয়।

পুনরুদ্ধার করা : সমস্ত গণনা সরাসরি ডাবল মানগুলিতে করা যায়, কোনও রূপান্তর ছাড়াই:

double value = data.GetValue();
value = value / 3.0 * 12.0;
[...]
data.SetValue(value);

নোট করুন যে উপরের কোডটি আপনি যদি এটির doubleসাথে প্রতিস্থাপন করেন তা কাজ করে না int64_t: তথ্যের সম্ভাব্য ক্ষতির সাথে এতে একটি অন্তর্নিহিত রূপান্তর হবে double, তারপরে এটি কেটে নেওয়া হবে। ডেটা.গেটভ্যালুint64_t ()

তুলনা করা : ভাসমান-পয়েন্টের ধরণের সাথে সঠিকভাবে তুলনা করা এক জিনিস। আমি এই তুলনায় একটি তুলনা পদ্ধতি ব্যবহার করার পরামর্শ দিচ্ছি:

/* Are values equal to a tenth of a cent? */
bool AreCurrencyValuesEqual(double a, double b) { return abs(a - b) < 0.001; }

রাউন্ডিং ফর্সা

মনে করুন আপনার অ্যাকাউন্টে 4% সুদ নিয়ে $ 9.99 রয়েছে। খেলোয়াড়ের কত আয় করা উচিত? পূর্ণসংখ্যার বৃত্তাকারে আপনি $ 0.03 পান; ভাসমান-পয়েন্টের বৃত্তাকার সাথে আপনি 0.04 ডলার পাবেন। আমি বিশ্বাস করি দ্বিতীয়টি আরও সুষ্ঠু।


4
+1 টি। আমি কেবল একটি স্পষ্টতা যোগ করতে চাই, আর্থিক প্রয়োগ যেমন নির্দিষ্ট পূর্বনির্ধারিত প্রয়োজনীয়তার সাথে খাপ খায়, তেমনি বৃত্তাকার অ্যালগরিদমও হয় does গেমটি যদি ক্যাসিনো এক হয় তবে এটি একই মানের সাথে খাপ খায় এবং তারপরে ডাবল কোনও বিকল্প নয়।
Ivaylo স্লাভভ

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

10
আমি এই উত্তরের সাথে একমত নই। রাউন্ডিংয়ের সমস্যাগুলি উপস্থিত হয় এবং যদি সেগুলি নীচে যায় এবং আপনি যদি কোনও অতিরিক্ত রাউন্ডিং ব্যবহার না করেন তবে হঠাৎ করে $ 1.00 ডলারে পরিণত হতে পারে। 0.99। তবে সবচেয়ে গুরুত্বপূর্ণ, নির্বিচারে যথার্থ দশমিকগুলি ধীর হওয়া (প্রায়) সম্পূর্ণ অপ্রাসঙ্গিক। আমরা প্রায় 2013 সালে এসেছি এবং আপনি যদি হাজার হাজার অঙ্ক সহ কয়েক মিলিয়ন সংখ্যার উপরে বড় ফ্যাক্টরীকরণ, ট্রিগ স্টাফ বা লগারিদম না করে থাকেন তবে আপনি কখনও কার্য সম্পাদন করতে পারেন না will যাইহোক, সহজ সর্বদা সেরা, তাই আমার প্রস্তাবটি হ'ল সমস্ত সংখ্যা সেন্ট হিসাবে সংরক্ষণ করুন। এইভাবে তারা সবাই int_64tএস।
পান্ডা পাইজামা

8
@ সাম গতবার আমি আমার ব্যাংক অ্যাকাউন্টটি চেক করেছি, আমার ব্যালেন্স .0000000000000001 এ শেষ হয়নি। বাস্তব মুদ্রা সিস্টেমগুলি অবশ্যই বিভাজক এককগুলির সাথে কাজ করে এবং এটি সঠিকভাবে পূর্ণসংখ্যার সাথে উপস্থাপন করে। যদি আপনাকে অবশ্যই মুদ্রা বিভাগগুলি সঠিকভাবে করতে হয় (যা প্রকৃত আর্থিক জগতের মধ্যে আসলে তেমন সাধারণ নয়), আপনার অর্থগুলি ক্ষতিগ্রস্থ না হওয়ার জন্য আপনাকে সেগুলি করতে হবে। উদাহরণস্বরূপ 10/3 = 3+3+4বা 10/3 = 3+3+3 (+1)। অন্যান্য সমস্ত ক্রিয়াকলাপের জন্য পূর্ণসংখ্যক পুরোপুরি কাজ করে, ভাসমান পয়েন্টের বিপরীতে যা কোনও ক্রিয়াকলাপের ক্ষেত্রে গোলাকৃতি সমস্যা পেতে পারে।
পান্ডা পাইজামা

2
@ সামহোসেভর 999 * 4/100। নিয়ম দ্বারা নির্ধারিত নয় যেখানে ধরে নেওয়া সমস্ত রাউন্ডিং ব্যাংকগুলির পক্ষে করা হবে।
ড্যান নীলি

21

জাভাতে ভাসমান পয়েন্টের ধরণগুলি ( float, double) মুখ্যগুলির জন্য একটি প্রধান কারণের জন্য ভাল উপস্থাপনা নয় - রাউন্ডিংয়ে একটি মেশিন ত্রুটি রয়েছে। একটি সহজ হিসাব একটি পূর্ণ সংখ্যা ফেরৎ এমনকি যদি - মত 12.0/2(6.0), ফ্লোটিং পয়েন্ট হতে পারে ভুলভাবে বৃত্তাকার এটা (মেমরি এই ধরনের নির্দিষ্ট উপস্থাপনা হউক না কেন কারণে) হিসাবে 6.0000000000001বা 5.999999999999998বা অনুরূপ। এটি প্রসেসরে ঘটে এমন নির্দিষ্ট মেশিন রাউন্ডিংয়ের ফলাফল এবং এটি গণনা করা কম্পিউটারের কাছে এটি অনন্য। সাধারণত, এই মানগুলি পরিচালনা করতে খুব কমই সমস্যা হয়, কারণ ত্রুটিটি যথেষ্ট অবহেলা, তবে এটি ব্যবহারকারীর কাছে প্রদর্শন করার জন্য এটি একটি ব্যথা।

এর সম্ভাব্য সমাধান হ'ল ফ্লোটিং পয়েন্ট ডেটা টাইপের কাস্টম বাস্তবায়ন, যেমন ব্যবহার করা BigDecimal। এটি আরও ভাল গণনা প্রক্রিয়াগুলিকে সমর্থন করে যা মেশিন নির্দিষ্ট না হওয়ার জন্য বৃত্তাকার ত্রুটিগুলি কমপক্ষে পৃথক করে তবে কার্যকারিতার দিক থেকে ধীর হয়।

আপনার যদি উচ্চ উত্পাদনশীলতার প্রয়োজন হয় তবে আপনি সাধারণ প্রকারের সাথে আরও ভাল লেগে থাকুন। আপনি যদি গুরুত্বপূর্ণ আর্থিক ডেটা নিয়ে কাজ করেন এবং প্রতিটি শতাংশ গুরুত্বপূর্ণ হয় (ফরেক্স অ্যাপ্লিকেশন, বা কিছু ক্যাসিনো গেমের মতো) তবে আমি আপনাকে ব্যবহার করার পরামর্শ দিই Longবা longLongআপনাকে বড় পরিমাণে এবং ভাল নির্ভুলতা পরিচালনা করতে দেয়। কেবলমাত্র ধরুন, আপনার দশমিক পয়েন্টের পরে 4 সংখ্যার দরকার আছে, আপনার যা দরকার তা হল 10000 দ্বারা পরিমাণটি বৃদ্ধি করা on অন-লাইন ক্যাসিনো গেমগুলি বিকাশের অভিজ্ঞতা থাকার কারণে, আমি Longপ্রায়শই সেন্টে অর্থ উপস্থাপন করতে ব্যবহৃত হতে দেখি । ফরেক্স অ্যাপ্লিকেশনগুলিতে, নির্ভুলতা আরও গুরুত্বপূর্ণ, সুতরাং আপনার আরও বৃহত্তর গুণক লাগবে - তবুও পুরো সংখ্যাগুলি মেশিন রাউন্ডিং ইস্যু থেকে মুক্ত থাকে (অবশ্যই ম্যানুয়াল রাউন্ডিং 3/2 এর মতো আপনাকে নিজেরাই পরিচালনা করা উচিত)।

একটি গ্রহণযোগ্য বিকল্প হ'ল স্ট্যান্ডার্ড ভাসমান পয়েন্টের ধরণগুলি ব্যবহার করা - Floatএবং Doubleযদি পারফরম্যান্স শতকের শতভাগের থেকে নির্ভুলতার চেয়ে বেশি গুরুত্বপূর্ণ। তারপরে, আপনার ডিসপ্লে লজিকের জন্য আপনার কেবলমাত্র পূর্বনির্ধারিত ফর্ম্যাটিংটি ব্যবহার করা দরকার , যাতে সম্ভাব্য মেশিনের রাউন্ডিংয়ের কদর্য ব্যবহারকারীর কাছে না যায়।


4
+1 বিশদ: "কেবলমাত্র অনুমান করুন যে আপনার প্রয়োজন দশমিক পয়েন্টের পরে 4 অঙ্ক, আপনার যা দরকার তা হ'ল পরিমাণকে 1000 দ্বারা গুণান" " -> এটাকে নির্দিষ্ট পয়েন্ট বলা হয়।
লরেন্ট কুইভিডু

1
@ স্যাম, নম্বরগুলি উদাহরণের অংশ হিসাবে সরবরাহ করা হয়েছিল। তবুও, আমি ব্যক্তিগতভাবে এমন সাধারণ সংখ্যার সাথে অদ্ভুত ফলাফল দেখেছি, তবে এটি ঘন ঘন দৃশ্য নয়। যখন ভাসমান পয়েন্ট খেলতে আসে, সম্ভবত এটি সম্ভবত হওয়ার সম্ভাবনা বেশি তবে স্পষ্ট হওয়ার সম্ভাবনা বেশি নয়
Ivaylo Slavov

2
@ আইভায়লো স্লাভভ, আমি আপনার সাথে একমত আমার উত্তরে আমি কেবল আমার মতামত তৈরি করেছি। আমি আলোচনা করতে পছন্দ করি এবং সঠিক জিনিসটি গ্রহণ করার ইচ্ছা পোষণ করি। আপনার মতামত জন্য ধন্যবাদ। :)
মোঃ মাহবুবুর রহমান

1
@ সামোহেশ্বর: এই যুক্তি সব ক্ষেত্রে কার্যকর হয় না। দেখুন: ideone.com/nI2ZOK
সমুরসা

1
@ সামোহেশ্বর: এটিরও গ্যারান্টি নেই। এখনও পুরো সংখ্যা রয়েছে এমন সীমার মধ্যে থাকা সংখ্যাগুলি প্রথম বিভাগে ত্রুটি জমা করতে শুরু করে: আদর্শোন
কেবিআর i

17

জন্য ক্ষুদ্র খেলা এবং যেখানে প্রক্রিয়া গতি, মেমরি গুরুত্বপূর্ণ বিষয় (স্পষ্টতা বা গণিত সহ-প্রসেসরের সাথে কাজ বেদনাদায়ক ধীর করতে পারেন কারণে), সেখানে দ্বিগুণ যথেষ্ট।

তবে বড় আকারের গেমগুলির জন্য (উদাহরণস্বরূপ, সামাজিক গেমস) এবং যেখানে প্রক্রিয়াটির গতি, মেমরি সীমাবদ্ধ নয়, সেখানে বিগডিসিমাল আরও ভাল। কারণ এখানে,

  • আর্থিক হিসাবের জন্য int বা দীর্ঘ।
  • ভাসমান এবং ডাবলগুলি বেশিরভাগ বেস 10 আসল সংখ্যাকে সঠিকভাবে উপস্থাপন করতে পারে না।

সম্পদ:

Https://stackoverflow.com থেকে

কারণ ফ্লোটস এবং ডাবলগুলি বেশিরভাগ বেস 10 আসল সংখ্যাকে সঠিকভাবে উপস্থাপন করতে পারে না।

কোনও আইইইই -৫ 75৪ ভাসমান-পয়েন্ট নম্বরটি কীভাবে এটি কাজ করে: এটি সাইনটির জন্য কিছুটা উত্সাহিত করে, কোনও খাঁটি সঞ্চয় করার জন্য কয়েকটি বিট এবং বাকীটি প্রকৃত ভগ্নাংশের জন্য। এটি সংখ্যায় 1.45 * 10 ^ 4 এর মতো আকারে প্রতিনিধিত্ব করে; বেসটি 10 ​​হওয়ার পরিবর্তে এটি দুটি।

সমস্ত বাস্তব দশমিক সংখ্যা দেখা যায়, দশজনের একটি শক্তির সঠিক ভগ্নাংশ হিসাবে। উদাহরণস্বরূপ, 10.45 আসলে 1045/10 ^ 2 is এবং ঠিক যেমন কিছু ভগ্নাংশ দশটির শক্তির ভগ্নাংশ হিসাবে ঠিক প্রতিনিধিত্ব করতে পারে না (যেমন 1/3 মনে আসে), তাদের মধ্যে কিছুটিকে দুটি শক্তির ভগ্নাংশ হিসাবে ঠিক উপস্থাপন করা যায় না। একটি সাধারণ উদাহরণ হিসাবে, আপনি কেবল একটি ভাসমান-পয়েন্ট ভেরিয়েবলের মধ্যে 0.1 সঞ্চয় করতে পারবেন না। আপনি নিকটতম প্রতিনিধিত্বমূলক মান পাবেন, যা 0.0999999999999999996 এর মতো কিছু এবং সফ্টওয়্যার এটি প্রদর্শিত হওয়ার সময় এটি 0.1 এ গোল করবে।

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

ব্লচ, জে।, কার্যকর জাভা, ২ য় সংস্করণ, আইটেম 48:

The float and double types are particularly ill-suited for 

আর্থিক হিসাব কারণ 0.1 (বা দশের যে কোনও নেতিবাচক শক্তি) প্রতিনিধিত্ব করা অসম্ভব ভাসা হিসাবে বা ঠিক দ্বিগুণ।

For example, suppose you have $1.03 and you spend 42c. How much money do you have left?

System.out.println(1.03 - .42);

prints out 0.6100000000000001.

The right way to solve this problem is to use BigDecimal, 

আর্থিক হিসাবের জন্য int বা দীর্ঘ।

একবার দেখুন


আমি কেবল সেই অংশের সাথেই একমত নই যে দীর্ঘ গণনার জন্য উপযুক্ত। আমার বাস্তব জীবনের অভিজ্ঞতায় এটি ভাল নির্ভুলতা এবং প্রচুর পরিমাণে অর্থ পরিচালনা করতে যথেষ্ট প্রমাণিত হয়েছে। হ্যাঁ, এটি ব্যবহার করা কিছুটা জটিল হতে পারে তবে এটি দুটি গুরুত্বপূর্ণ পয়েন্টে বিগডিসিমালকে পরাজিত করে - 1) এটি দ্রুততর (বিগডিসিমাল সফ্টওয়্যার রাউন্ডিং ব্যবহার করে, যা বিল্ট-ইন সিপিইউ রাউন্ডটি ফ্লোট / ডাবল ব্যবহৃত হয়) এবং 2) বিগডিসিমাল নির্ভুলতা না হারিয়ে ডাটাবেসে অবিচল থাকা আরও কঠিন - সমস্ত ডাটাবেস যেমন 'কাস্টম' টাইপ সমর্থন করে না। সমস্ত বড় ডেটাবেসগুলিতে লং সুপরিচিত এবং ব্যাপকভাবে সমর্থিত।
Ivaylo স্লাভভ

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

একই সমস্যার জন্য আলাদা দৃষ্টিভঙ্গি দেওয়ার জন্য ক্ষমা চাওয়ার দরকার নেই :)
Ivaylo Slavov

2
@ আইভায়লো স্লাভভ, আমি আপনার সাথে একমত আমার উত্তরে আমি কেবল আমার মতামত তৈরি করেছি। আমি আলোচনা করতে পছন্দ করি এবং সঠিক জিনিসটি গ্রহণ করার ইচ্ছা পোষণ করি। আপনার মতামত জন্য ধন্যবাদ। :)
মোঃ মাহবুবুর রহমান

এই সাইটের উদ্দেশ্য বিষয়গুলি স্পষ্ট করা এবং নির্দিষ্ট দৃশ্যের উপর নির্ভর করে ওপিকে সঠিক সিদ্ধান্ত নিতে সহায়তা করা। প্রক্রিয়াটি দ্রুততর করতে আমরা যা করতে পারি তা হ'ল :)
Ivaylo Slavov

13

আপনি নিজের মুদ্রাকে সঞ্চয় করতে longএবং কমপক্ষে ব্যাকআপ হিসাবে নিজের মুদ্রার গণনা করতে চান double। আপনি চান যে সমস্ত লেনদেন যেমন হয় long

আপনি longযেভাবে আপনার মুদ্রা সঞ্চয় করতে চান তা হ'ল আপনি কোনও মুদ্রা হারাতে চান না।

ধরা যাক আপনি একটি ব্যবহার করেন double, এবং আপনার কোনও অর্থ নেই। কেউ আপনাকে তিনটি ডাইম দেয় এবং তারপরে সেগুলি আবার নিয়ে যায়।

You:       0.1+0.1+0.1-0.1-0.1-0.1 = 2.7755575615628914E-17

ঠিক আছে, এটি এত সুন্দর নয়। হতে পারে যে 10 ডলারযুক্ত কেউ প্রথমে আপনাকে তিনটি ডাইম দিয়ে এবং তারপরে অন্য কাউকে 70 9.70 দিয়ে তাদের ভাগ্য দূরে দিতে চায়।

Them: 10.0-0.1-0.1-0.1-9.7 = 1.7763568394002505E-15

এবং তারপরে আপনি তাদের ডাইমগুলি ফিরিয়ে দিন:

Them: ...+0.1+0.1+0.1 = 0.3000000000000018

এটা ঠিক ভেঙে গেছে।

এখন, আসুন একটি দীর্ঘ ব্যবহার করুন, এবং আমরা দশম সেন্টের ট্র্যাক রাখব (সুতরাং 1 = $ 0.001)। আসুন গ্রহটির প্রত্যেককে এক বিলিয়ন, একশো বারো মিলিয়ন, পঁচাত্তর হাজার, একশত চল্লিশ তিন ডলার:

Us: 7000000000L*1112075143000L = 1 894 569 218 048

উম, অপেক্ষা করুন, আমরা সবাইকে এক বিলিয়ন ডলারেরও বেশি দিতে পারি, এবং কেবল মাত্র দুই'র বেশি ব্যয় করতে পারি? উপচে পড়া এখানে বিপর্যয় is

সুতরাং, যখনই আপনি স্থানান্তর করতে, অর্থ ব্যবহারের জন্য doubleএবং Math.roundএটি পাওয়ার জন্য একটি পরিমাণ অর্থ গণনা করছেন long। তারপর ভারসাম্যকে ঠিক (জুড়তে এবং উভয় অ্যাকাউন্টে বিয়োগ) ব্যবহার করে long

আপনার অর্থনীতি ফাঁস হবে না এবং এটি এক কোয়াড্রিলিয়ন ডলার পর্যন্ত স্কেল হবে।

আরও জটিল সমস্যা রয়েছে - উদাহরণস্বরূপ, আপনি বিশ টাকা প্রদান করলে আপনি কী করবেন? * - তবে এটি আপনাকে শুরু করা উচিত।

* আপনি গণনা করুন যে এক অর্থ প্রদান কী long; তারপরে গুন করুন 20.0এবং পরীক্ষা করুন যে এটি সীমার মধ্যে রয়েছে; যদি তা হয় তবে 20Lআপনার ভারসাম্য থেকে কেটে নেওয়া পরিমাণ অর্থ প্রদানের মাধ্যমে আপনি পেমেন্টকে গুণাবেন। সাধারণভাবে, সমস্ত লেনদেনকে অবশ্যই পরিচালনা করতে হবে long, সুতরাং আপনাকে ব্যক্তিগতভাবে সমস্ত লেনদেনের যোগফল দিতে হবে; আপনি একটি শর্টকাট হিসাবে গুণ করতে পারেন, তবে আপনাকে নিশ্চিত করতে হবে যে আপনি রাউন্ডিং ত্রুটিগুলি যুক্ত করবেন না এবং আপনি উপচে পড়ছেন না, যার অর্থ doubleসত্যিকারের গণনা করার আগে আপনাকে যাচাই করা উচিত long


8

আমি যতদূর বলতে চাই যে ব্যবহারকারীর কাছে প্রদর্শিত কোনও মান প্রায় সর্বদা পূর্ণসংখ্যার হওয়া উচিত। অর্থ এটির মধ্যে সর্বাধিক বিশিষ্ট উদাহরণ। এক দৈত্যের সাথে 900 টি এইচপি দিয়ে চারবার 225 টি ক্ষতি করে এবং এটি এখনও 1 এইচপি বামে খুঁজে পেয়ে অভিজ্ঞতা থেকে বিয়োগ করবে ঠিক ততটাই খুঁজে পেয়ে যে আপনি কোনও কিছুর সংগে সংক্ষিপ্তসার হিসাবে একটি পয়সার সংক্ষিপ্ত অংশের অদৃশ্য ভগ্নাংশ finding

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

number=(number*104)/100

4% যোগ করার জন্য, স্ট্যান্ডার্ড কনভেনশন দ্বারা গোল:

number=(number*104+50)/100

এখানে কোনও ফ্লোট পয়েন্টের অসতর্কতা নেই, গোলটি সর্বদা .5চিহ্নের উপর ঠিক বিভক্ত হয় ।

সম্পাদনা করুন, আসল প্রশ্ন:

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

একটি অ-পূর্ণসংখ্যার মান উপস্থাপনের জন্য একটি পূর্ণসংখ্যার ব্যবহার প্রোগ্রামারকে বাস্তবায়নের বিশদটি মোকাবেলা করতে বাধ্য করে। "কোন নির্ভুলতা ব্যবহার করতে হবে?" এবং "গোল করার কী উপায়?" স্পষ্টভাবে উত্তর দেওয়া আবশ্যক যে প্রশ্ন।

অন্যদিকে একটি ভাসা প্রোগ্রামারকে চিন্তিত করতে বাধ্য করে না, এটি ইতিমধ্যে একজনের প্রত্যাশার চেয়ে অনেক বেশি কাজ করে। তবে যেহেতু একটি ভাসা অসীম নির্ভুলতা নয়, তাই কিছু গোলাকার ঘটবে, এবং সেই গোলটি বেশ অনাকাঙ্ক্ষিত।

এক ব্যবহারে কি ঘটে এবং চক্রের নিয়ন্ত্রণটি নিতে চান? এটি প্রায় অসম্ভব হতে দেখা যাচ্ছে। সত্যিকারের পূর্বাভাসযোগ্য একটি ফ্লোট তৈরির একমাত্র উপায় হ'ল মানগুলি যা পুরো 2^nগুলি হিসাবে উপস্থাপিত হতে পারে ব্যবহার করা । তবে এই নির্মাণটি ভাসমানগুলি ব্যবহার করা বেশ শক্ত করে তোলে।

সুতরাং সহজ প্রশ্নের উত্তর হ'ল: আপনি যদি নিয়ন্ত্রণ নিতে চান তবে পূর্ণসংখ্যা ব্যবহার করুন, যদি না হয় তবে ফ্লোট ব্যবহার করুন।

তবে যে প্রশ্নটি বিতর্কিত হচ্ছে তা হ'ল প্রশ্নের আরও একটি রূপ: আপনি নিয়ন্ত্রণ নিতে চান?


5

এমনকি যদি এটি "কেবল একটি খেলা" হয় তবে আমি মার্টিন ফাউলারের কাছ থেকে মানি প্যাটার্নটি ব্যবহার করব , এটি দীর্ঘ সময় ব্যাক আপযুক্ত।

কেন?

স্থানীয়করণ (L10n): সেই প্যাটার্নটি ব্যবহার করে আপনি আপনার গেমের মুদ্রাকে সহজেই স্থানীয়করণ করতে পারেন। "ট্রান্সপোর্ট ট্রাইকুন" এর মতো পুরানো টাইকুন গেমগুলি সম্পর্কে ভাবুন। তারা খেলোয়াড়কে সহজেই গেমের মুদ্রা পরিবর্তনের অনুমতি দেয় (অর্থাত্ ব্রিটিশ পাউন্ড থেকে মার্কিন ডলারের কাছে) আসল বিশ্বের মুদ্রার সাথে দেখা করতে।

এবং

দীর্ঘ ডেটা টাইপ একটি 64-বিট স্বাক্ষরিত দুটির পরিপূরক পূর্ণসংখ্যা। এটির সর্বনিম্ন মান -9,223,372,036,854,775,808 এবং সর্বোচ্চ মূল্য 9,223,372,036,854,775,807 (অন্তর্ভুক্ত) ( জাভা টিউটোরিয়াল ) রয়েছে

এর অর্থ আপনি বর্তমান এম 2 ইউএস মানি সাপ্লাই (~ 10,000 বিলিয়ন ডলার) 9,000 বার সঞ্চয় করতে পারবেন । অন্য যে কোনও বিশ্ব মুদ্রা ব্যবহারের জন্য আপনাকে পর্যাপ্ত জায়গা প্রদান, সম্ভবত, যাদের হাইপারইনফ্লেশন ছিল / রয়েছে (যদি কৌতূহলী হয় তবে ডাব্লুডাব্লুআইয়ের পরে জার্মান মুদ্রাস্ফীতি দেখুন , যেখানে 1 পাউন্ড রুটি ছিল 3,000,000,000 চিহ্ন)

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


2

আপনি এই কাজটি করতে চান? নির্ভুলতা কতটা গুরুত্বপূর্ণ? বৃত্তাকারে ঘটে যাওয়া ভগ্নাংশগত ত্রুটিগুলি এবং বাইনারি সিস্টেমে দশমিক সংখ্যা উপস্থাপনের অদম্যতা সম্পর্কে আপনি কি নজর রাখেন?

পরিশেষে আমি "কোণার কেস" এবং জ্ঞাত সমস্যাযুক্ত কেসের জন্য ইউনিট পরীক্ষার কোডিং এবং প্রয়োগকরণের জন্য আরও কিছুটা সময় ব্যয় করার দিকে ঝুঁকতে দেখি - সুতরাং আমি কোনও সংশোধিত বিগইন্টিজারের বিবেচনায় ভাবছি যা নির্বিচারে বড় পরিমাণে পরিবেষ্টিত করে এবং একটি বিগডিসিমাল বা ভগ্নাংশ বিট বজায় রাখে একটি বিগ্যাশনাল অংশ (দুটি বিগআইন্টিজার, একটি ডোনমিনেটরের জন্য এবং আরেকটি সংখ্যক) - এবং কোডটি অন্তর্ভুক্ত করে প্রকৃত অংশকে আসল ভগ্নাংশ রাখার জন্য (সম্ভবত কেবলমাত্র পর্যায়ক্রমে) মূল বিগইন্টিজারে কোনও অ-ভগ্নাংশ যুক্ত করে। তারপরে আমি অভ্যন্তরীণভাবে সেন্ট জলের সমস্ত কিছুর সন্ধান কেবল ভগ্নাংশের অংশগুলিকে জিইউআই গণনার বাইরে রাখতে পারি।

সম্ভবত (সরল) গেমটির জন্য জটিল করার উপায় - তবে ওপেন সোর্স হিসাবে প্রকাশিত লাইব্রেরির পক্ষে ভাল! ভগ্নাংশ বিটগুলি মোকাবেলা করার সময় পারফরম্যান্সটি ভাল রাখার উপায়গুলি খুঁজে বের করার প্রয়োজন হবে ...


1

অবশ্যই ভাসা না। মাত্র 7 টি সংখ্যার সাথে আপনার কেবলর মতো যথার্থতা রয়েছে:

12,345.67 123,456.7x

সুতরাং আপনি দেখুন, ইতিমধ্যে 10 ^ 5 ডলার দিয়ে, আপনি পেনিগুলি হারিয়ে ফেলছেন। নির্ভুলতার উদ্বেগের কারণে ডাবল গেমের উদ্দেশ্যে ব্যবহারযোগ্য, বাস্তব জীবনে নয়।

তবে লম্বা (এবং এর অর্থ আমার কাছে them৪ বিট, বা দীর্ঘ দীর্ঘ দীর্ঘ C ++) যদি আপনি লেনদেনগুলি ট্র্যাক করতে এবং সেগুলিকে সংমিশ্রণ করতে চলেছেন তবে যথেষ্ট নয়। এটি কোনও সংস্থার নেট হোল্ডিংগুলি বজায় রাখতে যথেষ্ট, তবে এক বছরের জন্য সমস্ত লেনদেন উপচে পড়তে পারে। এটি নির্ভর করে যে আপনার আর্থিক "বিশ্বের" গেমটিতে কত বড়।


0

আমি এখানে যোগ করব এমন আরও একটি সমাধান হ'ল মানি ক্লাস করা। ক্লাসটি এমন কিছু হবে (এমনকি সহজভাবে একটি কাঠামোও হতে পারে)।

class Money
{
     string currencyType; //the type of currency example USD could be an enum as well
     bool isNegativeValue;
     unsigned long int wholeUnits;
     unsigned short int partialUnits;
}

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

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

সম্পাদনা:

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


0

আপনার মূল প্রশ্নের একটি মন্তব্যে উল্লিখিত হিসাবে, এই সমস্যাটি স্ট্যাকএক্সচেঞ্জ এ আচ্ছাদিত করা হয়েছে: https://stackoverflow.com/questions/8148684/ কি-is-test-best-data-type-to-use-for- অর্থ-ইন-জাভা-অ্যাপ

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


-1

এটি সর্বোত্তম উপায় শ্রেণীর ব্যবহার করুন । আপনি আপনার অর্থ প্রয়োগ বাস্তবায়ন গোপন করতে পারেন যে কোনও সময় আপনি যা চান তার দ্বিগুণ / দীর্ঘ পরিবর্তন করতে পারেন।

উদাহরণ

class Money
{
    private long count;//Store here what ever you want in what type you want i suggest long or int
    //methods constructors etc.
    public String print()
    {
        return count/100.F; //convert this to string
    }
}

আপনার কোডগুলিতে সহজভাবে গেটর ব্যবহার করুন এটি আমার মনে হয় আরও ভাল উপায় এবং আপনি আরও দরকারী পদ্ধতি সঞ্চয় করতে পারেন।

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