क्यों जावास्क्रिप्ट में ** के बराबर Math.pow () (कभी-कभी) होता है?


118

मैंने अभी ( MDN संदर्भ ) के a**bलिए एक विकल्प के रूप में ECMAScript 7 सुविधा की खोज की है और उस पोस्ट में चर्चा में आया , जिसमें वे स्पष्ट रूप से अलग तरह से व्यवहार करते हैं। मैंने इसे क्रोम 55 में परीक्षण किया है और यह पुष्टि कर सकता है कि परिणाम भिन्न हैं।Math.pow(a,b)

Math.pow(99,99) रिटर्न 3.697296376497263e+197

जहाँ तक

99**99 रिटर्न 3.697296376497268e+197

इसलिए अंतर को लॉग इन करने पर Math.pow(99,99) - 99**99परिणाम सामने आता है -5.311379928167671e+182

अब तक यह कहा जा सकता है, कि यह बस एक और क्रियान्वयन है, लेकिन इसे एक फंक्शन में लपेटने से फिर से अलग व्यवहार होता है:

function diff(x) {
  return Math.pow(x,x) - x**x;
}

कॉलिंग diff(99)रिटर्न 0

ऐसा क्यों हो रहा है?

जैसा कि xszaboj ने बताया, यह इस समस्या को कम कर सकता है:

var x = 99;
x**x - 99**99; // Returns -5.311379928167671e+182

7
ऐसा लगता है कि किसी ने उनके द्वारा उपयोग किए गए एल्गोरिदम को फिर से लिखा है, और एक अस्थायी बिंदु त्रुटि पाई गई। नंबर कठिन हैं ...
क्रिलगर

4
@krillgar वाजिब लगता है, लेकिन एक समारोह में फिर वही त्रुटि क्यों नहीं हो रही है?
थॉमस अल्टमैन

3
@AndersonPimentel MDN लिंक संगतता तालिका के लिए इंगित करता है ।
अलवारो गोंजालेज

7
अंतर इस दो के बीच है: var x = 99; x * * x; और 99 * * 99. या फ़ंक्शन भिन्न (x) {वापसी 99 * * 99 - (x * * x); }; diff (99)। रिक्ति के लिए क्षमा करें, टिप्पणी दो सितारों को फिल्टर करती है :(
xszaboj

1
@xszaboj ने `likethis`इसे पठनीय बनाने के लिए कोड को बैकटिक्स में रखा और बोल्ड / इटैलिक समस्या से भी बचा
phuclv

जवाबों:


126

99**99है संकलन समय पर मूल्यांकन किया जाता ( "निरंतर तह"), और संकलक के powदिनचर्या से अलग है क्रम एक**रन टाइम पर मूल्यांकन करते समय, परिणाम समान होते हैं Math.pow- कोई आश्चर्य नहीं कि **वास्तव में कॉल करने के लिए संकलित किया गया है Math.pow:

console.log(99**99);           // 3.697296376497268e+197
a = 99, b = 99;
console.log(a**b);             // 3.697296376497263e+197
console.log(Math.pow(99, 99)); // 3.697296376497263e+197

वास्तव में

99 99 = 369729637649726772657187905628805440595668764281741102430259972423552570455277523421410650010128232727940978889548326540119429996769494359451621570193644014418071060667659301384999779999159200499899

इसलिए पहला परिणाम एक बेहतर सन्निकटन है, फिर भी निरंतर और गतिशील अभिव्यक्तियों के बीच ऐसी विसंगति नहीं होनी चाहिए।

यह व्यवहार V8 में बग जैसा दिखता है। यह रिपोर्ट किया गया है और उम्मीद है कि जल्द ही ठीक हो जाएगा।


19
तो यह मूलतः जेएस कंप्यूटिंग के साथ प्रदर्शन में सुधार करने की कोशिश कर रहा है 99**99? क्या इसे बग माना जा सकता है, क्योंकि Math.powसंख्या और चर के लिए एक ही आउटपुट बनाता है और **नहीं?
थॉमस अल्टमैन

3
@ThomasAltmann: Math.rowहमेशा रनटाइम होता है, कास्ट फोल्डिंग केवल ऑपरेटरों के लिए किया जा सकता है। हाँ, यह निश्चित रूप से एक बग है।
जियोर्ज

11
एक बग को लॉग किया गया है , यहां ओपी द्वारा चीजों को देखा गया है।
जेम्स थॉर्प

5
मैं एमएस एज का उपयोग कर रहा है, और सभी 3 परिणाम एक ही कर रहे हैं: 3.697296376497263e+197, 3.697296376497263e+197, और 3.697296376497263e+197क्रमशः। यह निश्चित रूप से क्रोम बग है।
नोलोनार १६'१

4
@ThomasAltmann यदि निरंतर तह रनटाइम इम्प्लांट से भी बदतर मूल्य पैदा करता है तो यह एक बग है। यदि यह रनटाइम से बेहतर मूल्य का उत्पादन करता है तो इसे बग नहीं माना जा सकता है। इस मामले में, यह बेहतर है - सही मूल्य "... 26772 ..." है, निरंतर तह "... 268" (सही ढंग से गोल) का उत्पादन करता है, और रनटाइम "... 263" (4+ से बंद) पैदा करता है। अंतिम स्थान पर इकाइयाँ)।
हॉब्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.