ভাসমান ঘোষণার সময় কেন "চ" প্রয়োজন?


88

উদাহরণ:

float timeRemaining = 0.58f;

fএই সংখ্যাটির শেষে কেন প্রয়োজনীয়?


4
সম্ভবত, কারণ অন্যথায় এটি হিসাবে বিবেচিত হবে double
উওয়ে কেইম

4
0.58 (f প্রত্যয় ব্যতীত) ডাবল টাইপের আক্ষরিক এবং কোনও যেমন কোনও স্ট্রের জন্য কোনও int মান নির্ধারণ করতে পারে না তেমনি একটি ফ্লোটে একটি ডাবল মান বরাদ্দ করতে পারে না। তবে আপনি একটি ডাবলকে একটি ভাসমান মান নির্ধারণ করতে পারেন কারণ এখানে আপনি প্রশস্ত হয়ে যাচ্ছেন (সি # আপনার পক্ষে স্পষ্টত রূপান্তরিত করবে কোনও নির্ভুলতা হারাবে না)।
ডেভ নিউ


@ এভিডি যদিও এটি একটি সদৃশ, তবুও উপরের প্রশ্নের শিরোনামটি সম্ভবত নকল তালিকায় আপনার লিঙ্কটি প্রদান করবে না yield সুতরাং এটি কমপক্ষে আরও অনুসন্ধানের মানদণ্ডের ক্ষেত্রে মান যুক্ত করতে পারে।
অ্যাডাম হল্ডসওয়ার্থ

4
@ অ্যাডামহোল্ডসওয়ার্থ - সমস্ত রাস্তা যায় double & int
adatapost

উত্তর:


98

আপনার ফ্লোটের ঘোষণায় দুটি অংশ রয়েছে:

  1. এটি ঘোষণা করে যে ভেরিয়েবল timeRemainingপ্রকারের float
  2. এটি 0.58এই ভেরিয়েবলের মান নির্ধারণ করে ।

সমস্যাটি অংশ 2 এ ঘটে।

ডান হাতের নিজস্ব মূল্যায়ন করা হয়। সি # স্পেসিফিকেশন অনুসারে, দশমিক পয়েন্ট ধারণকারী একটি সংখ্যার প্রত্যয় নেই যা একটি হিসাবে ব্যাখ্যা করা হয় double

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

কারণটি হ'ল সংকলক দ্বারা ব্যবহৃত মানটি সত্যই 0.58 নয়, তবে ভাসমান-পয়েন্টের মান 0.58 এর নিকটতম, যা 0.57999999999999978655962351581366 ... এর জন্য doubleএবং ঠিক 0.579999946057796478271484375 এর জন্য float

কঠোরভাবে বলতে গেলে, এটির fপ্রয়োজন নেই। আপনি fএকটিতে মানটি ফেলে প্রত্যয়টি ব্যবহার করা এড়াতে পারেন float:

float timeRemaining = (float)0.58;

4
দুটি প্রশ্ন, আপনি কীভাবে '0.579999946057796478271484375' নাম্বারে পৌঁছেছেন এবং কীভাবে (float) 0.58কাজ করবে ? আপনি আগেই বলেছিলেন যে কোনও রূপান্তর নেই, কারণ তথ্য হারিয়ে যেতে পারে, তবে কাস্ট কীভাবে কাজ করবে?
সেক্সিবিস্ট

9
1. আমি উইন্ডোজ ক্যালকুলেটর ব্যবহার করেছি, যা 34 টি সংখ্যা পর্যন্ত ব্যবহার করে। ২. আমি বলেছিলাম যে কোনও অন্তর্নিহিত রূপান্তর নেই। একটি কাস্ট হ'ল সুস্পষ্ট রূপান্তর, সুতরাং আপনি স্পষ্টভাবে সংকলককে বলছেন যে আপনি রূপান্তর চান, এবং এটি অনুমোদিত।
জেফ্রি স্যাক্স

আকর্ষণীয় ... আমি আশা করি আপনি এখনও এই পোস্টটি পর্যবেক্ষণ করছেন। আমি যে ওয়েবকাস্টটি দেখছি তার জন্য 'মি' এর আগে চলে যাওয়া প্রত্যয়গুলির সাথে পরিচয় হয়েছিল। উইন্ডোজ ক্যালকুলেটরটি আপনি কিভাবে ভাসমান মান হিসাবে .58 প্রদর্শিত করতে পেলেন? আমি কয়েকটি বোতাম চেষ্টা করেছি যা দেখে মনে হচ্ছে তারা এটিকে ঘটতে বাধ্য করবে কিন্তু না ... 0.58 পেতে থাকছে। আমাকে এমন একজন ব্যক্তির শ্রদ্ধা করতে হবে যিনি তার সরঞ্জামগুলি এত ভাল জানেন ...
ব্যবহারকারী 1585204

আমি ভাসা জন্য পুরো এফ জিনিস বুঝতে পারি কিন্তু কেন? আপনি যখন ঘোষিত ভেরিয়েবলটিকে এটি একটি ফ্লোট হিসাবে ঘোষণা করা হয় তাই সংকলন করার সময় এটি জেনে রাখা উচিত যে এই মানটি একটি ফ্লোট। এবং আপনি যখন একটি ডাবল একই জিনিস ঘোষণা। এটি কোনও তাত্পর্যপূর্ণ নয় কারণ আপনি ভাসমান ম্যালভ্যালু = 2.4; সংকলক যখন কম্পাইল করা হয়েছে তখন ইতিমধ্যে জেনে রাখা উচিত ভাসমানের ধরণটি ফ্লোট। আমি কিছু অনুপস্থিত করছি? ধন্যবাদ!
ফ্রাঙ্ক জি।

@ ফ্র্যাঙ্কজি। দুটি কারণ: 1. 2.4প্রকাশটি অন্য কোথাও দ্বিগুণ হিসাবে ব্যাখ্যা করা হয়। ২. অন্তর্নিহিত সংকীর্ণ রূপান্তরগুলি (যেমন ডাবল থেকে ভাসা পর্যন্ত) অনুমোদিত নয় আপনি যদি এই নিয়মগুলিকে ব্যতিক্রম করতে চান তবে আপনার অবশ্যই খুব ভাল কারণ থাকতে হবে। 1 কী স্ট্রোক সংরক্ষণ যথেষ্ট ভাল হওয়ার সম্ভাবনা নেই।
জেফ্রি স্যাক্স

36

কারণ বেশ কিছু সাংখ্যিক ধরনের যে কম্পাইলার মান প্রতিনিধিত্ব করতে ব্যবহার করতে পারেন 0.58: float, doubleএবং decimal। সংকলক আপনার জন্য বাছাইয়ের সাথে আপনি যদি ঠিক না থাকেন তবে আপনাকে খতম করতে হবে।

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

ডিফল্টরূপে, অ্যাসাইনমেন্ট অপারেটরের ডানদিকে একটি আসল সংখ্যাসূচককে ডাবল হিসাবে ধরা হয়। তবে, আপনি যদি একটি পূর্ণসংখ্যার সংখ্যাটি দ্বিগুণ হিসাবে বিবেচনা করতে চান তবে d বা D প্রত্যয়টি ব্যবহার করুন

প্রত্যয় যুক্ত করা fএকটি তৈরি করে float; প্রত্যয়টি dএকটি সৃষ্টি করে double; প্রত্যয়টি mdecimal। এই সবগুলিও বড় হাতের কাজ করে।

তবে এটি কেন সংকলন করে না তা ব্যাখ্যা করার জন্য এটি এখনও পর্যাপ্ত নয়:

float timeRemaining = 0.58;

উত্তর অনুপস্থিত অর্ধেক থেকে রূপান্তর হয় double 0.58থেকে float timeRemainingসম্ভাব্য তথ্য হারায়, তাই কম্পাইলার এটা পরোক্ষভাবে প্রয়োগ করতে রাজি। আপনি যদি একটি স্পষ্ট কাস্ট যোগ করেন তবে রূপান্তরটি সম্পাদিত হবে; আপনি যদি fপ্রত্যয়টি যুক্ত করেন তবে কোনও রূপান্তর প্রয়োজন হবে না। উভয় ক্ষেত্রেই কোডটি সংকলিত হবে।


ভেরিয়েবলটি যদি ভাসমান হয় তবে এটি কীভাবে ডাবল বা দশমিক হতে পারে, আমি কিছু মিস করছি
টমাস

@ ব্লাজআর্ট হ্যাঁ, সংকলকটি যে বাক্যটি উল্লেখ করে তাতে অ্যাসাইনমেন্ট লক্ষ্য পরীক্ষা করার চেষ্টাও করা হয় না। এর কারণটি সংকলক টিমের তৈরি নকশার পছন্দগুলিতে সমাহিত করা হবে। আমি অনুমান করব যে সম্ভাব্য বিভ্রান্তির মুখে স্পষ্ট হওয়া ভাল, বা কেবল দুটি নিয়ম থাকার পরিবর্তে বাস্তবায়ন করতে বিরক্ত করা খুব ব্যয়বহুল, একটির জন্য intএবং একটি double
অ্যাডাম হল্ডসওয়ার্থ

@ ব্লাজআর্ট: সবেমাত্র উত্তরটি ছড়িয়ে দিতে শেষ করেছেন, দয়া করে আবার একবার দেখুন।
জন

4
তথ্য ক্ষতির বিষয়ে, আপনি কী আমাকে বলতে পারবেন যে কাস্টটি আসলে কীভাবে করা হয়, আইইইইই 754 ফর্ম্যাটটিতে সেগুলি সংরক্ষণ করে? ডাবল উচ্চতর নির্ভুলতা আছে, তাই এর মানে কি ভাসা থেকে ডাবল সর্বদা কাজ করবে, পছন্দ double a = 0.69f;?
সেক্সিবিস্ট

@Cupidvogel: হ্যাঁ, বৈশিষ্ট গ্যারান্টী (§6.1.2 মধ্যে), যা অন্যদের মধ্যে রূপান্তর অন্তর্ভুক্ত "অন্যান্য অন্তর্নিহিত সাংখ্যিক ধর্মান্তর কোন তথ্য হারান" floatথেকে double
জন

2

সমস্যাটি হ'ল নেট, কিছু প্রকারের অন্তর্নিহিত ক্রিয়াকলাপ পরিচালিত করার জন্য floatএবং double, মিশ্র অপারেশনগুলির সাথে জড়িত সমস্ত পরিস্থিতিতে কী ঘটেছিল তা স্পষ্ট করে নির্দিষ্ট করে দেওয়া প্রয়োজন বা অন্যথায় প্রকারের মধ্যে অন্তর্নিহিত রূপান্তরকে অনুমতি দেওয়া দরকার দিকনির্দেশ; মাইক্রোসফ্ট জাভা নেতৃত্ব অনুসরণ করতে বেছে নিয়েছিল যা মাঝে মধ্যে নির্ভুলতার পক্ষে যায় তবে প্রায়ই ঘন ঘন সঠিকতা ত্যাগ করে এবং ঝামেলা সৃষ্টি করে।

প্রায় সব ক্ষেত্রেই, doubleকোন নির্দিষ্ট সংখ্যার নিকটতম মানটি গ্রহণ করে এবং এটির সাথে floatনির্ধারিত floatকরে সেই পরিমাণটি পাওয়া যায় যা একই পরিমাণের নিকটতম। কয়েকটি কর্নার কেস রয়েছে যেমন মান 9,007,199,791,611,905; সেরা floatউপস্থাপনা 9,007,200,328,482,816 (যা 536,870,911 দ্বারা বন্ধ রয়েছে) হবে তবে সেরা doubleউপস্থাপনাটি (যেমন 9,007,199,791,611,904) float9,007,199,254,740,992 (যা 536,870,913 দ্বারা বন্ধ রয়েছে) উপস্থাপন করতে হবে। সাধারণভাবে, যদিও, doubleকিছু পরিমাণের সেরা উপস্থাপনাকে রূপান্তর করা floatহয় হয় সেরা সম্ভাব্য floatউপস্থাপনা অর্জন করতে পারে, বা মূলত সমানভাবে ভাল এমন দুটি উপস্থাপনার মধ্যে একটি।

নোট করুন যে এই পছন্দসই আচরণ চরমপন্থায়ও প্রযোজ্য; উদাহরণস্বরূপ, float10 ^ 308 পরিমাণের জন্য সেরা উপস্থাপনা সেই পরিমাণের floatসেরা doubleউপস্থাপনাকে রূপান্তরিত করে অর্জিত উপস্থাপনার সাথে মেলে । তেমনি, float10 ^ 309 floatএর সর্বোত্তম doubleউপস্থাপনা সেই পরিমাণের সেরা উপস্থাপনাকে রূপান্তরিত করে অর্জিত উপস্থাপনার সাথে মেলে ।

দুর্ভাগ্যক্রমে, যে দিকনির্দেশে সুস্পষ্ট কাস্টের প্রয়োজন হয় না সেগুলি খুব কমই যথাযথ হিসাবে খুব কমই পাওয়া যায়। floatকোনও মানকে সর্বোত্তম উপস্থাপনে রূপান্তর করা doubleখুব কমই doubleসেই মানটির সর্বোত্তম উপস্থাপনের নিকট থেকে খুব কম ফলন পেতে পারে এবং কিছু ক্ষেত্রে ফলাফলটি শতকরা আকারের আদেশের দ্বারা বন্ধ হয়ে যেতে পারে (যেমন float10 ^ 40 এর সেরা উপস্থাপনাকে রূপান্তরিত doubleকরবে) এমন মান যা double10 ^ 300 এর সেরা উপস্থাপনার চেয়ে বেশি তুলনা করে ।

হায়রে, রূপান্তর বিধিগুলি সেগুলি যা তাই, তাই "নিরাপদ" দিকনির্দেশে মানগুলি রূপান্তর করার সময় একজনকে নির্লিপ্ত টাইপকাস্ট এবং প্রত্যয় ব্যবহার করে বেঁচে থাকতে হয় এবং বিপজ্জনক দিকটিতে অন্তর্নিহিত টাইপকাস্টগুলি সম্পর্কে সতর্কতা অবলম্বন করা উচিত যা ঘন ঘন ফলস ফলাফল দেয়।

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