2012-10-10 19 views
14

के लिए घन जड़ गिना जा रहा है तो,, लघु होने कीनकारात्मक संख्या

√ (-8) = (-8) 1/3

console.log(Math.pow(-8,1/3)); 
//Should be -2 

लेकिन जब मैं इसका परीक्षण करता हूं, यह

NaN 

क्यों आउटपुट करता है? क्या यह एक बग है या ऐसा पहले स्थान पर होने की उम्मीद है? मैं ग्राफ़ खींचने के लिए जावास्क्रिप्ट का उपयोग कर रहा हूं, लेकिन यह ग्राफ को गड़बड़ कर देता है।

+3

गुणा 8^1/3 वापस आ जाएगी -1 द्वारा :-) – noel

+0

एक देशी [ES6 में घन जड़] (http नहीं है (समर्थन here जांच) कर सकते हैं: //stackoverflow.com/a/29740048/1090562) –

उत्तर

17

आप इस स्निपेट का उपयोग करने के लिए इसका उपयोग कर सकते हैं। यह अन्य शक्तियों के लिए भी काम करता है, उदा। 1/4, 1/5, आदि

function nthroot(x, n) { 
    try { 
    var negate = n % 2 == 1 && x < 0; 
    if(negate) 
     x = -x; 
    var possible = Math.pow(x, 1/n); 
    n = Math.pow(possible, n); 
    if(Math.abs(x - n) < 1 && (x > 0 == n > 0)) 
     return negate ? -possible : possible; 
    } catch(e){} 
} 

nthroot(-8, 3); 

स्रोत: http://gotochriswest.com/blog/2011/05/06/cube-root-an-beyond/

सिर्फ घन रूट की गणना के लिए एक तेजी से दृष्टिकोण:

Math.cbrt = function(x) { 
    var sign = x === 0 ? 0 : x > 0 ? 1 : -1; 

    return sign * Math.pow(Math.abs(x), 1/3); 
} 

Math.cbrt(-8); 

अद्यतन

आधारित घन जड़ एक पूर्णांक के लिए, आप उपयोग कर सकते हैं निम्नलिखित कार्य, this answer से प्रेरित:

// positive-only cubic root approximation 
function cbrt(n) 
{ 
    var a = n; // note: this is a non optimized assumption 

    while (a * a * a > n) { 
     a = Math.floor((2 * a + (n/(a * a)))/3); 
    } 

    return a; 
} 

यह एक धारणा से शुरू होता है जो निकटतम पूर्णांक a में परिवर्तित होता है जिसके लिए a^3 <= n है। नकारात्मक फ़ंक्शन का समर्थन करने के लिए इस फ़ंक्शन को उसी तरह समायोजित किया जा सकता है।

+0

धन्यवाद, यह पूरी तरह से काम करता है। –

+0

@ डेरेक ग्रेट, मैंने सिर्फ क्यूबिक रूट के लिए एक छोटा सा फ़ंक्शन जोड़ा है। –

+1

निश्चित रूप से स्थिरता के लिए आपको फेंकने के बजाय 'NaN' वापस करना चाहिए। संयोग से, वह कोड कब फेंक देगा? –

10

कोई बग नहीं है; आप एक आंशिक शक्ति के लिए एक नकारात्मक संख्या उठा रहे हैं; इसलिए, नाएन।

इसके लिए Google पर शीर्ष हिट Dr Math से स्पष्टीकरण बहुत अच्छा है। यह वास्तविक संख्याओं के लिए कहता है (वैसे भी जटिल संख्या नहीं), एक आंशिक शक्ति को एक नकारात्मक संख्या में उठाया गया वास्तविक संख्या वास्तविक संख्या नहीं हो सकती है। सबसे सरल उदाहरण शायद है

-4^(1/2)

जो अनिवार्य रूप से -4 का वर्गमूल की गणना की जाती है। भले ही 8 के घन रूट में वास्तविक समाधान हों, मुझे लगता है कि अधिकांश सॉफ़्टवेयर पुस्तकालयों को यह अधिक कुशल लगता है कि सभी जटिल अंकगणित न करें और नाइन केवल तभी वापस आएं जब काल्पनिक हिस्सा नज़र न हो और आपको अन्यथा असली वास्तविक उत्तर दें।

संपादित

बस बिल्कुल स्पष्ट बनाने के लिए है कि NaN, इच्छित परिणाम है see the official ECMAScript 5.1 Specification, Section 15.8.2.13। यह कहता है:

यदि x < 0 और x परिमित है और वाई परिमित है और वाई पूर्णांक नहीं है, तो परिणाम NaN है।

फिर भी, भले ही आंशिक शक्तियों को नकारात्मक संख्याओं को बढ़ाने के कुछ उदाहरणों में वास्तव में एक वास्तविक जड़ है, कई भाषाएं नकारात्मक संख्याओं के सभी मामलों के लिए आंशिक जड़ें हैं।

कृपया यह नहीं सोचना कि जावास्क्रिप्ट एकमात्र ऐसी भाषा है। C++ does the same thing:

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

+0

तो मैं '8√ (-8)' '8^(1/3)' के बिना कैसे करूँ? –

+1

आप वोल्फ्राम अल्फा पर स्विच कर सकते हैं, जो जावास्क्रिप्ट की तुलना में इन चीजों को संभालने में बेहतर है: http://www.wolframalpha.com/input/?i=-8+%5E+%281%2F3%29 :) गंभीर रूप से जावास्क्रिप्ट बस लेता है इनके लिए NaN आसान तरीका है और कहता है, क्योंकि वे अक्सर जटिल संख्याएं हैं, जो जावास्क्रिप्ट मूल रूप से समर्थन नहीं करता है। –

+0

+1, कुछ * गणित मंच * उत्तर शायद * आपके * –

4

मैं अन्य उत्तर पसंद है, लेकिन कैसे के बारे में Math.pow अधिभावी तो यह नकारात्मक संख्या सभी वें जड़ों के साथ काम करने के लिए सक्षम हो जाएगा:, मुझे एक चिल्लाओ अगर देना

//keep the original method for proxying 
Math.pow_ = Math.pow; 

//redefine the method 
Math.pow = function(_base, _exponent) { 
    if (_base < 0) { 
    if (Math.abs(_exponent) < 1) { 
     //we're calculating nth root of _base, where n === 1/_exponent 
     if (1/_exponent % 2 === 0) { 
     //nth root of a negative number is imaginary when n is even, we could return 
     //a string like "123i" but this would completely mess up further computation 
     return NaN; 
     }/*else if (1/_exponent % 2 !== 0)*/ 
     //nth root of a negative number when n is odd 
     return -Math.pow_(Math.abs(_base), _exponent); 
    } 
    }/*else if (_base >=0)*/ 
    //run the original method, nothing will go wrong 
    return Math.pow_(_base, _exponent); 
}; 

कुछ परीक्षण मामलों के साथ Fiddled आप एक बग स्पॉट!

+0

मुझे वास्तव में 'pow_' चारों ओर तैरना पसंद नहीं है ... क्या मूल' पाउ 'को नए' पाउ 'के अंदर रखना संभव है? –

+0

@ डेरेक: हाँ, यही वह है जो मैं कर रहा हूं।'पाउ' 'pow_' बन जाता है, या 'pow_legacy' हो सकता है या जो भी आपको चाहिए –

+0

नहीं, मेरा मतलब है कि मैं एक अतिरिक्त चर' Math.pow_' नहीं चाहता हूं। मैं इस तरह कुछ सोच रहा हूं: http://jsfiddle.net/DerekL/D32Td/ –

6

दो प्रमुख समस्याओं:

  1. गणित के अनुसार, वहाँ एक नकारात्मक संख्या के कई घन जड़ें हैं: -2, लेकिन यह भी 2 जटिल जड़ों (cube roots of unity देखें)।
  2. जावास्क्रिप्ट Math ऑब्जेक्ट (और अधिकांश अन्य मानक गणित पुस्तकालय) नकारात्मक संख्याओं की आंशिक शक्तियां नहीं करेंगे। फ़ंक्शन प्राप्त होने से पहले यह आंशिक शक्ति को एक फ्लोट में परिवर्तित करता है, इसलिए आप फ़ंक्शन को नकारात्मक संख्या की फ़्लोटिंग पॉइंट पावर की गणना करने के लिए कह रहे हैं, जो वास्तविक समाधान हो सकता है या नहीं। तो यह व्यावहारिक बात करता है और इस तरह के मूल्य की गणना करने का प्रयास करने से इंकार कर देता है।

आप सही उत्तर प्राप्त करना चाहते हैं, तो आप कैसे गणितीय सही आप होना चाहते हैं तय करने के लिए की जरूरत है, और pow के एक गैर मानक कार्यान्वयन में उन नियमों लिखेंगे।

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

+1

किसी भी सकारात्मक संख्या की कई घन जड़ें भी हैं। सटीक होने के लिए, किसी वास्तविक संख्या 'x' और सकारात्मक पूर्णांक' n' के लिए 'x = y^n' को जटिल विमान पर 'y' के लिए बिल्कुल' n' अद्वितीय मान हैं। यह बीजगणित के मौलिक प्रमेय से सीधे उपजी है। – AJMansfield

2

यह क्रोम कंसोल में कार्य करना है

function cubeRoot(number) { 
    var num = number; 
    var temp = 1; 
    var inverse = 1/3; 
    if (num < 0) { 
     num = -num; 
     temp = -1; 
    } 
    var res = Math.pow(num, inverse); 
    var acc = res - Math.floor(res); 
    if (acc <= 0.00001) 
     res = Math.floor(res); 
    else if (acc >= 0.99999) 
     res = Math.ceil(res); 
    return (temp * res); 
} 

cubeRoot(-64) // -4 
cubeRoot(64) // 4 
1

// ऋणात्मक संख्याओं सकारात्मक रूप में ही की जड़ों घन नहीं कर रहे हैं, पर हस्ताक्षर के अलावा?

Math.cubeRoot= function(n, r){ 
    var sign= (n<0)? -1: 1; 
    return sign*Math.pow(Math.abs(n), 1/3); 
} 
Math.cubeRoot(-8) 

/* returned value: (Number) 
-2 
*/ 
3

तो मैं तरीकों कि Math.pow(...) जो अच्छा है के चारों ओर घूमना के एक झुंड देखते हैं, लेकिन इनाम मैं एक अलग दृष्टिकोण का प्रस्ताव कर रहा हूँ की शब्दों पर आधारित है।

जड़ों को हल करने के लिए कई कम्प्यूटेशनल अनुमान हैं, कुछ दूसरों की तुलना में तेज़ कदम उठाते हैं। अंततः स्टॉपिंग पॉइंट वांछित परिशुद्धता की डिग्री तक आता है (यह वास्तव में आपके ऊपर/समस्या हल हो रही है)।(- प्रश्न शीर्षक की वजह से, यह भी कहा नकारात्मक रेंज इनाम परीक्षण)

मैं ठीक विस्तार से गणित समझाने के लिए नहीं जा रहा हूँ, लेकिन निम्नलिखित घन जड़ अनुमानों कि लक्ष्य परीक्षा उत्तीर्ण की कार्यान्वयन हैं। लूप में प्रत्येक पुनरावृत्ति (प्रत्येक विधि में while(Math.abs(xi-xi0)>precision) लूप देखें) वांछित परिशुद्धता के करीब एक कदम प्राप्त करता है। एक बार परिशुद्धता प्राप्त हो जाने पर एक प्रारूप को संख्या पर लागू किया जाता है, इसलिए यह पुनरावृत्ति से प्राप्त गणना के रूप में सटीक है।

var precision = 0.0000000000001; 
function test_cuberoot_fn(fn) { 
    var tested = 0, 
    failed = 0; 
    for (var i = -100; i < 100; i++) { 
     var root = fn(i*i*i); 
     if (i !== root) { 
      console.log(i, root); 
      failed++; 
     } 
     tested++; 
    } 
    if (failed) { 
     console.log("failed %d/%d", failed, tested); 
    }else{ 
     console.log("Passed test"); 
    } 
} 
test_cuberoot_fn(newtonMethod); 
test_cuberoot_fn(halleysMethod); 

न्यूटन के सन्निकटन कार्यान्वयन

function newtonMethod(cube){ 
    if(cube == 0){//only John Skeet and Chuck Norris 
     return 0; //can divide by zero, we'll have 
    }    //to settle for check and return 
    var xi = 1; 
    var xi0 = -1; 
    while(Math.abs(xi-xi0)>precision){//precision = 0.0000000000001 
     xi0=xi; 
     xi = (1/3)*((cube/(xi*xi))+2*xi); 
    } 
    return Number(xi.toPrecision(12)); 
} 

हैली सन्निकटन कार्यान्वयन टिप्पणी हैली सन्निकटन घन हल करने के लिए जल्दी कदम उठा लेता है, इसलिए यह न्यूटन के सन्निकटन से computationally तेज़ है।

function halleysMethod(cube){ 
    if(cube == 0){//only John Skeet and Chuck Norris 
     return 0; //can divide by zero, we'll have 
    }    //to settle for check and return 
    var xi = 1; 
    var xi0 = -1; 
    while(Math.abs(xi-xi0)>precision){//precision = 0.0000000000001 
     xi0=xi; 
     xi = xi*((xi*xi*xi + 2*cube)/(2*xi*xi*xi+cube)); 
    } 
    return Number(xi.toPrecision(12)); 
} 
1

एक सिर के रूप में, ईएस 6 में अब Math.cbrt फ़ंक्शन है।

Google क्रोम में मेरे परीक्षण में यह Math.pow के रूप में लगभग दोगुनी तेजी से काम करता प्रतीत होता है। दिलचस्प बात यह है कि मुझे परिणामों को जोड़ना पड़ा अन्यथा क्रोम ने पाउ फंक्शन को अनुकूलित करने का बेहतर काम किया।

//do a performance test on the cube root function from es6 
var start=0, end=0, k=0; 
start = performance.now(); 
k=0; 
for (var i=0.0; i<10000000.0; i+=1.0) 
{ 
    var j = Math.cbrt(i); 
    //k+=j; 
} 
end = performance.now(); 
console.log("cbrt took:" + (end-start),k); 
k=0; 
start = performance.now(); 
for (var i=0.0; i<10000000.0; i+=1.0) 
{ 
    var j = Math.pow(i,0.33333333); 
    //k+=j; 
} 
end = performance.now(); 
console.log("pow took:" + (end-start),k); 
k=0; 
start = performance.now(); 
for (var i=0.0; i<10000000.0; i+=1.0) 
{ 
    var j = Math.cbrt(i); 
    k+=j; 
} 
end = performance.now(); 
console.log("cbrt took:" + (end-start),k); 
k=0; 
start = performance.now(); 
for (var i=0.0; i<10000000.0; i+=1.0) 
{ 
    var j = Math.pow(i,0.33333333); 
    k+=j; 
} 
end = performance.now(); 
console.log("pow took:" + (end-start),k); 

परिणाम:

cbrt took:468.28200000163633 0 
pow took:77.21999999921536 0 
cbrt took:546.8039999977918 1615825909.5248165 
pow took:869.1149999940535 1615825826.7510242 
0

बस को उजागर करना है कि ES6 में एक native cubic root समारोह है वहाँ चाहते हैं। तो तुम सिर्फ इस

Math.cbrt(-8) आप -2