Hacker News new | past | comments | ask | show | jobs | submit login

This may be lower-level, with all the explicit type conversions, but it doesn't look much more complicated to me. Maybe I'm fooling myself?

    variable a  variable b  variable c  fvariable discriminant
    : b^2 b @ dup * ;       : 4ac 4 a @ c @ * * ;   : s>f s>d d>f ;
    : -b  b @ negate s>f ;  : /2a  a @ 2* s>f f/  ; : f. f>d d. ;
    : quadeq c ! b ! a !    b^2 4ac - s>f fsqrt  discriminant f!
        -b  discriminant f@ f+  /2a
        -b  discriminant f@ f-  /2a ;
Usage:

    : kragen@inexorable:~/devel/inexorable-misc ; gforth quadeq.fs
    Gforth 0.6.2, Copyright (C) 1995-2003 Free Software Foundation, Inc.
    Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
    Type `bye' to exit
    2 4 -30 quadeq f. f. -5. 3.  ok
I'd dispense with the floating-point nonsense altogether, but ANS Forth, like C, only defines a square-root routine in floating-point. It's a little more code to define in Forth than in C:

    variable n  : improve  n @ over / + 2/ ;  : far?  - abs 1 > ;
    : sqrt  dup n !  dup if  begin  dup improve  swap over far? while  repeat  then
      dup  dup * n @ > if  1-  then  ;
But that hardly seems like a strong recommendation.

Edit: someone else's cute Newton's-method square-root is at http://jasonwoof.org/sqrt.fs --- it looks quite a bit simpler!




On further inspection, the jasonwoof code is quite a bit simpler not only because it has a better approach (which it does!) but also because it leaves out the checks for 0 and off-by-one. So it crashes on 0 and gives the wrong answer for 6, saying 3 when the answer correct to two places is 2.45. You can correct the wrong answers with the same dup dup * n @ > if 1- then business that I was using, assuming you want floor(sqrt(n)) instead of, say, round(sqrt(n)) or ceil(sqrt(n)).




Consider applying for YC's first-ever Fall batch! Applications are open till Aug 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: