ভাসমান পয়েন্টের মানগুলির তুলনা করা কতটা বিপজ্জনক?


391

রেজোলিউশনের স্বতন্ত্র সমন্বিত সিস্টেমের কারণে আমি UIKitব্যবহারগুলি জানি CGFloat

কিন্তু প্রত্যেক বার আমি চেক করতে যদি উদাহরণস্বরূপ চান frame.origin.xহয় 0এটা আমার অসুস্থ বোধ করে তোলে:

if (theView.frame.origin.x == 0) {
    // do important operation
}

নন CGFloatমিথ্যা positives প্রবন যখন তুলনা ==, <=, >=, <, >? এটি একটি ভাসমান বিন্দু এবং তাদের অবাস্তব সমস্যা রয়েছে: 0.0000000000041উদাহরণস্বরূপ।

Objective-Cতুলনা করার সময় কি অভ্যন্তরীণভাবে এটি পরিচালনা করছে বা এমন কি ঘটতে পারে যে origin.xশূন্য হিসাবে পড়ে এমনটি 0সত্যের সাথে তুলনা করে না ?

উত্তর:


466

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

প্রথমত, আপনি যদি ভাসমান পয়েন্ট নিয়ে প্রোগ্রাম করতে চান তবে আপনার এটি পড়তে হবে:

প্রতিটি কম্পিউটার বিজ্ঞানী ভাসমান-পয়েন্ট পাটিগণিত সম্পর্কে যা জানা উচিত

হ্যাঁ, এটি সব পড়ুন। যদি এটি খুব বেশি বোঝা হয় তবে আপনার গণনার জন্য পূর্ণসংখ্যার / নির্দিষ্ট পয়েন্টটি ব্যবহার করা উচিত যতক্ষণ না আপনার এটি পড়ার সময় হয়। :-)

এখন, এই কথার সাথে, সঠিক ভাসমান পয়েন্ট তুলনা সহ সবচেয়ে বড় সমস্যাগুলি নেমে আসে:

  1. সত্য যে মান প্রচুর আপনি উৎস লিখতে পারে, অথবা সঙ্গে পড়া scanfবা strtod, অস্তিত্ব নেই ফ্লোটিং পয়েন্ট মান হিসাবে এবং নিঃশব্দে নিকটতম পড়তা রূপান্তরিত হয়। দৈত্য demon73৩৩ এর উত্তর এটিই বলছিল।

  2. আসল ফলাফল উপস্থাপনের যথেষ্ট যথাযথতা না থাকার কারণে অনেকগুলি ফলাফল গোল হয়ে যায়। একটি সহজ উদাহরণ যেখানে আপনি এটি দেখতে পাচ্ছেন এটি যোগ করা x = 0x1fffffeএবং y = 1ভাসমান হিসাবে রয়েছে। এখানে xমান্টিসায় 24 টি বিট আছে (ঠিক আছে) এবং yমাত্র 1 বিট রয়েছে তবে আপনি যখন এগুলি যুক্ত করেন তখন তাদের বিটগুলি ওভারল্যাপিং জায়গায় হয় না এবং ফলস্বরূপ 25 বিট নির্ভুলতার প্রয়োজন হয়। পরিবর্তে, এটি গোল হয়ে যায় ( 0x2000000ডিফল্ট রাউন্ডিং মোডে)।

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

  4. ডাবল রাউন্ডিং। কিছু সিস্টেমে (বিশেষত x86), ভাসমান পয়েন্ট এক্সপ্রেশনগুলি তাদের নামমাত্র ধরণের চেয়ে উচ্চতর নির্ভুলতায় মূল্যায়ন করা হয়। এর অর্থ এই যে যখন উপরের কোনও ধরণের রাউন্ডিং ঘটে তখন আপনি দুটি বৃত্তাকার পদক্ষেপ পাবেন, প্রথমে ফলাফলটি উচ্চ-নির্ভুলতার ধরণের, পরে চূড়ান্ত প্রকারের গোলাকার। উদাহরণস্বরূপ, দশমিকের মধ্যে কী ঘটে যায় তা বিবেচনা করুন যদি আপনি কোনও সংখ্যার (১) এর সাথে ১.৪৪ গোল করেন তবে আপনি যদি প্রথমে এটি একটি দশমিক স্থানে (1.5) গোল করেন তবে ফলাফলটি পূর্ণসংখ্যায় পরিণত হয় (2)। ভাসমান পয়েন্টটি মোকাবেলা করার জন্য এটি প্রকৃতপক্ষে একটি নস্টিস্ট অঞ্চল, যেহেতু সংকলকটির আচরণ (বিশেষত বগি, জিসিসির মতো না-অনুমানকারী সংকলকগুলির জন্য) অনাকাঙ্ক্ষিত।

  5. অতীন্দ্রিয় ফাংশন ( trig, exp, log, ইত্যাদি) সঠিকভাবে বৃত্তাকার ফলাফল নির্দিষ্ট করা হয় না; ফলাফলটি সুনির্দিষ্টতার শেষ স্থানে (সাধারণত 1ulp হিসাবে পরিচিত ) এক ইউনিটের মধ্যে সঠিক হতে নির্দিষ্ট করা হয়েছে ।

আপনি যখন ভাসমান পয়েন্ট কোডটি লিখছেন, তখন আপনাকে সেই সংখ্যাগুলি দিয়ে কী করছেন যেগুলি ফলাফলটি অকার্যকর হতে পারে এবং সেই অনুযায়ী তুলনা করা উচিত তা আপনার মনে রাখা প্রয়োজন। প্রায়শই একটি "অ্যাপসিলন" এর সাথে তুলনা করা বুদ্ধিমান হয়ে উঠবে, তবে সেই অ্যাপসিলনটি আপনি যে সংখ্যার সাথে তুলনা করছেন তার परिमाणের ভিত্তিতে হওয়া উচিত , একেবারে ধ্রুবক নয় not (যে ক্ষেত্রে নিরঙ্কুশ ধ্রুবক এপসিলন কাজ করবে, এটি দৃ indic়ভাবে নির্দেশক যে স্থির বিন্দু, ভাসমান বিন্দু নয়, এটি কাজের সঠিক সরঞ্জাম!)

সম্পাদনা: বিশেষত, একটি परिमाण-সম্পর্কিত আপেলসোন চেকটির মতো দেখতে হবে:

if (fabs(x-y) < K * FLT_EPSILON * fabs(x+y))

কোথা FLT_EPSILONথেকে ধ্রুবক রয়েছে float.h( এর DBL_EPSILONজন্য doubleবা এর LDBL_EPSILONজন্য এটি প্রতিস্থাপন করুন long double) এবং আপনি Kএমন ধ্রুবক হিসাবে বেছে বেছে বেছে বেছেছেন যে আপনার গুনে জমা হওয়া ত্রুটিটি অবশ্যই স্থায়ীভাবে Kইউনিট দ্বারা আবদ্ধ হয় (এবং যদি আপনি নিশ্চিত না হন যে ত্রুটিটি পেয়েছেন তবে আবদ্ধ গণনা ডান, Kআপনার গণনা যা বলেছিল তার থেকে কয়েকগুণ বড় করুন)।

পরিশেষে, নোট করুন যে আপনি এটি ব্যবহার করেন তবে শূন্যের কাছাকাছি কিছু বিশেষ যত্নের প্রয়োজন হতে পারে, যেহেতু FLT_EPSILONডেনারমালগুলি বোঝায় না। একটি দ্রুত সমাধান এটি করা হবে:

if (fabs(x-y) < K * FLT_EPSILON * fabs(x+y) || fabs(x-y) < FLT_MIN)

এবং একইভাবে বিকল্প DBL_MINযদি ডাবল ব্যবহার করে।


25
fabs(x+y)সমস্যাযুক্ত যদি xএবং y(থাকতে পারে) আলাদা চিহ্ন থাকতে পারে। তবুও, কার্গো-কাল্ট তুলনার জোয়ারের বিরুদ্ধে একটি ভাল উত্তর।
ড্যানিয়েল ফিশার

27
যদি xএবং yআলাদা চিহ্ন থাকে তবে কোনও সমস্যা নেই। ডান হাতের দিকটি "খুব ছোট" হবে তবে যেহেতু xএবং yবিভিন্ন চিহ্ন রয়েছে, সেগুলি আর যাইহোক সমান তুলনা করা উচিত নয়। (যদি না তারা এ জাতীয় হিসাবে এত ছোট হয় তবে দ্বিতীয় ক্ষেত্রে এটি ধরা পড়ে)
আর .. গিথহাব স্টপ হেল্পিং আইসিসি

4
আমি আপনার বক্তব্যটি সম্পর্কে আগ্রহী: "বিশেষত বগি, জিসিসির মতো নন-কনফর্মেন্ট কম্পাইলারগুলির জন্য"। আসলেই কি জিসিসির বগি এবং অ-সঙ্গতিপূর্ণ?
নিকোলস ওজিমিকা

3
যেহেতু প্রশ্নটি আইওএস ট্যাগ করা হয়েছে, তাই এটি লক্ষণীয় যে অ্যাপলের সংকলকগণ (ঝনঝন এবং অ্যাপলের জিসিসি উভয়ই নির্মিত) সর্বদা FLT_EVAL_METHOD = 0 ব্যবহার করেছেন এবং অতিরিক্ত নির্ভুলতা না নিয়ে সম্পূর্ণ কঠোর হওয়ার চেষ্টা করেছেন attempt যদি এর কোনও লঙ্ঘন পাওয়া যায় তবে দয়া করে বাগ প্রতিবেদন করুন।
স্টিফেন ক্যানন

17
"সর্বোপরি, ভাসমান পয়েন্টের মানগুলি তাদের আচরণে" এলোমেলো "নয় Ex সঠিক তুলনা প্রচুর বাস্তব-ব্যবহারের ক্ষেত্রে উপলব্ধি করতে পারে এবং তা করতে পারে।" - মাত্র দুটি বাক্য এবং ইতিমধ্যে একটি +1 অর্জন করেছেন! ভাসমান পয়েন্টগুলির সাথে কাজ করার সময় লোকেদের মধ্যে এটি সবচেয়ে বিরক্তিকর বিভ্রান্তি।
খ্রিস্টান রাউ

36

যেহেতু 0 হ'ল আইইইই 7575৫ টি ভাসমান-পয়েন্ট নম্বর হিসাবে প্রতিনিধিত্বযোগ্য (বা আমি যে কোনও এফপি সংখ্যা ব্যবহার করে অন্য কোনও প্রয়োগ ব্যবহার করেছি) 0 এর সাথে তুলনা করা সম্ভবত নিরাপদ। আপনি হয়ত কামড় পেতে পারেন, যদি আপনার প্রোগ্রামটি এমন কোনও মান (যেমন theView.frame.origin.x) গণনা করে যা আপনার বিশ্বাস করার কারণ রয়েছে যা 0 হওয়া উচিত তবে যা আপনার গণনা 0 হওয়ার নিশ্চয়তা দিতে পারে না।

কিছুটা স্পষ্ট করার জন্য, একটি গণনা যেমন:

areal = 0.0

(আপনার ভাষা বা সিস্টেমটি ভাঙা না হলে) এমন মান তৈরি করে যা (areal == 0.0) সত্য দেয় তবে অন্য গণনা যেমন

areal = 1.386 - 2.1*(0.66)

নাও হতে পারে.

যদি আপনি নিজেকে নিশ্চিত করতে পারেন যে আপনার গণনাগুলি 0 মান দেয় (এবং কেবল তারা মান 0 যা হওয়া উচিত তা উত্পাদন করে না) তবে আপনি এগিয়ে যেতে পারেন এবং 0 এর সাথে এফপি মানগুলি তুলনা করতে পারেন যদি আপনি প্রয়োজনীয় ডিগ্রীতে নিজেকে নিশ্চিত করতে না পারেন , সর্বোত্তম 'সহনশীল সমতা' এর সাধারণ পদ্ধতির সাথে আঁকুন stick

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

অ্যাংরি পাখির পক্ষে, এত বিপজ্জনক নয়।


11
প্রকৃতপক্ষে, 1.30 - 2*(0.65)এমন একটি অভিব্যক্তির একটি নিখুঁত উদাহরণ যা আপনার সংকলক আইইইই 754 প্রয়োগ করে তবে স্পষ্টতই 0.0 এ মূল্যায়ন করে, কারণ ডাবলগুলি একই তাত্পর্য হিসাবে উপস্থাপিত হয়েছে 0.65এবং 1.30দুটি দ্বারা গুণকটি স্পষ্টভাবে সঠিক।
পাস্কেল কুয়াক

7
এখনও এটির থেকে প্রতিনিধি পাচ্ছি, তাই আমি দ্বিতীয় উদাহরণ স্নিপেট পরিবর্তন করেছি।
উচ্চ পারফরম্যান্স মার্ক

22

আমি অন্যদের চেয়ে কিছুটা আলাদা উত্তর দিতে চাই। আপনার প্রশ্নের উত্তর হিসাবে বর্ণিত তারা এগুলি দুর্দান্ত তবে সম্ভবত আপনার যা জানা দরকার বা আপনার আসল সমস্যাটি তা নয়।

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

সুতরাং আপনি যদি পরীক্ষা করতে চান যে আপনার পয়েন্টটি [0.. প্রস্থের [শ্রেনীর মধ্যে এটি ঠিক আছে) outside আপনি নিশ্চিতভাবে অন্তর্ভুক্তির সংজ্ঞা দিয়েছেন। উদাহরণস্বরূপ সর্বদা অভ্যন্তরের সংজ্ঞা দেওয়া হয় (x> = 0 && x <প্রস্থ)। একই ছেদ বা হিট পরীক্ষার জন্য যায়।

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


13

শুন্যতে তুলনা করতে পারেন যতদিন শূন্য একটি হিসাব মান (হিসাবে একটি উপরে উত্তর উল্লেখ) ছিল না একটি নিরাপদ অপারেশন হতে। এর কারণ হ'ল শূন্যটি ভাসমান পয়েন্টে একটি নিখুঁতভাবে উপস্থাপনযোগ্য সংখ্যা।

নিখুঁতভাবে উপস্থাপনযোগ্য মানগুলির সাথে কথা বলার পরে, আপনি পাওয়ার-অফ-টু ধারণার (একক নির্ভুলতা) মধ্যে 24 বিটের পরিসর পাবেন। সুতরাং 1, 2, 4 পুরোপুরি প্রতিনিধিত্বযোগ্য, যেমন .5, .25 এবং .125। যতক্ষণ না আপনার সমস্ত গুরুত্বপূর্ণ বিট 24-বিটগুলিতে থাকে ততক্ষণ আপনি সোনালী। সুতরাং 10.625 যথাযথভাবে পোস্ট করা যেতে পারে।

এটি দুর্দান্ত, তবে দ্রুত চাপের মধ্যে পড়ে যাবে। দুটি পরিস্থিতি মনে পড়বে: 1) যখন কোনও গণনা জড়িত থাকে। যে স্কয়ার্ট (3) * স্কয়ার্ট (3) == 3. বিশ্বাস করবেন না। এটি ঠিক সেভাবে হবে না। এবং সম্ভবত এটি কোনও এপসিলনের মধ্যে থাকবে না, যেমন অন্যান্য উত্তরগুলির কিছু উত্তর দেয়। 2) যখন কোনও অ-পাওয়ার-অফ -2 (এনপিওটি) জড়িত থাকে। সুতরাং এটি অদ্ভুত লাগতে পারে তবে 0.1 বাইনারিতে একটি অসীম সিরিজ এবং সুতরাং এর মতো সংখ্যার সাথে জড়িত কোনও গণনা শুরু থেকেই অসম্পূর্ণ হবে।

(ওহ এবং মূল প্রশ্নটি শূন্যের সাথে তুলনা করেছে। ভুলে যাবেন না -0.0 একটি নিখুঁত বৈধ ভাসমান-পয়েন্ট মানও is)


11

['সঠিক উত্তর' বাছাই উপর glosses K। নির্বাচন Kশেষ হওয়ার সাথে সাথে অ্যাড-হক হিসাবেও শেষ হয় VISIBLE_SHIFTতবে নির্বাচন Kকম স্পষ্ট হয় কারণ VISIBLE_SHIFTএটি কোনও প্রদর্শন সম্পত্তিতে ভিত্তি করে না। এইভাবে আপনার বিষ বাছাই করুন - নির্বাচন করুন Kবা নির্বাচন করুন VISIBLE_SHIFT। এই উত্তরটি নির্বাচনের পক্ষে VISIBLE_SHIFTএবং তারপরে নির্বাচনের ক্ষেত্রে অসুবিধা প্রকাশ করে K]

অবিলম্বে গোলাকার ত্রুটির কারণে, আপনার যৌক্তিক ক্রিয়াকলাপের জন্য 'নির্ভুল' মানের তুলনা ব্যবহার করা উচিত নয়। ভিজ্যুয়াল ডিসপ্লেতে অবস্থিত আপনার অবস্থানের নির্দিষ্ট ক্ষেত্রে, অবস্থানটি 0.0 বা 0.0000000003 হয় তা সম্ভবত বিবেচনা করে না - পার্থক্যটি চোখে অদৃশ্য। সুতরাং আপনার যুক্তি এমন কিছু হওয়া উচিত:

#define VISIBLE_SHIFT    0.0001        // for example
if (fabs(theView.frame.origin.x) < VISIBLE_SHIFT) { /* ... */ }

তবে শেষ পর্যন্ত, 'চোখের অদৃশ্য' আপনার ডিসপ্লে বৈশিষ্ট্যের উপর নির্ভর করবে। আপনি যদি ডিসপ্লেটিকে উপরের দিকে আবদ্ধ করতে পারেন (আপনার পক্ষে সক্ষম হবেন); তারপরে VISIBLE_SHIFTসেই উপরের সীমাটির একটি ভগ্নাংশ হতে বেছে নিন ।

এখন, 'সঠিক উত্তর' এর উপর নির্ভর করে Kতাই আসুন পিকিং অনুসন্ধান করুন K। উপরের 'সঠিক উত্তর' বলেছেন:

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

সুতরাং আমাদের প্রয়োজন K। যদি Kআমার প্রাপ্তির তুলনায় যদি প্রাপ্তি আরও কঠিন হয়, স্বজ্ঞাত হয় VISIBLE_SHIFTতবে আপনার পক্ষে কী কাজ করে তা সিদ্ধান্ত নেবেন। এটির জন্য Kআমরা একটি পরীক্ষা প্রোগ্রাম লিখতে যাচ্ছি যা Kমানগুলির একগুচ্ছ দেখায় যাতে আমরা এটি দেখতে পারি যে এটি কীভাবে আচরণ করে। K'সঠিক উত্তর' ব্যবহারযোগ্য হলে কীভাবে চয়ন করতে হবে তা স্পষ্ট হওয়া উচিত । কোন?

আমরা 'সঠিক উত্তর' বিশদ হিসাবে ব্যবহার করতে যাচ্ছি:

if (fabs(x-y) < K * DBL_EPSILON * fabs(x+y) || fabs(x-y) < DBL_MIN)

আসুন কে-এর সমস্ত মান চেষ্টা করে দেখুন:

#include <math.h>
#include <float.h>
#include <stdio.h>

void main (void)
{
  double x = 1e-13;
  double y = 0.0;

  double K = 1e22;
  int i = 0;

  for (; i < 32; i++, K = K/10.0)
    {
      printf ("K:%40.16lf -> ", K);

      if (fabs(x-y) < K * DBL_EPSILON * fabs(x+y) || fabs(x-y) < DBL_MIN)
        printf ("YES\n");
      else
        printf ("NO\n");
    }
}
ebg@ebg$ gcc -o test test.c
ebg@ebg$ ./test
K:10000000000000000000000.0000000000000000 -> YES
K: 1000000000000000000000.0000000000000000 -> YES
K:  100000000000000000000.0000000000000000 -> YES
K:   10000000000000000000.0000000000000000 -> YES
K:    1000000000000000000.0000000000000000 -> YES
K:     100000000000000000.0000000000000000 -> YES
K:      10000000000000000.0000000000000000 -> YES
K:       1000000000000000.0000000000000000 -> NO
K:        100000000000000.0000000000000000 -> NO
K:         10000000000000.0000000000000000 -> NO
K:          1000000000000.0000000000000000 -> NO
K:           100000000000.0000000000000000 -> NO
K:            10000000000.0000000000000000 -> NO
K:             1000000000.0000000000000000 -> NO
K:              100000000.0000000000000000 -> NO
K:               10000000.0000000000000000 -> NO
K:                1000000.0000000000000000 -> NO
K:                 100000.0000000000000000 -> NO
K:                  10000.0000000000000000 -> NO
K:                   1000.0000000000000000 -> NO
K:                    100.0000000000000000 -> NO
K:                     10.0000000000000000 -> NO
K:                      1.0000000000000000 -> NO
K:                      0.1000000000000000 -> NO
K:                      0.0100000000000000 -> NO
K:                      0.0010000000000000 -> NO
K:                      0.0001000000000000 -> NO
K:                      0.0000100000000000 -> NO
K:                      0.0000010000000000 -> NO
K:                      0.0000001000000000 -> NO
K:                      0.0000000100000000 -> NO
K:                      0.0000000010000000 -> NO

আহ, সুতরাং K 1e16 বা তার চেয়ে বড় হওয়া উচিত যদি আমি 1e-13 'শূন্য' হতে চাই।

সুতরাং, আমি বলব আপনার কাছে দুটি বিকল্প রয়েছে:

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

10
রেজোলিউশন-স্বাধীনতার একটি দিক হ'ল সংকলন সময়ে আপনি "দৃশ্যমান শিফট" কী তা নিশ্চিত করে বলতে পারবেন না। সুপার-এইচডি স্ক্রিনে যা অদৃশ্য তা খুব সহজেই একটি ছোট গাধা স্ক্রিনে সুস্পষ্ট হতে পারে। কমপক্ষে একে একে স্ক্রিন আকারের একটি কার্যকারিতা তৈরি করা উচিত। বা এর নাম অন্য কিছু।
রোমেন

1
তবে কমপক্ষে 'দৃশ্যমান শিফট' নির্বাচন করা সহজভাবে বোঝা যায় এমন ডিসপ্লে (বা ফ্রেম) বৈশিষ্ট্যের উপর ভিত্তি করে - <সঠিক উত্তরটির> এর বিপরীতে Kযা নির্বাচন করা কঠিন এবং স্বজ্ঞাত নয়।
GoZoner

5

সঠিক প্রশ্ন: কোকো টাচে কীভাবে পয়েন্টের তুলনা করা যায়?

সঠিক উত্তর: সিজিপিউইটএকুয়াল টুপয়েন্ট ()।

একটি ভিন্ন প্রশ্ন: দুটি গণনা করা মানগুলি কি একই?

উত্তর এখানে পোস্ট করা: তারা না।

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


4

গতবার যখন আমি সি স্ট্যান্ডার্ডটি পরীক্ষা করেছিলাম তখন ডাবলস (64৪ বিট মোট, ৫৩ বিট ম্যান্টিসা) এর ভাসমান পয়েন্ট অপারেশনগুলির প্রয়োজন ছিল না যে সেই নির্ভুলতার চেয়ে আরও সঠিক হতে পারে। যাইহোক, কিছু হার্ডওয়্যার বৃহত্তর নির্ভুলতার নিবন্ধগুলিতে অপারেশনগুলি করতে পারে, এবং প্রয়োজনটিকে নিম্ন অর্ডার বিটগুলি পরিষ্কার করার প্রয়োজন নেই বলে বোঝানো হয়েছিল (নিবন্ধগুলির সংখ্যা নিখুঁততার বাইরে)। সুতরাং যে কেউ সেখানে শুয়েছিল তার থেকে রেজিস্টারে কী পড়ে ছিল তার উপর নির্ভর করে আপনি এর তুলনাগুলির অপ্রত্যাশিত ফলাফল পেতে পারেন।

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


1

আপনি শূন্যের সাথে তুলনা করার জন্য এই জাতীয় কোড ব্যবহার করতে পারেন:

if ((int)(theView.frame.origin.x * 100) == 0) {
    // do important operation
}

এটি 0.1 নির্ভুলতার সাথে তুলনা করবে, এই ক্ষেত্রে সিজিফ্লোয়েটের পক্ষে এটি যথেষ্ট।


এ কাস্ট intবীমা ছাড়া theView.frame.origin.xহয় / যে পরিসর কাছাকাছি intঅনির্ধারিত আচরণ (UB) এর বিশালাকার - অথবা এই ক্ষেত্রে, 1/100 তম পরিসীমা int
chux -

এর মতো পূর্ণসংখ্যায় রূপান্তর করার কোনও কারণ নেই। যেমন চুকস বলেছে, সীমার বাইরে থাকা মানগুলি থেকে ইউবি হওয়ার সম্ভাবনা রয়েছে; এবং কিছু স্থাপত্যগুলিতে এটি কেবল ভাসমান স্থানে গণনা করার চেয়ে উল্লেখযোগ্যভাবে ধীর হবে। শেষ অবধি, এর সাথে ১০০ দিয়ে গুণ করলে 0.1 এর সাথে 0.01 নির্ভুলতার সাথে তুলনা করা হবে।
স্নেফটেল

0
-(BOOL)isFloatEqual:(CGFloat)firstValue secondValue:(CGFloat)secondValue{

BOOL isEqual = NO;

NSNumber *firstValueNumber = [NSNumber numberWithDouble:firstValue];
NSNumber *secondValueNumber = [NSNumber numberWithDouble:secondValue];

isEqual = [firstValueNumber isEqualToNumber:secondValueNumber];

return isEqual;

}


0

আমি বেশ কয়েকটি দশমিক স্থানের তুলনা করতে নিম্নলিখিত তুলনা ফাংশনটি ব্যবহার করছি:

bool compare(const double value1, const double value2, const int precision)
{
    int64_t magnitude = static_cast<int64_t>(std::pow(10, precision));
    int64_t intValue1 = static_cast<int64_t>(value1 * magnitude);
    int64_t intValue2 = static_cast<int64_t>(value2 * magnitude);
    return intValue1 == intValue2;
}

// Compare 9 decimal places:
if (compare(theView.frame.origin.x, 0, 9)) {
    // do important operation
}

-6

আমি বলব সঠিক জিনিসটি হ'ল প্রতিটি সংখ্যাটিকে একটি বস্তু হিসাবে ঘোষণা করা এবং তারপরে সেই বস্তুর মধ্যে তিনটি জিনিস সংজ্ঞায়িত করা: ১) সমতা অপারেটর। 2) একটি সেটএসেপ্টেবল ডিফারেন্স পদ্ধতি। 3) মান নিজেই। সমতা অপারেটর সত্যটি ফেরত দেয় যদি দুটি মানের পরম পার্থক্য গ্রহণযোগ্য হিসাবে সেট করা মানের চেয়ে কম হয়।

আপনি সমস্যার উপযুক্ত জিনিসটি সাবক্লাস করতে পারেন lass উদাহরণস্বরূপ, 1 এবং 2 ইঞ্চির মধ্যে ধাতুর বৃত্তাকার বারগুলি সমান ব্যাস হিসাবে বিবেচিত হতে পারে যদি তাদের ব্যাসার্ধ 0.0001 ইঞ্চির চেয়ে কম হয়। সুতরাং আপনি 0.0001 প্যারামিটারের সাথে সেটঅ্যাকসেপ্টেবল ডিফারেন্স কল করতে পারেন এবং তারপরে আত্মবিশ্বাসের সাথে সাম্যতা অপারেটরটি ব্যবহার করবেন।


1
এটি উত্তম উত্তর নয়। প্রথমত, পুরো "অবজেক্ট আইটেম" আপনার সমস্যাটি সমাধান করার জন্য কিছুই করে না। এবং দ্বিতীয়ত, আপনার "সমতা" বাস্তবায়ন বাস্তবে সঠিকটি নয় one
টম সওয়ারলি

3
টম, সম্ভবত আপনি "অবজেক্ট আইটেম" সম্পর্কে আবার ভাববেন। উচ্চ সংক্ষিপ্ততার প্রতিনিধিত্বকারী আসল সংখ্যা সহ, সাম্যতা খুব কমই ঘটে। তবে সমতার বিষয়ে কারও ধারণাটি যদি আপনার উপযুক্ত হয় তবে সেগুলি অনুসারে তৈরি করা যেতে পারে। এটি যদি খুব বেশি 'ওভাররিডেবল' প্রায় সমান 'অপারেটর থাকে তবে এটি বেশ ভাল।
জন হোয়াইট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.