PROGRAM Newton
    USE double
    IMPLICIT NONE
    REAL(KIND=DP) :: target, current
    REAL(KIND=DP), DIMENSION(5) :: previous
    INTEGER :: i, k
mainloop: DO
        PRINT *, 'Type in a real number'
        READ (*, *, IOSTAT=k) target
        IF (k < 0) THEN
            STOP 1
        ELSE IF (k > 0) THEN
            PRINT *, 'Some sort of horrible I/O error'
            STOP 1
        END IF 
        IF (target .EQ. 0.0_DP) THEN
            PRINT *, 'The cube root of zero is, er, zero'
            CYCLE
        END IF
!
! This is cheating, but the hardest part of Newton-Raphson solution of
! Nth roots is getting the starting value, and doing so properly would
! merely be confusing.  So use a horrible hack to get an approximation.
!
        current = 1.1*CMPLX(target,KIND=KIND(0.0))**0.3
        DO i = 1,5
            previous(i) = 0.0_DP
        END DO
loop:   DO
            current = current - &
                value(current,target)/derivative(current)
            PRINT *, current
            DO i = 1,5
                if (current .EQ. previous(i)) EXIT loop
            END DO
            DO i = 1,4
                previous(i+1) = previous(i)
            END DO
            previous(1) = current
        END DO loop
        PRINT *, current**3, current**3.0_DP
    END DO mainloop

CONTAINS

FUNCTION value (arg, targ)
    USE double
    IMPLICIT NONE
    REAL(KIND=DP) :: value, arg, targ
    value = arg**3-targ
END FUNCTION value

FUNCTION derivative (arg)
    USE double
    IMPLICIT NONE
    REAL(KIND=DP) :: derivative, arg
    derivative = 3*arg**2
END FUNCTION derivative

END PROGRAM Newton
