ভাসমান পয়েন্টের মানগুলির সমস্যা হ'ল তারা নির্ধারিত পরিমাণে বিট সহ অসীম পরিমাণ (অবিচ্ছিন্ন) মান উপস্থাপনের চেষ্টা করছেন। সুতরাং স্বাভাবিকভাবেই, খেলায় কিছু লোকসান হতে হবে এবং আপনাকে কয়েকটি মান দিয়ে দংশিত হতে চলেছে।
যখন কোনও কম্পিউটার 1.275 কে একটি ভাসমান পয়েন্টের মান হিসাবে সঞ্চয় করে, এটি আসলে মনে করবে না এটি 1.275 বা 1.27499999999999993, এমনকি 1.27500000000000002 ছিল কিনা whether এই মানগুলি দুটি দশমিকের বৃত্তাকার পরে বিভিন্ন ফলাফল দেয়, তবে তারা তা করবে না, যেহেতু কম্পিউটারের জন্য তারা ভাসমান পয়েন্টের মান হিসাবে সংরক্ষণ করার পরে ঠিক একই রকম দেখায় এবং হারিয়ে যাওয়া ডেটা পুনরুদ্ধারের কোনও উপায় নেই। পরবর্তী কোনও গণনা কেবল এই জাতীয় অসম্পূর্ণতা জমা করবে।
সুতরাং, যদি নির্ভুলতার বিষয়টি বিবেচনা করে তবে আপনাকে শুরু থেকেই ভাসমান পয়েন্টের মানগুলি এড়াতে হবে। সহজ বিকল্পগুলি হল
- একটি উত্সর্গীকৃত গ্রন্থাগার ব্যবহার করুন
- মানগুলি সংরক্ষণ এবং পাস করার জন্য স্ট্রিংগুলি ব্যবহার করুন (স্ট্রিং অপারেশন সহ)
- পূর্ণসংখ্যা ব্যবহার করুন (উদাহরণস্বরূপ আপনি আপনার আসল মূল্যের শততম পরিমাণের কাছাকাছি যেতে পারেন, যেমন ডলারের পরিবর্তে সেন্টে পরিমাণ)
উদাহরণস্বরূপ, শততম সংখ্যা সঞ্চয় করতে পূর্ণসংখ্যার ব্যবহার করার সময়, আসল মান সন্ধানের জন্য ফাংশনটি বেশ সহজ:
function descale(num, decimals) {
var hasMinus = num < 0;
var numString = Math.abs(num).toString();
var precedingZeroes = '';
for (var i = numString.length; i <= decimals; i++) {
precedingZeroes += '0';
}
numString = precedingZeroes + numString;
return (hasMinus ? '-' : '')
+ numString.substr(0, numString.length-decimals)
+ '.'
+ numString.substr(numString.length-decimals);
}
alert(descale(127, 2));
স্ট্রিংগুলির সাথে আপনার গোলাকার প্রয়োজন, তবে এটি এখনও পরিচালনাযোগ্য:
function precise_round(num, decimals) {
var parts = num.split('.');
var hasMinus = parts.length > 0 && parts[0].length > 0 && parts[0].charAt(0) == '-';
var integralPart = parts.length == 0 ? '0' : (hasMinus ? parts[0].substr(1) : parts[0]);
var decimalPart = parts.length > 1 ? parts[1] : '';
if (decimalPart.length > decimals) {
var roundOffNumber = decimalPart.charAt(decimals);
decimalPart = decimalPart.substr(0, decimals);
if ('56789'.indexOf(roundOffNumber) > -1) {
var numbers = integralPart + decimalPart;
var i = numbers.length;
var trailingZeroes = '';
var justOneAndTrailingZeroes = true;
do {
i--;
var roundedNumber = '1234567890'.charAt(parseInt(numbers.charAt(i)));
if (roundedNumber === '0') {
trailingZeroes += '0';
} else {
numbers = numbers.substr(0, i) + roundedNumber + trailingZeroes;
justOneAndTrailingZeroes = false;
break;
}
} while (i > 0);
if (justOneAndTrailingZeroes) {
numbers = '1' + trailingZeroes;
}
integralPart = numbers.substr(0, numbers.length - decimals);
decimalPart = numbers.substr(numbers.length - decimals);
}
} else {
for (var i = decimalPart.length; i < decimals; i++) {
decimalPart += '0';
}
}
return (hasMinus ? '-' : '') + integralPart + (decimals > 0 ? '.' + decimalPart : '');
}
alert(precise_round('1.275', 2));
alert(precise_round('1.27499999999999993', 2));
নোট করুন যে এই ফাংশনটি কাছাকাছি অবস্থিত, শূন্য থেকে দূরে সম্পর্কযুক্ত , যখন আইইইই 754 কাছাকাছি গোলাকার প্রস্তাব দেয় এমনকি ভাসমান পয়েন্ট অপারেশনগুলির জন্য ডিফল্ট আচরণ হিসাবেও সম্পর্কযুক্ত । এই জাতীয় পরিবর্তনগুলি পাঠকের অনুশীলন হিসাবে ছেড়ে গেছে :)