एक जादू नंबर क्या है, और यह खराब क्यों है? [बन्द है]


514

मैजिक नंबर क्या है?

इससे क्यों बचना चाहिए?

क्या ऐसे मामले हैं जहां यह उचित है?


2
आप जादू की संख्या से बचने के कारण अन्य लोगों को आपके कोड को देखकर समझ नहीं पाएंगे कि आप ऐसा क्यों कर रहे हैं जो आप कर रहे हैं ... जैसे const myNum = 22; const number = myNum / 11;अभी मेरा 11 लोग या बीयर की बोतल या कुछ और हो सकता है इसलिए इसके बजाय मैं 11 को लगातार बदलूंगा जैसे कि निवासी।
JuicY_Burrito

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

जवाबों:


574

एक जादू संख्या कोड में एक संख्या का प्रत्यक्ष उपयोग है।

उदाहरण के लिए, यदि आपके पास (जावा में):

public class Foo {
    public void setPassword(String password) {
         // don't do this
         if (password.length() > 7) {
              throw new InvalidArgumentException("password");
         }
    }
}

यह करने के लिए refactored किया जाना चाहिए:

public class Foo {
    public static final int MAX_PASSWORD_SIZE = 7;

    public void setPassword(String password) {
         if (password.length() > MAX_PASSWORD_SIZE) {
              throw new InvalidArgumentException("password");
         }
    }
}

यह कोड की पठनीयता में सुधार करता है और इसे बनाए रखना आसान है। उस मामले की कल्पना करें जहां मैंने GUI में पासवर्ड फ़ील्ड का आकार सेट किया है। यदि मैं एक मैजिक नंबर का उपयोग करता हूं, जब भी अधिकतम आकार बदलता है, मुझे दो कोड स्थानों में बदलना होगा। अगर मैं एक भूल करता हूं, तो इससे विसंगतियां होंगी।

JDK Integer, Characterऔर Mathवर्गों जैसे उदाहरणों से भरा है ।

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


174
0 और 1 इस नियम के अपवाद हैं।
जोनाथन पार्कर

24
@Kirill: यदि आप "हंड्रेड पर्चेस" की परिभाषा को बदलने की उम्मीद करते हैं, तो हाँ। एक बेहतर तरीका यह होगा कि वह वैसा ही हो जैसा कि वह प्रतिनिधित्व करता है, यानी सार्वजनिक स्थैतिक अंतिम MAX_DOWNLOAD_PERCENTAGE = 100। यह समझ में नहीं आता है, क्योंकि "100 प्रतिशत" बहुत अच्छी तरह से परिभाषित है। दूसरी ओर, तथ्य यह है कि पासवर्ड अधिकतम 7 वर्णों का हो सकता है, जो विश्व स्तर पर परिभाषित नहीं है और वास्तव में भिन्न है, इसलिए यह एक चर के लिए एक उम्मीदवार है।
माइकल Stum

40
@ जोनाथन पार्कर, सिवाय जब वे नहीं ( TRUE/ FALSE)
ब्रेंडन लॉन्ग

82
सिर्फ इसलिए कि एक जादू की संख्या कभी नहीं बदलेगी इसका मतलब यह नहीं है कि इसे एक स्थिर द्वारा प्रतिस्थापित नहीं किया जाना चाहिए। मेरा कोड HzPerMHz और msecPerSecond जैसे वैश्विक स्थिरांक से भरा है। ये कभी नहीं बदलेंगे, लेकिन वे अर्थ को स्पष्ट करते हैं, और टाइपोस के खिलाफ कुछ सुरक्षा प्रदान करते हैं।
जीन पिंडार

43
@MarcusJ आप अधिक गलत नहीं हो सकते। यह कई प्रोग्रामरों की राय का नहीं, बल्कि कठिन परिश्रम का अनुभव है। मैं आपको बता नहीं सकता कि प्रोग्रामिंग के पिछले 40 वर्षों में कितनी बार, कि मैंने एक पिछले प्रोग्रामर को शाप दिया है, जो एक स्थिरांक को परिभाषित नहीं करता है, इसलिए मैंने केवल एक नंबर का प्रत्यक्ष उपयोग खोजा, जिसे कोड रखरखाव के दौरान समझने की आवश्यकता थी , बहुत सारे कोड में कहीं दफनाया गया है, जिसका अर्थ ऐसे स्थिरांक को परिभाषित करके स्पष्ट किया गया होगा। किसी भी अन्य वरिष्ठ प्रोग्रामर के पास इस लाइन के साथ कई डरावनी कहानियां होंगी।
टूलमेकरसेव

145

मैजिक नंबर एक हार्ड-कोडेड मान है जो बाद के चरण में बदल सकता है, लेकिन इसलिए इसे अपडेट करना कठिन हो सकता है।

उदाहरण के लिए, मान लें कि आपके पास एक पृष्ठ है जो "आपके आदेश" अवलोकन पृष्ठ में अंतिम 50 आदेश प्रदर्शित करता है। 50 यहां मैजिक नंबर है, क्योंकि यह मानक या सम्मेलन के माध्यम से सेट नहीं है, यह एक संख्या है जिसे आपने कल्पना में उल्लिखित कारणों से बनाया है।

अब आप क्या करते हैं, आपके पास अलग-अलग जगहों पर 50 हैं - आपकी एसक्यूएल स्क्रिप्ट (SELECT TOP 50 * FROM orders ), आपकी वेबसाइट (आपका अंतिम 50 आदेश), आपका ऑर्डर लॉगिन ( for (i = 0; i < 50; i++)) और संभवतः कई अन्य स्थान।

अब, क्या होता है जब कोई व्यक्ति 50 से 25 को बदलने का फैसला करता है? या 75५? या 153? अब आपको सभी स्थानों पर 50 को बदलना होगा, और आप इसे मिस करने की बहुत संभावना है। ढूँढें / बदलें काम नहीं कर सकते हैं, क्योंकि 50 का उपयोग अन्य चीजों के लिए किया जा सकता है, और नेत्रहीन 50 की जगह 25 के साथ कुछ अन्य दुष्प्रभाव हो सकते हैं (अर्थात आपका)Session.Timeout = 50 कॉल, जो 25 पर भी सेट है और उपयोगकर्ता बहुत अधिक समय समाप्त करना शुरू कर देते हैं)।

इसके अलावा, कोड को समझना मुश्किल हो सकता है, "if a < 50 then bla " - यदि आप एक जटिल फ़ंक्शन के बीच में मुठभेड़ करते हैं, तो अन्य डेवलपर्स जो कोड से परिचित नहीं हैं वे खुद से पूछ सकते हैं "डब्ल्यूटीएफ 50 है ???"

यही कारण है कि इस तरह के अस्पष्ट और मनमानी संख्याओं को ठीक 1 स्थान पर रखना सबसे अच्छा है - "const int NumOrdersToDisplay = 50 ", क्योंकि यह कोड को अधिक पठनीय बनाता है (" if a < NumOrdersToDisplay", इसका मतलब यह भी है कि आपको इसे 1 अच्छी तरह से परिभाषित जगह में बदलने की आवश्यकता है।

ऐसी जगहें जहां मैजिक नंबर उपयुक्त हैं, वह सब कुछ है जो एक मानक के माध्यम से परिभाषित किया गया है, SmtpClient.DefaultPort = 25या TCPPacketSize = whatever(यदि यह मानकीकृत है तो निश्चित नहीं है)। साथ ही, केवल 1 फ़ंक्शन के भीतर परिभाषित सब कुछ स्वीकार्य हो सकता है, लेकिन यह संदर्भ पर निर्भर करता है।


18
यहां तक ​​कि अगर यह नहीं बदल सकता है यह अभी भी एक बुरा विचार है क्योंकि यह स्पष्ट नहीं है कि क्या चल रहा है।
लोरेन Pechtel

11
यह हमेशा अस्पष्ट नहीं है। SmtpClient.DefaultPort = 25संभवतः की तुलना में स्पष्ट एर है SmtpClient.DefaultPort = DEFAULT_SMTP_PORT
user253751

4
@ मुझे लगता है कि मान लिया गया है कि DEFAULT_SMTP_PORT की अवधारणा का उपयोग करने वाला कोई अन्य कोड नहीं है। यदि उस एप्लिकेशन के लिए डिफ़ॉल्ट SMTP पोर्ट को बदल दिया जाता है, तो असंगतता की संभावना के कारण इसे कई स्थानों पर अपडेट करना होगा।
बजे रस ब्रैडबेरी

3
सभी उपयोगों को ढूंढना भी कठिन है - आपको 25आवेदन के लिए पूरी खोज करनी होगी और यह सुनिश्चित करना होगा कि आप केवल 25एसएमटीपी पोर्ट के लिए ही बदलाव करें , 25 का नहीं, जैसे कि टेबल कॉलम या संख्या की चौड़ाई। किसी पृष्ठ पर दिखाने के लिए अभिलेखों का।
माइकल स्टम

2
उस उदाहरण में, मुझे उम्मीद है कि कोड SmtpClient.DefaultPort का उपयोग करेगा, 25 नहीं। इसलिए आपको इसे केवल एक स्थान पर बदलना होगा। और पोर्ट नंबर एक ही रहने की संभावना है, यह एक यादृच्छिक जादू नंबर नहीं है, लेकिन इसके द्वारा निर्दिष्ट संख्या है IANA
njsg

34

क्या आपने मैजिक नंबर के लिए विकिपीडिया प्रविष्टि पर एक नज़र डाली है ?

यह जादू की संख्या के संदर्भ में किए गए सभी तरीकों के बारे में विस्तार से बताता है। यहां एक बुरे प्रोग्रामिंग अभ्यास के रूप में जादू की संख्या के बारे में एक उद्धरण है

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


8
RTFW का अच्छा उदाहरण :)
ईवा

मैं कहूंगा कि उत्तर पूर्ण से बहुत दूर है।
स्कीव

25

जादू नंबर बनाम। प्रतीकात्मक लगातार: कब बदलना है?

जादू: अज्ञात शब्दार्थ

प्रतीकात्मक स्थिरांक -> उपयोग के लिए सही अर्थ और सही संदर्भ दोनों प्रदान करता है

शब्दार्थ: किसी वस्तु का अर्थ या उद्देश्य।

"एक स्थिरांक बनाएं, इसे अर्थ के बाद नाम दें, और इसके साथ संख्या बदलें।" - मार्टिन फाउलर

पहला, मैजिक नंबर सिर्फ नंबर नहीं हैं। कोई भी मूल मूल्य "जादू" हो सकता है। मूल मान प्रकट होते हैं जैसे कि पूर्णांक, वास्तविक, युगल, फ़्लोट, दिनांक, तार, बूलियन, वर्ण, इत्यादि। मुद्दा डेटा प्रकार नहीं है, लेकिन मूल्य का "जादू" जैसा कि हमारे कोड टेक्स्ट में दिखाई देता है।

"जादू" से हमारा क्या मतलब है? सटीक होने के लिए: "जादू" द्वारा, हम अपने कोड के संदर्भ में मूल्य के शब्दार्थ (अर्थ या उद्देश्य) को इंगित करना चाहते हैं; यह अज्ञात, अनजाना, अस्पष्ट या भ्रामक है। यह "जादू" की धारणा है। एक बुनियादी मूल्य जादू नहीं है जब इसका अर्थ अर्थ या उद्देश्य-का-होना, जल्दी और आसानी से जाना जाता है, स्पष्ट है, और विशेष सहायक शब्दों (जैसे प्रतीकात्मक स्थिर) के बिना आसपास के संदर्भ से समझा (भ्रमित नहीं) है।

इसलिए, हम कोड रीडर की क्षमता को जानने, स्पष्ट होने और उसके आसपास के संदर्भ से एक मूल मूल्य के अर्थ और उद्देश्य को समझकर जादू की संख्याओं की पहचान करते हैं। कम ज्ञात, कम स्पष्ट और अधिक भ्रमित पाठक, अधिक "जादू" मूल मूल्य है।

सहायक परिभाषाएँ

  • भ्रामक: कारण (कोई) भयभीत या हैरान हो जाना।
  • हतप्रभ: कारण (कोई) हैरान और भ्रमित हो जाना।
  • हैरान: पूरी तरह से चकित; बहुत हैरान हुए।
  • चकित: पूरी तरह से हतप्रभ या चंचल।
  • हैरान: समझने में असमर्थ; हैरान।
  • समझ: (शब्दों, एक भाषा, या वक्ता) के इच्छित अर्थ पर विचार करें।
  • अर्थ: शब्द, पाठ, अवधारणा या क्रिया से क्या अभिप्राय है।
  • का अर्थ है: (किसी विशेष बात या धारणा) को व्यक्त करना, इंगित करना या संदर्भित करना; दर्शाता है।
  • संकेत: एक संकेत हो।
  • संकेत: एक संकेत या सूचना का टुकड़ा जो कुछ इंगित करता है।
  • इंगित करें: इंगित करें; प्रदर्शन।
  • संकेत: एक वस्तु, गुणवत्ता, या घटना जिसकी उपस्थिति या घटना किसी अन्य चीज की संभावित उपस्थिति या घटना को इंगित करती है।

मूल बातें

हमारे पास हमारे जादुई बुनियादी मूल्यों के लिए दो परिदृश्य हैं। केवल दूसरा प्रोग्रामर और कोड के लिए प्राथमिक महत्व का है:

  1. एक अकेला बुनियादी मूल्य (उदाहरण संख्या) जिसमें से इसका अर्थ अज्ञात, अनजाना, अस्पष्ट या भ्रमित है।
  2. संदर्भ में एक बुनियादी मूल्य (उदाहरण के लिए संख्या), लेकिन इसका अर्थ अज्ञात, अनजाना, अस्पष्ट या भ्रमित रहता है।

"जादू" की एक अधिभावी निर्भरता यह है कि अकेला बुनियादी मूल्य (जैसे संख्या) का कोई सामान्यतः ज्ञात अर्थ नहीं है (जैसे कि पीआई), लेकिन एक स्थानीय रूप से ज्ञात शब्दार्थ (जैसे आपका कार्यक्रम) है, जो संदर्भ से पूरी तरह से स्पष्ट नहीं है या दुरुपयोग किया जा सकता है अच्छे या बुरे संदर्भ में।

अधिकांश प्रोग्रामिंग भाषाओं के शब्दार्थ हमें डेटा (यानी डेटा की तालिका) के रूप में (शायद) को छोड़कर, अकेले बुनियादी मूल्यों का उपयोग करने की अनुमति नहीं देंगे। जब हम "जादुई संख्या" का सामना करते हैं, तो हम आम तौर पर एक संदर्भ में ऐसा करते हैं। इसलिए, का जवाब

"क्या मैं इस जादुई संख्या को प्रतीकात्मक स्थिरांक से बदल दूं?"

है:

"आप इसके संदर्भ में संख्या (इसके होने का उद्देश्य) के अर्थ का कितनी जल्दी आकलन और समझ सकते हैं?"

जादू की तरह, लेकिन काफी नहीं

इस विचार को ध्यान में रखते हुए, हम जल्दी से देख सकते हैं कि कैसे पाई (3.14159) जैसी संख्या उचित संदर्भ में रखे जाने पर "मैजिक नंबर" नहीं है (जैसे 2 x 3.14159 x त्रिज्या या 2 * पाई * आर)। यहां, 3.14159 की संख्या को मानसिक रूप से पहचाने जाने वाले निरंतर पहचानकर्ता के बिना पाई को मान्यता दी गई है।

फिर भी, हम आम तौर पर संख्या की लंबाई और जटिलता की वजह से पाई जैसे प्रतीकात्मक निरंतर पहचानकर्ता के साथ 3.14159 को प्रतिस्थापित करते हैं। पीआई की लंबाई और जटिलता के पहलुओं (सटीकता की आवश्यकता के साथ युग्मित) का मतलब आमतौर पर प्रतीकात्मक पहचानकर्ता या निरंतरता में त्रुटि की संभावना कम होती है। एक नाम के रूप में "पाई" की मान्यता बस एक सुविधाजनक बोनस है, लेकिन स्थिर होने का प्राथमिक कारण नहीं है।

उसी समय रैंच में

पाई जैसे सामान्य स्थिरांक को छोड़ते हुए, हम मुख्य रूप से विशेष अर्थ वाले संख्याओं पर ध्यान केंद्रित करते हैं, लेकिन जो अर्थ हमारे सॉफ्टवेयर सिस्टम के ब्रह्मांड के लिए विवश हैं। ऐसी संख्या "2" हो सकती है (मूल पूर्णांक मान के रूप में)।

यदि मैं अपने आप से नंबर 2 का उपयोग करता हूं, तो मेरा पहला सवाल यह हो सकता है: "2" का क्या अर्थ है? अपने आप से "2" का अर्थ अज्ञात और अनजाना है बिना संदर्भ के, इसके उपयोग को अस्पष्ट और भ्रमित करना। भले ही हमारे सॉफ्टवेयर में "2" होने के कारण भाषा शब्दार्थ नहीं होगा, लेकिन हम यह देखना चाहते हैं कि "2" अपने आप में कोई विशेष शब्दार्थ या स्पष्ट उद्देश्य नहीं रखता है।

आइए हमारे लोन को "2" के संदर्भ में रखें: padding := 2 जहां संदर्भ एक "जीयूआई कंटेनर" है। इस संदर्भ में 2 का अर्थ (पिक्सेल या अन्य चित्रमय इकाई के रूप में) हमें इसके शब्दार्थ (अर्थ और उद्देश्य) का एक त्वरित अनुमान प्रदान करता है। हम यहां रुक सकते हैं और कह सकते हैं कि 2 इस संदर्भ में ठीक है और हमें कुछ और जानने की आवश्यकता नहीं है। हालांकि, शायद हमारे सॉफ्टवेयर ब्रह्मांड में यह पूरी कहानी नहीं है। इसमें कुछ और भी है, लेकिन एक संदर्भ के रूप में "पैडिंग = 2" इसे प्रकट नहीं कर सकता है।

चलो आगे दिखाते हैं कि हमारे कार्यक्रम में 2 पिक्सेल पैडिंग हमारे सिस्टम में "default_padding" किस्म की है। इसलिए, निर्देश लिखना padding = 2पर्याप्त नहीं है। "डिफ़ॉल्ट" की धारणा सामने नहीं आई है। केवल जब मैं लिखता हूं: padding = default_paddingएक संदर्भ के रूप में और फिर कहीं और: default_padding = 2क्या मुझे पूरी तरह से हमारे सिस्टम में 2 के एक बेहतर और पूर्ण अर्थ (अर्थ और उद्देश्य) का एहसास है।

उपरोक्त उदाहरण बहुत अच्छा है क्योंकि "2" अपने आप में कुछ भी हो सकता है। केवल जब हम "मेरे प्रोग्राम" को समझने की सीमा और डोमेन को सीमित करते हैं, जहां 2 "मेरे प्रोग्राम" default_paddingके GUI UX भागों में होता है, तो क्या हम अंत में इसके उचित संदर्भ में "2" का अर्थ बनाते हैं। यहाँ "2" एक "मैजिक" नंबर है, जिसे default_padding"माई प्रोग्राम" के GUI UX के संदर्भ में एक सांकेतिक स्थिरांक के रूप में बताया गया है, ताकि इसे default_paddingकोडिंग के अधिक से अधिक संदर्भ में जल्दी से समझा जा सके।

इस प्रकार, कोई भी मूल मूल्य, जिसका अर्थ (अर्थ और उद्देश्य) पर्याप्त रूप से और जल्दी से नहीं समझा जा सकता है, मूल मूल्य (जैसे जादू संख्या) के स्थान पर एक प्रतीकात्मक निरंतर के लिए एक अच्छा उम्मीदवार है।

आगे बढ़ते हुए

एक पैमाने पर संख्याएँ शब्दार्थ भी हो सकती हैं। उदाहरण के लिए, दिखावा है कि हम एक डी एंड डी गेम बना रहे हैं, जहां हमारे पास एक राक्षस की धारणा है। हमारे राक्षस ऑब्जेक्ट में एक विशेषता है life_force, जो एक पूर्णांक है। संख्याओं के अर्थ हैं जो अर्थ देने के लिए शब्दों के बिना पता या स्पष्ट नहीं हैं। इस प्रकार, हम मनमाने ढंग से कहने से शुरू करते हैं:

  • full_life_force: INTEGER = 10 - बहुत सजीव (और अनसुना)
  • न्यूनतम_जीव_फोर्स: INTEGER = 1 - बमुश्किल जीवित (बहुत आहत)
  • dead: INTEGER = 0 - मृत
  • पूर्ववत्: INTEGER = -1 - न्यूनतम पूर्ववत् (लगभग मृत)
  • ज़ोंबी: INTEGER = -10 - अधिकतम मरे (बहुत पूर्ववत)

ऊपर के प्रतीकात्मक स्थिरांक से, हम अपने डी एंड डी गेम में हमारे राक्षसों के लिए एलियन, डेडनेस, और "अनडीनेस" (और संभावित प्रभाव या परिणाम) की मानसिक तस्वीर प्राप्त करना शुरू करते हैं। इन शब्दों (प्रतीकात्मक स्थिरांक) के बिना, हमें केवल संख्याओं से छोड़ दिया जाता है -10 .. 10। शब्दों के बिना बस सीमा हमें महान भ्रम की स्थिति में छोड़ देती है और संभावित रूप से हमारे खेल में त्रुटियों के साथ होती है यदि खेल के विभिन्न हिस्सों पर निर्भरता होती है कि संख्याओं की उस सीमा का अर्थ विभिन्न ऑपरेशनों जैसे attack_elvesया seek_magic_healing_potion

इसलिए, जब "मैजिक नंबरों" के प्रतिस्थापन की खोज और विचार करना चाहते हैं, तो हम अपने सॉफ़्टवेयर के संदर्भ में संख्याओं के बारे में बहुत ही उद्देश्य से भरे प्रश्न पूछना चाहते हैं और यहां तक ​​कि कैसे संख्याएं एक-दूसरे के साथ शब्दार्थ करती हैं।

निष्कर्ष

आइए समीक्षा करें कि हमें कौन से प्रश्न पूछने चाहिए:

आप एक जादू नंबर हो सकता है अगर ...

  1. क्या आपके सॉफ्टवेयर्स ब्रह्मांड में मूल मूल्य का कोई विशेष अर्थ या उद्देश्य हो सकता है?
  2. क्या विशेष अर्थ या उद्देश्य अज्ञात हो सकता है, अनजाना, अस्पष्ट, या भ्रामक, यहां तक ​​कि इसके उचित संदर्भ में भी?
  3. क्या गलत संदर्भ में गलत परिणामों के साथ उचित बुनियादी मूल्य का गलत इस्तेमाल किया जा सकता है?
  4. क्या सही संदर्भ में गलत परिणामों के साथ एक अनुचित बुनियादी मूल्य का सही उपयोग किया जा सकता है?
  5. क्या विशिष्ट संदर्भों में अन्य बुनियादी मूल्यों के साथ मूल मूल्य का अर्थ या उद्देश्य संबंध है?
  6. क्या मूल कोड हमारे कोड में एक से अधिक स्थानों में प्रत्येक में अलग-अलग शब्दार्थों के साथ मौजूद हो सकता है, जिससे हमारे पाठक को भ्रम हो सकता है?

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

अंत में, प्रतिस्थापन का उत्तर कनेक्शन बनाने के लिए पाठक की ताकत या कमजोरी के माप (आपके दिमाग में) का जवाब है (उदाहरण के लिए "इसे प्राप्त करें")। जितना जल्दी वे अर्थ और उद्देश्य को समझते हैं, उतना कम "जादू" आपके पास है।

निष्कर्ष: प्रतीकात्मक स्थिरांक के साथ बुनियादी मूल्यों को तब ही बदलें, जब भ्रम से उत्पन्न होने वाली बगों का पता लगाने के लिए जादू काफी बड़ा हो।


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

17

एक जादू संख्या एक फ़ाइल प्रारूप, या प्रोटोकॉल एक्सचेंज की शुरुआत में पात्रों का एक क्रम है। यह संख्या एक पवित्रता जाँच के रूप में कार्य करती है।

उदाहरण: कोई भी GIF फ़ाइल खोलें, आप बहुत शुरुआत में देखेंगे: GIF89। "GIF89" मैजिक नंबर है।

अन्य प्रोग्राम किसी फ़ाइल के पहले कुछ वर्णों को पढ़ सकते हैं और GIF की सही पहचान कर सकते हैं।

खतरा यह है कि यादृच्छिक बाइनरी डेटा में ये समान वर्ण हो सकते हैं। लेकिन इसकी संभावना बहुत कम है।

प्रोटोकॉल एक्सचेंज के लिए, आप इसका उपयोग जल्दी से पहचानने के लिए कर सकते हैं कि वर्तमान 'संदेश' जो आपके पास भेजा जा रहा है वह दूषित है या मान्य नहीं है।

मैजिक नंबर अभी भी उपयोगी हैं।


13
मुझे नहीं लगता कि वह जादू की संख्या है जिसका वह उल्लेख कर रहा है
Marcio Aguiar

4
हो सकता है कि आपने "फ़ाइल-स्वरूप" और "नेटवर्किंग" टैग हटा दिए हों क्योंकि वह स्पष्ट रूप से उन प्रकार के जादुई नंबरों के बारे में बात नहीं कर रहा है।
लैंडन

9
यह जानना अभी भी बहुत उपयोगी है कि मैजिक नंबर एक कोड इश्यू से अधिक हो सकते हैं। -आदम
एडम डेविस

3
यदि विषय पढ़ा जाता है: "स्रोत कोड के संदर्भ में एक जादुई संख्या क्या है" तो टैग नहीं होना चाहिए। लेकिन उन्होंने इसे निर्दिष्ट नहीं किया। इसलिए मेरी अतिरिक्त जानकारी होना अच्छा है। मुझे लगता है कि काइल, लैंडन और मार्सियो गलत हैं।
ब्रायन आर। बॉंडी

4
यह निर्धारित करने का भी कोई तरीका नहीं था कि वह किसकी तलाश कर रहा था। चूंकि मैं पहली पोस्ट थी, इसलिए मैं अनुमान नहीं लगा सकता था कि वह किसकी तलाश में है।
ब्रायन आर। बॉंडी

12

प्रोग्रामिंग में, "मैजिक नंबर" एक मूल्य है जिसे एक प्रतीकात्मक नाम दिया जाना चाहिए, लेकिन इसके बजाय एक शाब्दिक के रूप में कोड में फिसल गया, आमतौर पर एक से अधिक स्थानों पर।

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

इन स्थिरांक को विन्यास के रूप में कार्य करने के लिए लोग कभी-कभी जादू की संख्या को खत्म कर देते हैं। यह कभी-कभी सहायक होता है, लेकिन इसके लायक होने से अधिक जटिलता भी पैदा कर सकता है।


क्या आप इस बात पर अधिक विशिष्ट हो सकते हैं कि मैजिक नंबरों को खत्म करना ISN'T alway अच्छा क्यों है?
Marcio Aguiar

गणित में सूत्र जैसे e ^ pi + 1 = 0
Jared Updateike

5
Marcio: जब आप "const int आठ = 8;" जैसी चीजें करते हैं और फिर आवश्यकताएं बदल जाती हैं और आप "const int Eight = 9;"
jmucchiello

6
क्षमा करें, लेकिन यह केवल खराब नामकरण, या स्थिरांक के लिए आधार उपयोग का एक उदाहरण है।
1

1
@MarcioAguiar: कुछ प्लेटफार्मों पर, (foo[i]+foo[i+1]+foo[i+2]+1)/3लूप की तुलना में बहुत तेजी से मूल्यांकन किया जा सकता है। यदि किसी को 3कोड को लूप के रूप में लिखे बिना प्रतिस्थापित करना था , तो किसी ने यह देखा कि उसे जिस आकृति के ITEMS_TO_AVERAGEरूप में परिभाषित किया गया है, 3वह उसे बदल सकता है 5और कोड को औसत से अधिक आइटम हो सकता है। इसके विपरीत, कोई व्यक्ति जो शाब्दिक के साथ अभिव्यक्ति को देखता है, 3उसे एहसास होगा कि 3एक साथ अभिव्यक्त होने वाली वस्तुओं की संख्या का प्रतिनिधित्व करता है।
22

10

एक जादू संख्या विशेष, हार्डकोड शब्दार्थ के साथ एक संख्या भी हो सकती है। उदाहरण के लिए, मैंने एक बार एक सिस्टम देखा था जहां रिकॉर्ड आईडी> 0 का सामान्य रूप से इलाज किया गया था, 0 खुद "नया रिकॉर्ड" था, -1 था "यह रूट है" और -99 "यह रूट में बनाया गया था"। 0 -99 के कारण WebService को एक नई ID की आपूर्ति होगी।

इसके बारे में बुरा यह है कि आप विशेष क्षमताओं के लिए एक जगह (रिकॉर्ड आईडी के लिए हस्ताक्षरित पूर्णांक) का पुन: उपयोग कर रहे हैं। हो सकता है कि आप कभी भी आईडी 0, या नकारात्मक आईडी के साथ रिकॉर्ड बनाना नहीं चाहेंगे, लेकिन यदि नहीं, तो भी हर व्यक्ति जो कोड या डेटाबेस में दिखता है, वह इस पर ठोकर खा सकता है और पहले भ्रमित हो सकता है। यह कहे बिना जाता है कि उन विशेष मूल्यों को अच्छी तरह से प्रलेखित नहीं किया गया था।

संभवतः, 22, 7, -12 और 620 को जादुई संख्या के रूप में गिना जाता है। ;-)


10

एक समस्या जो जादू की संख्या का उपयोग करने के साथ उल्लेख नहीं किया गया है ...

यदि आपके पास उनमें से बहुत से हैं, तो संभावनाएं बहुत अच्छी हैं कि आपके पास दो अलग-अलग उद्देश्य हैं, जिनके लिए आप जादुई संख्या का उपयोग कर रहे हैं, जहां मान हैं समान होते हैं।

और फिर, निश्चित रूप से पर्याप्त है, आपको केवल एक उद्देश्य के लिए मूल्य बदलने की आवश्यकता है ...


संख्याओं के बारे में बात करते समय यह सब संभव नहीं दिखता है (कम से कम मेरे लिए नहीं), लेकिन मैं तार के साथ इसमें भाग गया और यह एक हिट है: पहले आपको यह देखने के लिए बहुत सारे कोड पढ़ने होंगे कि इसका उपयोग कहां किया गया है, आपके मुकाबले ध्यान दें कि यह विभिन्न चीजों के लिए उपयोग किया जा रहा है ... मेरा पसंदीदा शगल नहीं।
टॉमिस्लाव नैक-अल्फेयरविक

4

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


3

मैंने हमेशा "मैजिक नंबर" शब्द का उपयोग किया है, एक डेटा संरचना के भीतर संग्रहीत एक अस्पष्ट मूल्य के रूप में, जिसे त्वरित घनत्व जांच के रूप में सत्यापित किया जा सकता है। उदाहरण के लिए gzip फाइलों में 0x1f8b08 होते हैं क्योंकि उनकी पहली तीन बाइट्स, Java क्लास की फाइलें 0xcaflabe आदि से शुरू होती हैं।

आप अक्सर फ़ाइल स्वरूपों में एम्बेडेड मैजिक नंबर देखते हैं, क्योंकि फाइलों को आस-पास के बजाय भेजा जा सकता है और वे कैसे बनाए गए थे, इसके बारे में कोई मेटाडेटा खो देते हैं। हालाँकि मैजिक नंबर कभी-कभी इन-मेमोरी डेटा संरचनाओं के लिए भी उपयोग किए जाते हैं, जैसे ioctl () कॉल।

फ़ाइल या डेटा संरचना को संसाधित करने से पहले मैजिक नंबर की एक त्वरित जांच एक व्यक्ति को त्रुटियों को जल्दी संकेतित करने की अनुमति देती है, बजाय संभावित लंबा प्रसंस्करण के माध्यम से सभी तरह से यह घोषणा करने के लिए कि इनपुट पूरा बाल्डरैश था।


2

यह ध्यान देने योग्य है कि कभी-कभी आप अपने कोड में गैर-विन्यास योग्य "हार्ड-कोडेड" नंबर चाहते हैं। कई प्रसिद्ध हैं जो अनुकूलित उलटा वर्गमूल एल्गोरिथ्म में प्रयोग किया जाता है 0x5F3759DF भी शामिल है।

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


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

2

डिफ़ॉल्ट मान के साथ वर्ग के शीर्ष पर एक चर को इनिशियलाइज़ करने के बारे में क्या? उदाहरण के लिए:

public class SomeClass {
    private int maxRows = 15000;
    ...
    // Inside another method
    for (int i = 0; i < maxRows; i++) {
        // Do something
    }

    public void setMaxRows(int maxRows) {
        this.maxRows = maxRows;
    }

    public int getMaxRows() {
        return this.maxRows;
    }

इस मामले में, 15000 एक मैजिक नंबर है (चेकस्इटल्स के अनुसार)। मेरे लिए, डिफ़ॉल्ट मान सेट करना ठीक है। मैं नहीं करना चाहता:

private static final int DEFAULT_MAX_ROWS = 15000;
private int maxRows = DEFAULT_MAX_ROWS;

क्या इससे पढ़ने में ज्यादा मुश्किल होती है? जब तक मैंने CheckStyles स्थापित नहीं किया, मैंने इस पर कभी विचार नहीं किया।


मुझे लगता है कि यह ठीक होगा अगर कंस्ट्रक्टर मूल्य को इनिशियलाइज़ करता है। अन्यथा यदि मूल्य को कंस्ट्रक्टर के बाहर इनिशियलाइज़ किया जाता है, तो मैं इसे केवल एक झंझट के रूप में देखता हूं और कुछ कठिन पढ़ने के लिए।
थॉमस ईडिंग

मुझे लगता है कि static finalजब आप उन्हें एक विधि में उपयोग कर रहे हैं तो स्थिरांक अधिक हो जाता है। finalविधि के शीर्ष पर घोषित एक चर अधिक पठनीय IMHO है।
इवा

0

@ eed3si9n: मैं यह भी सुझाव दूंगा कि '1' एक जादुई संख्या है। :-)

मैजिक नंबरों से संबंधित एक सिद्धांत यह है कि आपके द्वारा कोड किए जाने वाले हर तथ्य को एक बार बिल्कुल घोषित किया जाना चाहिए। यदि आप अपने कोड में मैजिक नंबर का उपयोग करते हैं (जैसे कि पासवर्ड की लंबाई का उदाहरण जो @marcio ने दिया है, तो आप आसानी से उस तथ्य को दोहरा सकते हैं, और जब उस तथ्य के बारे में आपकी समझ बदल जाती है तो आपको रखरखाव की समस्या हो सकती है।


5
IOW कोड इस तरह लिखा जाना चाहिए:factorial n = if n == BASE_CASE then BASE_VALUE else n * factorial (n - RECURSION_INPUT_CHANGE); RECURSION_INPUT_CHANGE = 1; BASE_CASE = 0; BASE_VALUE = 1
थॉमस Eding

0

वापसी चर के बारे में क्या?

संग्रहीत प्रक्रियाओं को लागू करते समय मुझे विशेष रूप से चुनौतीपूर्ण लगता है ।

अगली संग्रहीत प्रक्रिया की कल्पना करें (गलत सिंटैक्स, मुझे पता है, बस एक उदाहरण दिखाने के लिए):

int procGetIdCompanyByName(string companyName);

यदि यह किसी विशेष तालिका में मौजूद है, तो यह कंपनी की Id लौटाती है। अन्यथा, यह रिटर्न -1। किसी तरह यह एक जादू की संख्या है। अब तक पढ़ी गई सिफारिशों में से कुछ का कहना है कि मुझे वास्तव में इस तरह से डिजाइन करना होगा:

int procGetIdCompanyByName(string companyName, bool existsCompany);

वैसे, अगर कंपनी मौजूद नहीं है तो उसे क्या लौटना चाहिए? ठीक है: यह अस्तित्व को असत्य के रूप में सेट करेगा , लेकिन -1 भी लौटाएगा।

एंटेरो विकल्प दो अलग-अलग कार्य करने के लिए है:

bool procCompanyExists(string companyName);
int procGetIdCompanyByName(string companyName);

तो दूसरी संग्रहीत प्रक्रिया के लिए एक पूर्व शर्त यह है कि कंपनी मौजूद है।

लेकिन मुझे कंसीडर से डर लगता है, क्योंकि इस सिस्टम में एक कंपनी दूसरे यूजर द्वारा बनाई जा सकती है।

जिस तरह से नीचे की रेखा है: आप उस तरह के "मैजिक नंबरों" का उपयोग करने के बारे में क्या सोचते हैं जो अपेक्षाकृत ज्ञात और सुरक्षित हैं कि कुछ असफल है या कुछ मौजूद नहीं है?


उस विशिष्ट मामले में, यदि फ़ंक्शन के प्रलेखन में कहा गया है कि नकारात्मक रिटर्न वैल्यू का मतलब है कि कोई कंपनी नहीं मिली है, तो निरंतर उपयोग करने का कोई कारण नहीं है।
विंसेंट फोरमंड

-1

एक जादू की संख्या को एक स्थिर के रूप में निकालने का एक अन्य लाभ स्पष्ट रूप से व्यावसायिक जानकारी को दस्तावेज़ करने की संभावना देता है।

public class Foo {
    /** 
     * Max age in year to get child rate for airline tickets
     * 
     * The value of the constant is {@value}
     */
    public static final int MAX_AGE_FOR_CHILD_RATE = 2;

    public void computeRate() {
         if (person.getAge() < MAX_AGE_FOR_CHILD_RATE) {
               applyChildRate();
         }
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.