কোনও বিগডিসিমাল সঠিকভাবে ভাসমান বা ডাবল রূপান্তর করতে পারে কিনা তা কীভাবে জানবেন?


10

BigDecimalঅবিরাম রূপান্তর নিশ্চিত করার জন্য শ্রেণীর কয়েকটি দরকারী পদ্ধতি রয়েছে:

  • byteValueExact()
  • shortValueExact()
  • intValueExact()
  • longValueExact()

তবে, পদ্ধতি floatValueExact()এবং doubleValueExact()অস্তিত্ব নেই।

আমি পদ্ধতি জন্য OpenJDK সোর্স কোড পড়া floatValue()এবং doubleValue()। উভয়ই যথাক্রমে ফ্যালব্যাক হিসাবে উপস্থিত হয় Float.parseFloat()এবং এটি Double.parseDouble()ইতিবাচক বা নেতিবাচক অসীম ফিরে আসতে পারে। উদাহরণস্বরূপ, 10,000 9s এর স্ট্রিংকে পার্স করা ইতিবাচক অনন্তিকে ফিরে আসবে। যেমনটি আমি বুঝতে পারি, BigDecimalঅনন্তের কোনও অভ্যন্তরীণ ধারণা নেই। আরও, 100 9s এর স্ট্রিংকে doubleদেয় হিসাবে বিশ্লেষণ করে 1.0E100যা অনন্ত নয়, তবে নির্ভুলতা হারিয়ে ফেলে।

একটি যুক্তিসঙ্গত বাস্তবায়ন কি floatValueExact()এবং doubleValueExact()?

আমি একটি সম্পর্কে চিন্তা doubleসমাধান মিশ্রন দ্বারা BigDecimal.doubleValue(), BigDecial.toString(), Double.parseDouble(String)এবং Double.toString(double), কিন্তু এটা নোংরা দেখায়। আমি এখানে জিজ্ঞাসা করতে চাই কারণ একটি সহজ সমাধান হতে পারে (অবশ্যই!)

পরিষ্কার হওয়ার জন্য, আমার উচ্চতর পারফরম্যান্স সমাধানের দরকার নেই।


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

উত্তর:


6

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

হিসাবে floatValue()এবং হিসাবে doubleValue(), একই অনুরূপ ওভারফ্লো চেক করা হচ্ছে, তবে ব্যতিক্রম ছোঁড়ার পরিবর্তে এটি ফিরে আসে Double.POSITIVE_INFINITYবা Double.NEGATIVE_INFINITYডাবলস এবং Float.POSITIVE_INFINITYঅথবা Float.NEGATIVE_INFINITYফ্লোটের জন্য।

অতএব অধিকাংশ যুক্তিসংগত (এবং সহজ) বাস্তবায়ন exactভাসা এবং ডাবল জন্য পদ্ধতি, কেবল যদি রূপান্তর আয় পরীক্ষা করা উচিত POSITIVE_INFINITYবা NEGATIVE_INFINITY


তদ্ব্যতীত , মনে রাখবেন যে BigDecimalএটি ব্যবহার করে floatবা doubleবড় অযৌক্তিকতার জন্য যথাযথতার অভাবকে পরিচালনা করার জন্য ডিজাইন করা হয়েছিল , সুতরাং @ জেবি নিজেট মন্তব্য করেছেন যে , উপরে আপনি যে আরও একটি চেক যুক্ত করতে পারেন তা হ'ল আপনি এখনও পান কিনা তা দেখার জন্য doubleবা floatফিরে রূপান্তর করা BigDecimalএকই মান। এটি রূপান্তরটি সঠিক ছিল তা প্রমাণ করা উচিত।

এই জাতীয় পদ্ধতির জন্য কী দেখতে হবে তা এখানে floatValueExact():

public static float floatValueExact(BigDecimal decimal) {
    float result = decimal.floatValue();
    if (!Float.isInfinite(result)) {
        if (new BigDecimal(String.valueOf(result)).compareTo(decimal) == 0) {
            return result;
        }
    }
    throw new ArithmeticException(String.format("%s: Cannot be represented as float", decimal));
}

উপরের compareToপরিবর্তে ব্যবহারের equalsউদ্দেশ্যমূলক যাতে চেকগুলি দিয়ে খুব বেশি কঠোর না হয়। equalsযখন দুটি BigDecimalবস্তুর একই মান এবং স্কেল (দশমিকের ভগ্নাংশের অংশের আকার) থাকবে কেবল তখনই সত্যটিকে মূল্যায়ন করা compareToহবে , যখন এটি বিবেচনা না করে তখন এই পার্থক্যটিকে উপেক্ষা করবে। উদাহরণস্বরূপ 2.0বনাম 2.00


খুব ধূর্ত ঠিক আমার কী দরকার! দ্রষ্টব্য: আপনিও ব্যবহার করতে চাইতে পারেন Float.isFinite()বা Float.isInfinite(), তবে এটি alচ্ছিক। :)
কেভিনার্পে

3
সমান তুলনায় আপনার তুলনাও পছন্দ করা উচিত, কারণ বিগডিসিমালে সমান () ২.০ এবং ২.০০ কে বিভিন্ন মান হিসাবে বিবেচনা করবে।
জেবি নিজেট

ভ্যালু হিসাবে যথাযথভাবে প্রতিনিধিত্ব করা যায় না এমন মানগুলি কাজ করবে না। উদাহরণ: 123.456f। আমার ধারণা, এটি 32-বিট ফ্লোট এবং 64-বিট ডাবল এর মধ্যে বিভিন্ন আকারের ম্যানিট্যান্ডের (ম্যান্টিসা) কারণে রয়েছে। আপনার উপরের কোড, আমি সঙ্গে ভাল ফলাফল পাবেন: if (new BigDecimal(result, MathContext.DECIMAL32).equals(decimal)) {। এটি কি যুক্তিসঙ্গত পরিবর্তন ... বা ভাসমান পয়েন্টের মানগুলির আমি অন্য কোন কোণটি মিস করছি?
কেভিনার্পে

1
@ কেভিনার্প - 123.456fধারণাটি আপনার 1.0E100 উদাহরণের মতো। এটা আমার হানা আপনি যদি প্রয়োজন চেক করার জন্য যে BigDecimal থেকে রুপান্তরের -> বাইনারি ফ্লোটিং পয়েন্ট সঠিক তারপর যে প্রয়োজন সমস্যা হয়; অর্থাৎ রূপান্তর বিবেচনা করা উচিত নয়।
স্টিফেন সি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.