फ्लोट्स की घोषणा करते समय "f" की आवश्यकता क्यों है?


86

उदाहरण:

float timeRemaining = 0.58f;

fइस संख्या के अंत में क्यों आवश्यक है?


4
शायद, क्योंकि अन्यथा यह माना जाएगा double
उवे कीम जूल १12

2
0.58 (f प्रत्यय के बिना) टाइप डबल का एक शाब्दिक है और एक फ्लोट को एक डबल मान नहीं दे सकता है, जैसे एक स्ट्रिंग के लिए एक इंट्यू वैल्यू असाइन नहीं कर सकता है। हालाँकि आप एक फ्लोट मान को एक डबल में असाइन कर सकते हैं क्योंकि यहां आप चौड़ा कर रहे हैं (C # आपके लिए इसे संक्षेप में रूपांतरित कर देगा क्योंकि कोई सटीक खो नहीं जाएगा)।
डेव न्यू


@AVD हालांकि यह एक डुप्लिकेट है, ऊपर दिया गया प्रश्न शीर्षक आपके लिंक को संभावित डुप्लिकेट सूची में नहीं देता है। तो यह कम से कम अधिक खोज मानदंडों के संदर्भ में मूल्य जोड़ सकता है।
एडम हल्ड्सवर्थ

1
@AdamHouldsworth - सभी सड़क के लिए जाता है double & int
adatapost

जवाबों:


96

फ्लोट की आपकी घोषणा में दो भाग होते हैं:

  1. यह घोषणा करता है कि चर timeRemainingप्रकार का है float
  2. यह 0.58इस वैरिएबल को मान प्रदान करता है ।

समस्या भाग 2 में होती है।

दाहिने हाथ की ओर का मूल्यांकन किया जाता है। C # विनिर्देशन के अनुसार, एक संख्या जिसमें एक दशमलव बिंदु है जिसमें एक प्रत्यय नहीं है एक के रूप में व्याख्या की गई है double

इसलिए अब हमारे पास एक doubleमूल्य है जो हम एक प्रकार के चर को असाइन करना चाहते हैं float। ऐसा करने के लिए, वहाँ से एक अंतर्निहित रूपांतरण होना चाहिए doubleकरने के लिए float। ऐसा कोई रूपांतरण नहीं है, क्योंकि आप (और इस मामले में) रूपांतरण में जानकारी खो सकते हैं।

कारण यह है कि संकलक द्वारा उपयोग किया जाने वाला मान वास्तव में 0.58 नहीं है, लेकिन फ़्लोटिंग-पॉइंट मान 0.58 के सबसे करीब है, जो कि 0.57999999999999978655962351581366 है ... doubleऔर बिल्कुल 0.5799999460596478271484375 के लिए float

कड़ाई से बोलना, fआवश्यक नहीं है। आप fमान का उपयोग करके प्रत्यय का उपयोग करने से बच सकते हैं float:

float timeRemaining = (float)0.58;

4
दो सवाल, आप '0.579999946057796478271484375' नंबर पर कैसे पहुंचे, और कैसे (float) 0.58काम करेंगे ? आपने पहले कहा था कि कोई रूपांतरण नहीं है, क्योंकि जानकारी खो सकती है, फिर कलाकार कैसे काम करेंगे?
सेक्सीबिट

8
1. मैंने विंडोज कैलकुलेटर का इस्तेमाल किया, जो 34 अंकों तक का उपयोग करता है। 2. मैंने कहा कि इसका कोई निहितार्थ नहीं है । एक कास्ट एक स्पष्ट रूपांतरण है, इसलिए आप स्पष्ट रूप से संकलक को बता रहे हैं कि आप रूपांतरण चाहते हैं, और इसकी अनुमति है।
जेफरी सैक्स

दिलचस्प ... मुझे उम्मीद है कि आप अभी भी इस पोस्ट की निगरानी कर रहे हैं। मुझे पहले से देखे जा रहे वेबकास्ट के लिए 'मी' में चलने वाले प्रत्ययों से परिचय हुआ। आपको फ्लोट वैल्यू के रूप में .58 प्रदर्शित करने के लिए विंडोज कैलकुलेटर कैसे मिला? मैंने एक दो बटन आज़माए जो दिखते थे कि वे ऐसा होने के लिए मजबूर करेंगे लेकिन नहीं ... 0.58 मिलते रहे। मुझे एक ऐसे आदमी का सम्मान करना है जो अपने औजारों को इतनी अच्छी तरह जानता है ...
user1585204

मैं फ्लोट के लिए पूरी एफ चीज को समझता हूं लेकिन क्यों? जब आपने घोषित किया चर को इसे एक फ्लोट के रूप में घोषित किया जाता है तो संकलित होने पर यह जानना चाहिए कि यह मान एक फ्लोट है। और जब आप एक ही समान घोषित करते हैं। इसका कोई मतलब नहीं है क्योंकि आपके पास फ्लोट मायवेल्यू = 2.4 है; अब जब संकलित किया जाना चाहिए संकलक को पहले से ही पता होना चाहिए कि चर का प्रकार है। क्या मैं कुछ भूल रहा हूँ? धन्यवाद!
फ्रैंक जी।

@FrankG। दो कारण हैं: 1. अभिव्यक्ति 2.4की व्याख्या हर जगह एक दुसरे के रूप में की जाती है। 2. व्यापक संकीर्ण रूपांतरण (जैसे डबल से फ्लोट तक) की अनुमति नहीं है। यदि आप इन नियमों को अपवाद बनाना चाहते हैं, तो आपके पास एक बहुत अच्छा कारण होना चाहिए। 1 कुंजी स्ट्रोक को सहेजना काफी अच्छा होने की संभावना नहीं है।
जेफरी सैक्स

36

क्योंकि वहाँ कई सांख्यिक प्रकार है कि संकलक मूल्य का प्रतिनिधित्व करने के लिए उपयोग कर सकते हैं 0.58: float, doubleऔर decimal। जब तक आप संकलक के साथ एक के लिए ठीक नहीं होते हैं, तब तक आपको मना करना होगा।

दस्तावेज़ में doubleकहा गया है कि यदि आप स्वयं उस प्रकार को निर्दिष्ट नहीं करते हैं जो संकलक हमेशा doubleकिसी वास्तविक संख्यात्मक शाब्दिक के प्रकार के रूप में करता है:

डिफ़ॉल्ट रूप से, असाइनमेंट ऑपरेटर के दाईं ओर एक वास्तविक संख्यात्मक शाब्दिक रूप में दोहरा व्यवहार किया जाता है। हालाँकि, यदि आप चाहते हैं कि पूर्णांक संख्या को डबल माना जाए, तो प्रत्यय d या D का उपयोग करें।

प्रत्यय लगाना fएक बनाता है float; प्रत्यय dएक बनाता है double; प्रत्यय mएक बनाता है decimal। ये सभी अपरकेस में भी काम करते हैं।

हालांकि, यह समझाने के लिए अभी भी पर्याप्त नहीं है कि यह क्यों संकलन नहीं करता है:

float timeRemaining = 0.58;

जवाब की याद आ रही आधा है कि रूपांतरण से है double 0.58करने के लिए float timeRemainingसंभावित रूप से जानकारी खो देता है, तो संकलक यह परोक्ष लागू करने के लिए मना कर दिया। यदि आप एक स्पष्ट कास्ट जोड़ते हैं तो रूपांतरण किया जाता है; यदि आप fप्रत्यय जोड़ते हैं तो किसी रूपांतरण की आवश्यकता नहीं होगी। दोनों मामलों में कोड फिर संकलित होगा।


लेकिन यह एक डबल या एक दशमलव कैसे हो सकता है यदि चर एक फ्लोट है, तो मुझे कुछ याद आ रहा है
थॉमस

@BlazArt हाँ, वाक्य जो संकलक को बताता है वह असाइनमेंट लक्ष्य को जांचने की कोशिश भी नहीं करता है। इसका कारण कंपाइलर टीम द्वारा बनाए गए डिज़ाइन विकल्पों में दफन किया जाएगा। मुझे लगता है कि संभव भ्रम की स्थिति में स्पष्ट होना सबसे अच्छा है, या केवल दो नियमों के बजाय, एक के लिए intऔर एक के लिए कार्यान्वयन को परेशान करना बहुत महंगा है double
एडम हल्ड्सवर्थ

@BlazArt: जवाब खत्म करने के लिए बस fleshing समाप्त, कृपया एक बार फिर से देखें।
जॉन

1
सूचना के नुकसान के बारे में, क्या आप मुझे बता सकते हैं कि वास्तव में कलाकारों को किस तरह से IEEE 754 प्रारूप में संग्रहीत किया जाता है? डबल में उच्च सटीकता है, तो क्या इसका मतलब है कि फ्लोट से डबल तक कास्ट हमेशा काम करेगा, जैसे double a = 0.69f;?
सेक्सीबीट

@Cupidvogel: हाँ, युक्ति की गारंटी देता है (.26.1.2 में) कि "अन्य निहित सांख्यिक रूपांतरण कभी भी कोई जानकारी नहीं खोते हैं", जिसमें अन्य लोगों floatको परिवर्तित करना शामिल है double
जॉन

2

समस्या यह है कि .NET, कुछ प्रकार के निहित संचालन को शामिल करने की अनुमति देने के लिए , floatऔर इसमें doubleया तो स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता है कि मिश्रित परिदृश्यों को शामिल करने वाले सभी परिदृश्यों में क्या होना चाहिए या एक में प्रदर्शन किए जाने वाले प्रकारों के बीच निहित रूपांतरणों की अनुमति दें केवल दिशा; Microsoft ने उस दिशा की अनुमति देने में जावा के नेतृत्व का अनुसरण करने का विकल्प चुना, जो कभी-कभी परिशुद्धता का पक्षधर होता है, लेकिन बार-बार शुद्धता का त्याग और आम तौर पर परेशानी पैदा करता है।

लगभग सभी मामलों में, वह 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,87013 से बंद है) के लिए होगा। सामान्य तौर पर, हालांकि, doubleकुछ मात्रा का सबसे अच्छा प्रतिनिधित्व परिवर्तित करने floatसे या तो सर्वोत्तम संभव floatप्रतिनिधित्व प्राप्त होगा, या दो अभ्यावेदन में से एक होगा जो अनिवार्य रूप से बहुत अच्छा होगा।

ध्यान दें कि यह वांछनीय व्यवहार चरम सीमा पर भी लागू होता है; उदाहरण के लिए, floatमात्रा 10 ^ 308 के floatलिए सबसे अच्छा doubleप्रतिनिधित्व उस मात्रा के सर्वश्रेष्ठ प्रतिनिधित्व को परिवर्तित करके प्राप्त किए गए प्रतिनिधित्व से मेल खाता है । इसी तरह, float10 ^ 309 floatका सबसे अच्छा doubleप्रतिनिधित्व उस मात्रा का सबसे अच्छा प्रतिनिधित्व परिवर्तित करके प्राप्त प्रतिनिधित्व से मेल खाता है ।

दुर्भाग्य से, एक स्पष्ट कलाकारों की आवश्यकता नहीं है कि दिशा में रूपांतरण शायद ही कभी कहीं भी सटीक के रूप में निकट हैं। floatमूल्य के सर्वोत्तम प्रतिनिधित्व को परिवर्तित करने doubleसे शायद ही कभी doubleउस मूल्य के सर्वश्रेष्ठ प्रतिनिधित्व के करीब कुछ भी प्राप्त होगा , और कुछ मामलों में परिणाम परिमाण के सैकड़ों आदेशों से बंद हो सकता है (जैसे float10 ^ 40 का सबसे अच्छा प्रतिनिधित्व परिवर्तित करने के लिए doubleउपज प्राप्त कर सकते हैं) एक मान जो double10 ^ 300 के सर्वश्रेष्ठ प्रतिनिधित्व की तुलना में अधिक है ।

काश, रूपांतरण नियम वे क्या हैं, इसलिए किसी को "सुरक्षित" दिशा में मूल्यों को परिवर्तित करते समय मूर्खतापूर्ण टाइपकास्ट और प्रत्यय का उपयोग करके जीना पड़ता है, और खतरनाक दिशा में निहित टाइपकास्ट से सावधान रहना चाहिए जो अक्सर द्विगुणित परिणाम देगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.