Berechnen Sie die Kubikwurzel einer Zahl

12

Das Ziel dieses Codegolfs ist es, ein Programm oder eine Funktion zu erstellen, die die Kubikwurzel einer Zahl berechnet und ausgibt, die als Eingabe angegeben wird.
Die Regeln:

  • Keine externen Ressourcen
  • Keine Verwendung der eingebauten Kubikwurzelfunktionen.
  • Keine Verwendung von Methoden / Operatoren, die eine Zahl zur Potenz erheben können (einschließlich Quadratwurzel, 4. Wurzel usw.).
  • Ihre Funktion / Ihr Programm muss Gleitkommazahlen und negative Zahlen als Eingabe akzeptieren können.
  • Wenn die Kubikwurzel eine Gleitkommazahl ist, runden Sie sie auf 4 Nachkommastellen.
  • Dies ist ein Code Golf, der kürzeste Code in Bytes gewinnt.

Testfälle:

27 --> 3
64 --> 4
1  --> 1
18.609625 --> 2.65
3652264 --> 154
0.001 --> 0.1
7  --> 1.9129

Sie können alle obigen Testfälle verwenden, um negative Zahlen ( -27 --> -3, -64 --> -4...) zu testen.

ProgramFOX
quelle
Verdammt, wenn Sie nur Zahlen mit genauem Würfel zulassen würden, hätte ich einen schönen Golf
yo
1
Nach Ihren Testfällen zu urteilen gehe ich davon aus, dass das Programm nur mit reellen Zahlen umgehen muss?
user12205
@ace Komplex hinzufügen und ich ändere 2 Buchstaben in meinem Code;)
yo
2
Ist das Runden auf 4 Stellen nach dem Komma eine wichtige Voraussetzung? Oder könnte es so etwas wie "Sie müssen nicht mehr als 4 Stellen nach dem Komma anzeigen" sein?
Victor Stafusa
Bitte klären Sie anhand meiner Antwort mit Exp (ln (x) / 3) (und mehreren Klonen davon), ob Exp zulässig ist. Ich gehe davon aus, dass Pow (x, 1/3) nicht ist (obwohl es technisch keine Kubikwurzelfunktion ist.)
Level River St

Antworten:

6

J: 16 Zeichen

Lose Übersetzung der Haskell-Antwort:

-:@((%*~)+])^:_~

Testfälle:

   -:@((%*~)+])^:_~27
3
   -:@((%*~)+])^:_~64
4
   -:@((%*~)+])^:_~1
1
   -:@((%*~)+])^:_~18.609625
2.65
   -:@((%*~)+])^:_~3652264
154
   -:@((%*~)+])^:_~0.001
0.1
   -:@((%*~)+])^:_~7
1.91293

Das funktioniert so:

     (-:@((% *~) + ])^:_)~ 27
↔ 27 (-:@((% *~) + ])^:_) 27
↔ 27 (-:@((% *~) + ])^:_) 27 (-:@((% *~) + ])) 27
↔ 27 (-:@((% *~) + ])^:_) -: ((27 % 27 * 27) + 27)
↔ 27 (-:@((% *~) + ])^:_) 13.5185
↔ 27 (-:@((% *~) + ])^:_) 27 (-:@((% *~) + ])) 13.5185
↔ 27 (-:@((% *~) + ])^:_) -: ((27 % 13.5185 * 13.5185) + 13.5185)
↔ 27 (-:@((% *~) + ])^:_) 6.83313
...

In Worten:

half =. -:
of =. @
divideBy =. %
times =. *
add =. +
right =. ]
iterate =. ^:
infinite =. _
fixpoint =. iterate infinite
by_self =. ~

-:@((%*~)+])^:_~ ↔ half of ((divideBy times by_self) add right) fixpoint by_self

Keine der besten wortreichen Übersetzungen, da es eine dyadische Gabel und ein ~Recht am Ende gibt.

James Wood
quelle
19

Haskell - 35

c n=(iterate(\x->(x+n/x/x)/2)n)!!99

Beispiel läuft:

c 27  =>  3.0
c 64  =>  4.0
c 1  =>  1.0
c 18.609625  =>  2.6500000000000004  # only first 4 digits are important, right?
c 3652264  =>  154.0
c 0.001  =>  0.1
c 7  =>  1.9129311827723892
c (-27)  =>  -3.0
c (-64)  =>  -4.0

Außerdem, wenn Sie importieren Data.Complex, funktioniert es sogar bei komplexen Zahlen, es gibt eine der Wurzeln der Zahl zurück (es gibt 3):

c (18:+26)  =>  3.0 :+ 1.0

Der :+Operator sollte als 'plus i times' gelesen werden

mniip
quelle
1
Dies verdient eine +1. Ich habe verallgemeinerte n-te Root-Algen in der letzten Stunde überarbeitet und bin gerade zu demselben Ergebnis gekommen. Bravo.
Primo
@primo Ich habe mich sofort an alle n-ten Algorithmen für die Root-Approximation erinnert und nach dem Verzicht auf Taylor / Maclaurin-Reihen in APL diese verwendet.
Mittwoch,
Können x=(2*x+n/x/x)/3Sie anhand der Newton-Methode erklären, warum Sie sie anwenden können x=(x+n/x/x)/2? Es konvergiert langsamer, aber ich kann nicht erklären, warum es konvergiert ...
Michael M.
@Michael denn wenn du nimmst x=cbrt(n), dann x=(x+n/x/x)/2stimmt das. So ist es wahr für Ihren Ausdruck
Mniip
@Michael Ich bin auf folgendem Weg dorthin gekommen: codepad.org/gwMWniZB
primo
7

SageMath, (69) 62 Bytes

Glauben Sie jedoch nicht, dass Sie das Ergebnis erhalten, es ist sehr schwierig, alle Zahlen zufällig durchzugehen:

def r(x):
 y=0
 while y*y*y-x:y=RR.random_element()
 return "%.4f"%y

Wenn Sie nicht darauf bestanden haben, abzuschneiden:

def r(x):
 y=0
 while y*y*y-x:y=RR.random_element()
 return y

SageMath, 12 Bytes, wenn exp zulässig

Funktioniert für alle Dinge: positiv, negativ, null, komplex, ...

exp(ln(x)/3)
yo '
quelle
Ich glaube, Sie verwenden einen Operator, der eine Zahl zur Potenz erheben kann.
user12205
ah ok, richtig, bearbeitet
yo
6
+1 für einen monumental dummen Algorithmus, der die Anforderungen noch erfüllt.
Mechanische Schnecke
Vielen Dank. Ich hoffe, es ist offensichtlich, dass ich eine Art Rezession mache: D Wenn expes jedoch erlaubt ist, bin ich auf 12 und überhaupt nicht dumm :)
yo
Dies expist die Abkürzung für "Exponentialfunktion". Dabei handelt es sich um eine Funktion, deren Wert eine Konstante ist, die auf die Potenz des Arguments angehoben wird, insbesondere die Funktion, bei der die Konstante e ist kann eine Zahl zur Potenz erheben ", expist nicht erlaubt.
mbomb007
5

Python - 62 Bytes

x=v=input()
exec"x*=(2.*v+x*x*x)/(v+2*x*x*x or 1);"*99;print x

Wertet mit voller Gleitkommapräzision aus. Die verwendete Methode ist die von Halley . Da jede Iteration dreimal so viele korrekte Stellen wie die letzte erzeugt, sind 99 Iterationen ein wenig übertrieben.

Input-Output:

27 -> 3.0
64 -> 4.0
1 -> 1.0
18.609625 -> 2.65
3652264 -> 154.0
0.001 -> 0.1
7 -> 1.91293118277
0 -> 1.57772181044e-30
-2 -> -1.25992104989
primo
quelle
Wie funktioniert das?
Nur die Hälfte des
1
@justhalf Ich denke, dies ist im Grunde die Newtonsche Näherungsmethode.
Du
Btw, nicht auf0
yo‘
Scheitert -2, tut mir leid.
yo‘
3
@plg Die Problembeschreibung verbietet die Verwendung von Exponentialfunktionen, sonst v**(1/.3)wäre ein sicherer Gewinner.
Primo
3

Javascript (55)

function f(n){for(i=x=99;i--;)x=(2*x+n/x/x)/3;return x}

BONUS, allgemeine Formulierung für alle Wurzeln
function f(n,p){for(i=x=99;i--;)x=x-(x-n/Math.pow(x,p-1))/p;return x}

Verwenden Sie für die Kubikwurzel einfach f(n,3)Quadratwurzel f(n,2)usw. Beispiel: f(1024,10)return 2.

Erläuterung
Basierend auf der Newton-Methode:

Suchen: f(x) = x^3 - n = 0Die Lösung lautet n = x^3
Die Ableitung:f'(x) = 3*x^2

Iterieren:
x(i+1) = x(i) - f(x(i))/f'(x(i)) = x(i) + (2/3)*x + (1/3)*n/x^2

Tests

[27,64,1,18.609625,3652264,0.001,7].forEach(function(n){console.log(n + ' (' + -n + ') => ' + f(n) + ' ('+ f(-n) +')')})

27 (-27) => 3 (-3)
64 (-64) => 4 (-4)
1 (-1) => 1 (-1)
18.609625 (-18.609625) => 2.65 (-2.65)
3652264 (-3652264) => 154 (-154)
0.001 (-0.001) => 0.09999999999999999 (-0.09999999999999999)
7 (-7) => 1.912931182772389 (-1.912931182772389) 
Michael M.
quelle
Ein Zeichen kürzer:function f(n){for(i=x=99;i--;)x-=(x-n/x/x)/3;return x}
kopieren
Kann auf 47 Bytes reduziert werdenf=(n)=>eval('for(i=x=99;i--;)x=(2*x+n/x/x)/3')
Luis Felipe De Jesus Munoz
2

PHP - 81 Bytes

Iterative Lösung:

$i=0;while(($y=abs($x=$argv[1]))-$i*$i*$i>1e-4)$i+=1e-5;@print $y/$x*round($i,4);
Razvan
quelle
Was passiert, wenn versucht wird, die Kubikwurzel von Null zu berechnen?
Victor Stafusa
Es wird nur "0" ausgegeben (dank des Fehlerunterdrückungsoperators - "@").
Razvan
1
0.0001kann nach 1e-4und 0.00001nach ersetzt werden 1e.5.
ComFreek
Dies erfordert PHP <7 ( 0/0gibt NANin PHP 7). $i=0;ist unnötig (-5 Byte. Wenn nicht, forwürde ein Byte gespart.) Der Platz danach printist nicht erforderlich (-1 Byte). -Rkann mit 3 Bytes sparen $argn.
Titus
Speichern Sie ein Paar Klammern mit while(1e-4+$i*$i*$i<$y=abs($x=$argn))(-2 Bytes).
Titus
2

Perl, 92 Bytes

sub a{$x=1;while($d=($x-$_[0]/$x/$x)/3,abs$d>1e-9){$x-=$d}$_=sprintf'%.4f',$x;s/\.?0*$//;$_}
  • Die Funktion agibt einen String mit der Nummer ohne unnötigen Bruchteil oder unbedeutende Nullen am rechten Ende zurück.

Ergebnis:

              27 --> 3
             -27 --> -3
              64 --> 4
             -64 --> -4
               1 --> 1
              -1 --> -1
       18.609625 --> 2.65
      -18.609625 --> -2.65
         3652264 --> 154
        -3652264 --> -154
           0.001 --> 0.1
          -0.001 --> -0.1
               7 --> 1.9129
              -7 --> -1.9129
 0.0000000000002 --> 0.0001
-0.0000000000002 --> -0.0001
               0 --> 0
              -0 --> 0

Generiert von

sub test{
    my $a = shift;
    printf "%16s --> %s\n", $a, a($a);
    printf "%16s --> %s\n", "-$a", a(-$a);
}
test 27;
test 64;
test 1;
test 18.609625;
test 3652264;
test 0.001;
test 7;
test "0.0000000000002";
test 0;

Die Berechnung basiert auf Newtons Methode :

Berechnung

Heiko Oberdiek
quelle
2

APL - 31

(×X)×+/1,(×\99⍴(⍟|X←⎕)÷3)÷×\⍳99

Nutzt die Tatsache, dass cbrt(x)=e^(ln(x)/3), aber anstatt naiv zu tun Exponentiation e^xTaylor / Maclaurin-Reihen verwendet werden.

Probeläufe:

⎕: 27
3
⎕: 64
4
⎕: 1
1
⎕: 18.609625
2.65
⎕: 3652264
154
⎕: 0.001
0.1
⎕: 7
1.912931183
⎕: ¯27
¯3
⎕: ¯7
¯1.912931183

Da es in 16 Zeichen eine J-Antwort gibt , muss ich bei APL wirklich schrecklich sein ...

mniip
quelle
2

Java, 207 182 181

Manchmal, wenn ich Golf spiele, trinke ich zwei Bier und spiele wirklich sehr, sehr schlecht

class n{public static void main(String[]a){double d=Double.valueOf(a[0]);double i=d;for(int j=0;j<99;j++)i=(d/(i*i)+(2.0*i))/3.0;System.out.println((double)Math.round(i*1e4)/1e4);}}

Iterative Newtons Approximationsmethode führt 99 Iterationen aus.

Hier ist der UnGolfed:

class n{
    public static void main(String a[]){
        //assuming the input value is the first parameter of the input
        //arguments as a String, get the Double value of it
        double d=Double.valueOf(a[0]);
        //Newton's method needs a guess at a starting point for the 
        //iterative approximation, there are much better ways at 
        //going about this, but this is by far the simplest. Given
        //the nature of the problem, it should suffice fine with 99 iterations
        double i=d;

        //make successive better approximations, do it 99 times
        for(int j=0;j<99;j++){
            i=( (d/(i*i)) + (2.0*i) ) / 3.0;
        }
        //print out the answer to standard out
        //also need to round off the double to meet the requirements
        //of the problem.  Short and sweet method of rounding:
        System.out.println( (double)Math.round(i*10000.0) / 10000.0 );
    }
}
md_rasler
quelle
1
Sie können die argsVariable in so etwas wie umbenennen zund 6 Zeichen reduzieren. Sie können das Leerzeichen und die geschweiften Klammern im Körper der for-Schleife entfernen und 3 Zeichen reduzieren. Sie ersetzen 10000.0durch 1e4, wodurch 6 Zeichen. Die Klasse muss nicht öffentlich sein, sodass Sie mehr als 7 Zeichen reduzieren können. Auf diese Weise wird es auf 185 Zeichen reduziert.
Victor Stafusa
Ist die Besetzung am Ende wirklich notwendig? Das geht bei mir nicht.
Victor Stafusa
@ Victor Danke für das gute Auge, die Verwendung der E-Notation für das 10000.0-Double war eine spektakulär gute Idee. Aufgrund der Fragestellung halte ich es für legitim, diese Methode anstelle einer funktionierenden Klasse cli zu verwenden, wodurch die Größe erheblich verringert würde. Mit Java habe ich nicht gedacht, dass ich eine Chance habe, also habe ich mich auf der funktionalen Seite geirrt.
md_rasler
Willkommen bei CodeGolf! Vergessen Sie nicht, in der Antwort zu erklären, wie das funktioniert!
Justin
@ Quincunx, Danke, empfohlene Änderung vorgenommen.
md_rasler
2

TI-Basic, 26 24 Bytes

Input :1:For(I,1,9:2Ans/3+X/(3AnsAns:End
Timtech
quelle
Das benutzt direkt den ^Operator, nicht wahr?
Dies
@mniip: Ist e^ein einzelner Operator bei der TI-83-Serie? Ich erinnere mich nicht. In jedem Fall verstößt es gegen den Geist der Regeln.
Mechanische Schnecke
Es ist egal, würde ich sagen. In den meisten Sprachen könnten Sie nur eines dieser beiden Dinge tun exp(ln(x)/3)oder erlauben e^(ln(x/3)). Aber irgendwie verstehe ich das exp(ln(x)/a)als zu viel Äquivalent, x^(1/a)um es nach den Regeln
yo
Exponentialfunktion: "Eine Funktion, deren Wert eine Konstante ist, die zur Potenz des Arguments erhoben wird , insbesondere die Funktion, bei der die Konstante e ist." ... "Keine Verwendung von Methoden / Operatoren, die eine Zahl zur Macht bringen können"
mbomb007
Danke für den catch @ mbomb007, ich habe diese Antwort vor mehr als 3 Jahren geschrieben und werde sie korrigieren, um sie jetzt zu erfüllen.
Timtech
2

Js 57 Bytes

f=(x)=>eval('for(w=0;w**3<1e12*x;w++);x<0?-f(-x):w/1e4')

f=(x)=>eval('for(w=0;w**3<1e12*x;w++);x<0?-f(-x):w/1e4')
document.getElementById('div').innerHTML += f(-27) + '<br>'
document.getElementById('div').innerHTML += f(-64) + '<br>'
document.getElementById('div').innerHTML += f(-1) + '<br>'
document.getElementById('div').innerHTML += f(-18.609625) + '<br>'
document.getElementById('div').innerHTML += f(-3652264) + '<br>'
document.getElementById('div').innerHTML += f(-0.001) + '<br>'
document.getElementById('div').innerHTML += f(-7) + '<br><hr>'
document.getElementById('div').innerHTML += f(27) + '<br>'
document.getElementById('div').innerHTML += f(64) + '<br>'
document.getElementById('div').innerHTML += f(1) + '<br>'
document.getElementById('div').innerHTML += f(18.609625) + '<br>'
document.getElementById('div').innerHTML += f(3652264) + '<br>'
document.getElementById('div').innerHTML += f(0.001) + '<br>'
document.getElementById('div').innerHTML += f(7) + '<br>'
<div id="div"></div>

Luis Felipe De Jesus Munoz
quelle
2

Javascript: 73/72 Zeichen

Dieser Algorithmus ist lahm und nutzt die Tatsache, dass diese Frage auf 4 Nachkommastellen begrenzt ist. Es ist eine modifizierte Version des Algorithmus, den ich in der Sandbox vorgeschlagen habe, um die Frage zu überarbeiten. Es zählt von Null bis unendlich h*h*h<a, nur mit einem Multiplikations- und Divisionstrick, um die 4-Dezimalstellen-Genauigkeit zu handhaben.

function g(a){if(a<0)return-g(-a);for(h=0;h*h*h<1e12*a;h++);return h/1e4}

Bearbeiten, 4 Jahre später: Wie von Luis Felipe De Jesus Munoz vorgeschlagen, ist die Verwendung **des Codes kürzer, aber diese Funktion war 2014 nicht verfügbar, als ich diese Antwort schrieb. Wie auch immer, indem wir es benutzen, rasieren wir einen zusätzlichen Charakter:

function g(a){if(a<0)return-g(-a);for(h=0;h**3<1e12*a;h++);return h/1e4}
Victor Stafusa
quelle
1
Stattdessen h*h*hkönnen Sie h**31 Byte ausführen und speichern
Luis Felipe De Jesus Munoz
@LuisfelipeDejesusMunoz Diese Antwort stammt aus dem Jahr 2014. Der **Operator wurde im Jahr 2015 vorgeschlagen und als Teil von ECMAScript 7 im Jahr 2016 akzeptiert. Zu dem Zeitpunkt, als ich das schrieb, war **in der Sprache also nichts vorhanden .
Victor Stafusa
1

Javascript - 157 Zeichen

Diese Funktion:

  • Mit negativen Zahlen umgehen.
  • Behandeln Sie fließend zeigende Zahlen.
  • Für jede eingegebene Nummer schnell ausführen.
  • Hat die maximal zulässige Genauigkeit für Javascript-Gleitkommazahlen.
function f(a){if(p=q=a<=1)return a<0?-f(-a):a==0|a==1?a:1/f(1/a);for(v=u=1;v*v*v<a;v*=2);while(u!=p|v!=q){p=u;q=v;k=(u+v)/2;if(k*k*k>a)v=k;else u=k}return u}

Ungolfed erklärte Version:

function f(a) {
  if (p = q = a <= 1) return a < 0 ? -f(-a)      // if a < 0, it is the negative of the positive cube root.
                           : a == 0 | a == 1 ? a // if a is 0 or 1, its cube root is too.
                           : 1 / f (1 / a);      // if a < 1 (and a > 0) invert the number and return the inverse of the result.

  // Now, we only need to handle positive numbers > 1.

  // Start u and v with 1, and double v until it becomes a power of 2 greater than the given number.
  for (v = u = 1; v * v * v < a; v *= 2);

  // Bisects the u-v interval iteratively while u or v are changing, which means that we still did not reached the precision limit.
  // Use p and q to keep track of the last values of u and v so we are able to detect the change.
  while (u != p | v != q) {
    p = u;
    q = v;
    k = (u + v) / 2;
    if (k * k * k > a)
      v=k;
    else
      u=k
  }

  // At this point u <= cbrt(a) and v >= cbrt(a) and they are the closest that is possible to the true result that is possible using javascript-floating point precision.
  // If u == v then we have an exact cube root.
  // Return u because if u != v, u < cbrt(a), i.e. it is rounded towards zero.
  return u
}
Victor Stafusa
quelle
1

PHP, 61

Basierend auf Newtons Methode. Leicht modifizierte Version von Michaels Antwort :

for($i=$x=1;$i++<99;)$x=(2*$x+$n/$x/$x)/3;echo round($x,14);

Es funktioniert mit negativen Zahlen, kann Gleitkommazahlen verarbeiten und rundet das Ergebnis auf 4 Zahlen nach dem Komma, wenn das Ergebnis eine Gleitkommazahl ist.

Arbeitsdemo

Amal Murali
quelle
Mit können Sie zwei Bytes speichern for($x=1;++$i<100;).... Die Verwendung vordefinierter Variablen als Eingabe wird jedoch im Allgemeinen verpönt . Besser nutzen $argv[1]oder $argn.
Titus
1

Befunge 98 - In Arbeit

Diese Sprache unterstützt keine Gleitkommazahlen. Dies versucht, sie zu emulieren. Es funktioniert derzeit für positive Zahlen, die nicht 0nach dem Komma beginnen (meistens). Es werden jedoch nur 2 Dezimalstellen ausgegeben.

&5ka5k*&+00pv
:::**00g`!jv>1+
/.'.,aa*%.@>1-:aa*

Es funktioniert, indem der Teil vor dem Dezimalpunkt eingegeben und mit multipliziert wird 100000 , dann den Teil nach dem Punkt eingeben und die beiden Zahlen addieren. Die zweite Zeile zählt solange, bis der Würfel größer als die eingegebene Zahl ist. Dann extrahiert die dritte Zeile die Dezimalzahl aus der Ganzzahl.

Wenn mir jemand sagen kann, warum die dritte Zeile nur durch teilt 100 , um die korrekten Werte zu erhalten, sagen Sie es mir bitte.

IOs:

27.0       3 .0
64.0       4 .0
1.0        1 .0
18.609625  2 .65
0.001      0 .1
7.0        1 .91

0.1        0 .1
Justin
quelle
1

Smalltalk, 37

Kredit geht an Mniip für den Algorithmus; Smalltalk-Version seines Codes:

Eingabe in n; Ausgabe in x:

1to:(x:=99)do:[:i|x:=2*x+(n/x/x)/3.0]

oder als Block

[:n|1to:(x:=99)do:[:i|x:=2*x+(n/x/x)/3.0].x]
blabla999
quelle
1

GameMaker-Sprache, 51 Byte

for(i=x=1;i++<99;1)x=(2*x+argument0/x/x)/3;return x
Timtech
quelle
0

Haskell: 99 ° C

Kann @mniip in der Klugheit nicht schlagen. Ich habe gerade eine binäre Suche durchgeführt.

c x=d 0 x x
d l h x
 |abs(x-c)<=t=m
 |c < x=d m h x
 |True=d l m x
 where m=(l+h)/2;c=m*m*m;t=1e-4

Ungolfed:

-- just calls the helper function below
cubeRoot x = cubeRoot' 0 x x

cubeRoot' lo hi x
    | abs(x-c) <= tol = mid           -- if our guess is within the tolerance, accept it
    | c < x = cubeRoot' mid hi x      -- shot too low, narrow our search space to upper end
    | otherwise = cubeRoot' lo mid x  -- shot too high, narrow search space to lower end
    where
        mid = (lo+hi)/2
        cubed = mid*mid*mid
        tol = 0.0001
danmcardle
quelle
Sie können einen Infix-Operator für d(like (l#h)x) verwenden, um ein Byte für jeden Aufruf zu speichern. cdann wird id>>=(0#).
Esolanging Fruit
Sie können Leerzeichen entfernen c < x.
Esolanging Fruit
Sie können 1>0anstelle von verwenden True.
Esolanging Fruit
0

J 28

*@[*(3%~+:@]+(%*~@]))^:_&|&1

Mit der Newton-Methode finden Sie die Wurzel von x^3 - X Aktualisierungsschritts gefunden x - (x^3 - C)/(3*x^2), wobei x die aktuelle Schätzung und C die Eingabe ist. Nachrechnen ergibt den lächerlich einfachen Ausdruck von (2*x+C/x^2) /3. Bei negativen Zahlen ist Vorsicht geboten.

Implementiert in J, von rechts nach links:

  1. | Nimm abs von beiden Argumenten, gib sie weiter
  2. ^:_ Bis zur Konvergenz tun
  3. (%*~@])ist C / x^2( *~ yist äquivalent zuy * y )
  4. +:@] ist 2 x
  5. 3%~durch drei teilen. Dies ergibt die positive Wurzel
  6. *@[ * positive_root multipliziert positive Wurzel mit dem Zeichen von C.

Testlauf:

   NB. give it a name:
   c=: *@[*(3%~+:@]+(%*~@]))^:_&|&1
   c 27 64 1 18.609625 3652264 0.001 7
3 4 1 2.65 154 0.1 1.91293
jpjacobs
quelle
0

AWK, 53 Bytes

{for(n=x=$1;y-x;){y=x;x=(2*x+n/x/x)/3}printf"%.4g",y}

Beispielverwendung:

$ awk '{for(n=x=$1;y-x;){y=x;x=(2*x+n/x/x)/3}printf"%.4g",y}' <<< 18.609625 
2.65$

Vielen Dank an @Mig für die JavaScriptLösung, von der diese abgeleitet ist. Es läuft überraschend schnell, da die forSchleife die Iteration benötigt, um nicht mehr geändert zu werden.

Robert Benson
quelle
0

C 69 Bytes

i;float g(float x){for(float y=x;++i%999;x=x*2/3+y/3/x/x);return x;}

Nur eine weitere Implementierung von Newtons Methode. Probieren Sie es online!

Ceilingcat
quelle
0

Stax , 10 Bytes CP437

╘♀┘A╕äO¶∩'

Online ausführen und debuggen!

Erläuterung

Verwendet die entpackte Version, um zu erklären.

gpJux*_+h4je
gp              Iterate until a fixed point is found, output the fix point
  Ju            Inverse of square
    x*          Multiplied by input
      _+h       Average of the value computed by last command and the value at current iteration
         4je    Round to 4 decimal digits
Weijun Zhou
quelle
0

JAVA-Lösung

public BigDecimal cubeRoot (BigDecimal number) {

    if(number == null || number.intValue() == 0) return BigDecimal.ZERO;
    BigDecimal absNum = number.abs();
    BigDecimal t;
    BigDecimal root =  absNum.divide(BigDecimal.valueOf(3), MathContext.DECIMAL128);


    do {

        t = root;
        root = root.multiply(BigDecimal.valueOf(2))
                .add(absNum.divide(root.multiply(root), MathContext.DECIMAL128))
                .divide(BigDecimal.valueOf(3), MathContext.DECIMAL128);

    } while (t.toBigInteger().subtract(root.toBigInteger()).intValue() != 0);

    return root.multiply(number.divide(absNum), MathContext.DECIMAL128);
}
Ramanathan Ganesan
quelle
1
Willkommen bei PPCG! Dies ist eine Code-Golf- Herausforderung. Das bedeutet, dass das Ziel darin besteht, die Herausforderung so wenig Code wie möglich zu lösen (in Byte der Quelldatei gezählt). Sie sollten einige Anstrengungen unternehmen, um Ihre Lösung für dieses Ziel zu optimieren, und die Anzahl der Bytes in Ihre Antwort aufnehmen.
Martin Ender
0

Python-Lösung

def cube_root(num):
    if num == 0:
        return 0

    t = 0
    absNum = abs(num)
    root = absNum/3

    while (t - root) != 0:
        t = root
        root = (1/3) * ((2 * root) + absNum/(root * root))

    return root * (num / absNum)
Ramanathan Ganesan
quelle