कोड जो एक मान को एक अलग प्रतिनिधित्व में परिवर्तित करता है, फिर उसे वापस उसी स्थान पर परिवर्तित करता है जहां से शुरू हुआ यह खराब है, लेकिन कैसे? [बन्द है]


35

मैं खराब प्रोग्रामिंग प्रथाओं के बारे में एक लेख पढ़ रहा था ।

यह उल्लेख किया -

"यो-यो कोड" जो एक मान को एक अलग प्रतिनिधित्व में परिवर्तित करता है, फिर उसे वापस उसी स्थान पर परिवर्तित करता है जहां से शुरू हुआ था (जैसे: दशमलव को एक स्ट्रिंग में बदलना और फिर वापस दशमलव में बदलना, या एक स्ट्रिंग को पैडिंग करना और फिर उसे ट्रिम करना)

मुझे समझ में नहीं आता कि वह जो विशेष उदाहरण देता है वह प्रोग्राम लिखने का एक बुरा तरीका है। यदि स्थिति को इसकी आवश्यकता है तो इसका उपयोग करना उचित है, ताकि मूल्य का उपयोग किया जा सके।

क्या कोई इस बारे में अधिक बता सकता है?


4
अनुशंसित पढ़ने: इस $ {ब्लॉग} पर चर्चा करें
gnat

8
ज्यादातर समय यह केवल निरर्थक होता है और यह केवल इसलिए होता है क्योंकि प्रोग्रामर को यह जानने का कोई बेहतर तरीका नहीं था कि वे क्या चाहते हैं। ब्लॉग प्रविष्टि कुछ पैराग्राफों को बाद में एक विशिष्ट उदाहरण देता है "Roundabout code" that accomplishes in many instructions what could be done with far fewer (eg: rounding a number by converting a decimal into a formatted string, then converting the string back into a decimal):। if the situation is so that they have to be used?- वह क्या स्थिति होगी?
कोनराड मोरावस्की

3
@gnat मुझे नहीं मिलता कि यह कैसे एक बुरा सवाल है। यदि आप चाहते हैं कि मैं इसे कहने के लिए संपादित कर सकता हूं "कोड है जो धर्मान्तरित करता है और एक मान खराब करता है?" और यह उस टेम्पलेट को अब फिट नहीं करेगा।
djechlin

5
मैंने हाल ही में जावा में कोड पाया है जो एक सरणी पर पुनरावृत्त करता है, प्रत्येक ऑब्जेक्ट को JSON ऑब्जेक्ट में क्रमबद्ध करता है, स्ट्रिंग कॉन्सेनटेशन का उपयोग करते हुए, एक JSON धारावाहिक नहीं। परिणाम को फिर एक निजी पद्धति में पारित किया गया, जिसने आईडी की एक गुच्छा निकालने के लिए JSON सरणी को पार्स किया, फिर आईडी का कहीं और पास किया। यह सिस्टम में उस JSON सरणी का एकमात्र उपयोग था। यह यो-यो कोड है। आगे और पीछे परिवर्तन का कोई कारण नहीं था। हम मूल वस्तुओं से केवल आईडी पास कर सकते थे।
ब्रैंडन

3
decimal myValue = decimal.Parse(dataReader["myColumn"].ToString())मेरा एक पालतू जानवर है।
मैथ्यू

जवाबों:


125

यहां तक कि अगर आप ऐसा जरूरत दोनों संख्यात्मक और एक नंबर की स्ट्रिंग प्रतिनिधित्व, यह बजाय फिर हर बार जब आप एक या दूसरे की जरूरत है परिवर्तित करने की, बस एक बार बदलने और भी वास्तविक मान पर बने रहने से बेहतर है।

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


5
ख़ूब कहा है। हम प्रोग्रामर सभी को इतना सतर्क रहना चाहिए।
नील

58
"कोड जो अस्तित्व में नहीं है, उसमें सूक्ष्म दोष नहीं हो सकते हैं, जबकि कोड जो अक्सर मौजूद होता है" काश मैं उसके लिए +2 आप कर सकता था। कोड न लिखने के मूल्य को कभी भी कम न समझें।
बेंजामिन ग्रुएनबाम

2
लेकिन बिट्स में हेरफेर करने के "सही" तरीके की तुलना में सरल ऑपरेशन के कुछ जोड़े (स्ट्रिंग और बैक में कन्वर्ट) बहुत कम जटिल (समझने और कोड करने में आसान) हो सकते हैं। और एक श्रेणी में सभी डेटा को एक ही रूप में रखना अक्सर एक अच्छा विचार होता है, भले ही कुछ निश्चित डेटा को अनिवार्य रूप से अन्य रूपों में बदल दिया जाए।
डैनियल आर हिक्स

36
@DanielRHicks तो आइए उस साधारण तारीख (10 नवंबर 2014) को एक स्ट्रिंग में परिवर्तित करते हैं, -> 10-11-2014 और एक तारीख को वापस -> (11 ओकट्रब 2014) अरे रुको क्या?
पीटर बी

20
@PieterB एक बड़ा जर्मन अकाउंटिंग सॉफ्टवेयर है जो गैर जर्मन लोकेल के साथ कंप्यूटर पर काम नहीं करता है क्योंकि यह ऐसा करता है। यह पहले सिस्टम लोकेल का उपयोग करके तारीख को स्ट्रिंग में परिवर्तित करता है और फिर एक निश्चित स्थान के साथ पार्स करने की कोशिश करता है और अवैध प्रारूप के बारे में शिकायत करता है। यह संख्याओं और भिन्न दशमलव विभाजकों के साथ भी ऐसा ही करता है, सिवाय इसके कि यह वहाँ कोई शिकायत नहीं करता है, यह डेटा को दूषित करता है और अजीब व्यवहार प्रदर्शित करता है। मुझे लगता है कि एक दिन के लिए ले लिया।
कोडइन्चोस

23

यह तीन प्रमुख कारणों से खराब है:

  1. यह दर्शाता है कि आपने इस बारे में नहीं सोचा है कि चर वास्तव में किस प्रकार / प्रारूप में होना चाहिए, लेकिन इसके बजाय आप इसे उस समय की आवश्यकता के अनुसार परिवर्तित कर रहे हैं। यह डिजाइन विचार की कमी को दर्शाता है।
  2. शायद यह बेकार है। आप लगभग निश्चित रूप से साइकिल और कोड की पंक्तियों को बर्बाद कर रहे हैं, रूपांतरण कर रहे हैं जो वहां होने की आवश्यकता नहीं है। यह आपके कोड को धीमा कर देगा और जितना होना चाहिए उससे अधिक फूला हुआ होगा।
  3. प्रकार रूपांतरण सूक्ष्म त्रुटियों के लिए प्रवण हैं। अपने कोड के माध्यम से इन रूपांतरणों को रद्द करके आप त्रुटि की संभावना बढ़ा रहे हैं।

मुझे संदेह है कि कारण 1 कारण है कि आपका स्रोत उस संदर्भ के आधार पर सोच रहा था जिसमें इसका उल्लेख किया गया था।


6

मैं वर्णन को "कोड के रूप में फिर से बताऊंगा जो एक प्रकार को एक अलग प्रतिनिधित्व करने के लिए कुछ करने के उद्देश्य से परिवर्तित करता है जो मूल रूप में या तो बेहतर या बेहतर हो सकता था और फिर इसे वापस रूपांतरित करता है। कई परिस्थितियां हैं जहां कुछ को एक में परिवर्तित करना। विभिन्न प्रकार, उस पर अभिनय करना, और इसे वापस परिवर्तित करना पूरी तरह से उचित है और ऐसा करने में विफलता गलत व्यवहार का परिणाम होगा।

एक उदाहरण के रूप में जहां रूपांतरण अच्छा है:
एक में floatमनमाने संकेतों के चार मूल्य हैं जिनकी परिमाण 1,000 तक के कारक से भिन्न हो सकती है, और अंतिम स्थान पर 0.625 इकाइयों के भीतर राशि की गणना करने की आवश्यकता है। सभी चार मूल्यों को परिवर्तित करना double, योग की गणना करना, और परिणाम को वापस रूपांतरित floatकरना floatअकेले की तुलना में किसी भी दृष्टिकोण की तुलना में बहुत अधिक कुशल होगा ।
अंतिम स्थान (ULP) में 0.5 यूनिट तक फ्लोटिंग-पॉइंट वैल्यू सबसे सही हैं। इस उदाहरण के लिए आवश्यक है कि सबसे खराब स्थिति वाली त्रुटि से अधिकतम 25% से अधिक खराब राउंडिंग त्रुटि हो। डबल का उपयोग करने से एक मान प्राप्त होगा जो 0.5001 ULP के भीतर सटीक होगा। जबकि एक 0.625 ULP आवश्यकता से वंचित लग सकता है, इस तरह की आवश्यकताओं को अक्सर क्रमिक-सन्निकटन एल्गोरिदम में महत्वपूर्ण हैं। अधिक कसकर त्रुटि की सीमा निर्दिष्ट की जाती है, सबसे कम मामले में चलने की आवश्यकता कम होती है।

एक उदाहरण के रूप में जहां रूपांतरण खराब है:
किसी के पास एक फ्लोटिंग-पॉइंट संख्या है, और एक स्ट्रिंग को आउटपुट करने की इच्छा रखता है जो विशिष्ट रूप से इसके मूल्य का प्रतिनिधित्व करेगा। एक दृष्टिकोण यह है कि एक निश्चित संख्या में अंकों के साथ संख्या को स्ट्रिंग में परिवर्तित करना, इसे वापस बदलने की कोशिश करना, और देखें कि क्या परिणाम मेल खाता है।

लेकिन यह वास्तव में एक खराब दृष्टिकोण है। यदि एक दशमलव स्ट्रिंग एक मान का प्रतिनिधित्व करती है जो दो फ़्लोटिंग-पॉइंट मानों के बीच आधे बिंदु पर लगभग ठीक बैठता है, तो यह स्ट्रिंग-टू-फ्लोट विधि के लिए काफी महंगा है, यह गारंटी देता है कि यह हमेशा निकटतम floatमूल्य प्राप्त करेगा , और ऐसे कई रूपांतरण तरीके डॉन 'ऐसी गारंटी को बरकरार रखें (अन्य बातों के अलावा, ऐसा करने से कुछ मामलों में किसी संख्या के सभी अंकों को पढ़ने की आवश्यकता होगी, भले ही वह अरबों अंकों का हो)।

यह गारंटी देने के लिए एक विधि के लिए बहुत सस्ता है कि यह हमेशा एक मान लौटाएगा जो प्रतिनिधित्व मूल्य के अंतिम स्थान (ULP) में 0.5625 इकाइयों के भीतर है। एक मजबूत "प्रतिवर्ती" दशमलव-से-स्ट्रिंग प्रारूपण रूटीन की गणना करनी चाहिए कि आउटपुट वैल्यू सही मान से कितनी दूर है, और आउटपुट अंक तब तक जारी रखें जब तक कि परिणाम 0.375 (ULP) के भीतर न हो, यदि 0.25 (ULP) न हो। अन्यथा, यह एक स्ट्रिंग का उत्पादन कर सकता है जो कुछ रूपांतरण विधियों को सही ढंग से संसाधित करेगा, लेकिन अन्य रूपांतरण विधियां नहीं होंगी।

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


1
आपका उदाहरण मूल मान नहीं लौटाता है जो ओपी के बारे में पूछ रहा है। यह केवल एक ही प्रकार के साथ एक मान लौटाता है, जिसकी गणना कई इनपुट से की जाती है।
CJ डेनिस

2

कई कारणों से

  1. यह व्यर्थ है और जटिलता को जोड़ता है - दोनों को लिखने और बनाए रखने के लिए कोड की मात्रा में, और आवश्यक सीपीयू समय की मात्रा

    1. यह सटीकता या बदतर खो सकता है, पूरी तरह से मूल्य को भ्रष्ट कर सकता है

    2. यह स्मृति को बर्बाद कर देता है (संभावित रूप से, भाषा पर निर्भर करता है) जैसा कि आप एक संख्या के अधिक प्रतिनिधित्व को समाप्त करते हैं जो आपको चाहिए

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


इससे किए गए बिंदुओं पर कुछ भी पर्याप्त नहीं लगता है और पूर्व उत्तर में समझाया गया है
gnat

2
क्या यह एक वोट को सही ठहराता है? मुझे विश्वास है कि मेरी पोस्ट संभावित रूप से अधिक संक्षिप्त है
जॉन स्टोरी

पहले के उत्तर वास्तव में मेरे लिए और अधिक संक्षिप्त लगते हैं, दोनों में
gnat

0

क्यूं कर? क्योंकि हममें से सर्वश्रेष्ठ भी गलतियां कर सकते हैं।

जब Microsoft ने एक "गोल-यात्रा" प्रारूप लागू करने का प्रयास किया, तो विशेष रूप से सुनिश्चित करें कि फ्लोट <-> स्ट्रिंग रूपांतरण सुरक्षित थे: https://stackoverflow.com/q/24299692/541686


0

जब मैं स्कूल में था (और इलेक्ट्रिकल इंजीनियरिंग में पोस्ट स्कूल) तो हमें गुणा करने के बाद विभाजित करना सिखाया गया था। विभाजन अक्सर कई अंकों और गोल हो जाते हैं। विभाजन के बाद गुणा करने से विभाजन त्रुटि गुणा होती है।

प्रकार रूपांतरण समान हैं, आप डेटा खोने का जोखिम उठाते हैं। CInt (1.3) = 1।

मेरी भाषा में, बेसिक, हम केवल रूपांतरण करते हैं (एक VB6 प्रोग्राम 90% समय व्यतीत करता है, यह ANSI / यूनिकोड रूपांतरण कर रहा है, सभी एपीआई कॉल रनटाइम बनाता है)।

टाइप कन्वर्जन हम सभी में निहित है।

 Print 5

स्ट्रिंग "5" संख्यात्मक शाब्दिक से मुद्रित होता है।

form1.caption = "My Form"

यूनीकोड ​​स्ट्रिंग शाब्दिक ANSI स्ट्रिंग में परिवर्तित हो जाता है और प्रपत्र पैकेज द्वारा SetWindowsTextA को भेज दिया जाता है।

यहां तक ​​कि यह बुनियादी काम करता है

a = "5"
b = 3

c = a + b (= 8)

मैं इन दिनों एक वैरिएंट प्रोग्रामर हूं - मैं टाइप के बारे में भी नहीं सोचता। मैं सिर्फ निरंकुशता पर भरोसा करता हूं।

वैसे भी मेरे 3 पालतू जानवर हैं

उन्हें उपयोग करने के लिए चर शाब्दिक स्ट्रिंग वेरिएबल को असाइन करना (स्मृति और धीमी गति से अपशिष्ट)

जब कोड इनलाइन हो सकता है तब व्यर्थ कार्य (और कंपाइलर संभवतः आपके फ़ंक्शन को पूर्ववत कर देगा और वैसे भी इनलाइन कर सकता है)

अंतिम कार्य या कार्यक्रम के अंत से पहले अंतिम पंक्ति के रूप में कुछ भी नहीं करने के लिए सभी वस्तुओं की स्थापना।

और छोटे कार्यक्रमों के लिए एक 4 था

5 लाइन प्रोग्राम में अपने 3 वेरिएबल्स को व्यर्थ रूप से डिमिंग करते हुए।

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