0

The functions purpose is to calculate the square root of a number using the Newton-Raphson method. I included a printf routine in the while loop so I can see the value of root 2 get closer and closer to the actual value. I originally used float to define epsilon but as I increased the value of epsilon, the value of the return results seem to be cut-off after a certain number of digits. So I decided to switch all the variable to long double, and the program is displaying negative results. How do I fix it?

//Function to calculate the absolute value of a number

#include <stdio.h>

long double absoluteValue (long double x)
{
    if (x < 0)
        x = -x;
    return (x);
}

//Function to compute the square root of a number

long double squareRoot (long double x, long double a)
{
    long double guess = 1.0;

    while ( absoluteValue (guess * guess - x) >= a){
        guess = (x / guess + guess) / 2.0;
        printf ("%Lf\n ", guess);
        }

    return guess;
}

    int main (void)
    {
    long double epsilon = 0.0000000000000001;

    printf ("\nsquareRoot (2.0) = %Lf\n\n\n\n", squareRoot (2.0, epsilon));
    printf ("\nsquareRoot (144.0) = %Lf\n\n\n\n", squareRoot (144.0, epsilon));
    printf ("\nsquareRoot (17.5) = %Lf\n", squareRoot (17.5, epsilon));

    return 0;
}
Rockstar5645
  • 4,376
  • 8
  • 37
  • 62
  • I'm running this on my PC ( gcc version 4.8.3 in cygwin ), and I get exactly the expected values. – Matthew Carlson May 30 '15 at 18:13
  • Why isn't it working on my computer, I am using Code::Blocks 13.12, it should work. – Rockstar5645 May 30 '15 at 18:43
  • I edited my answer to recommend trying just straight `double`, and putting in some code to avoid infinite loop. – Matthew Carlson May 30 '15 at 18:58
  • Side note: Functions from the `printf` family promote `float` to `double` so they treat `%f` and `%lf` in the same manner (expecting an 8-byte argument). They (`%f` and `%lf`) are distinguishable only when used in functions from the `scanf` family. – barak manos May 30 '15 at 19:03

1 Answers1

0

If you are using the version of Code::Blocks with mingw, see this answer: Conversion specifier of long double in C

mingw ... printf does not support the 'long double' type.

Some more supporting documentation for it.

http://bytes.com/topic/c/answers/135253-printing-long-double-type-via-printf-mingw-g-3-2-3-a

If you went straight from float to long double, you may try just using double instead, which is twice as long as a float to start with, and you may not need to go all the way to a long double.

For that you would use the print specifier of %lf, and your loop might want to look something like this, to prevent infinite loops based on your epsilon:

double squareRoot (    double x,     double a)
{
    double nextGuess = 1.0;
    double lastGuess = 0.0;

    while ( absoluteValue (nextGuess * nextGuess - x) >= a && nextGuess != lastGuess){
        lastGuess = nextGuess;
        nextGuess = (x / lastGuess + lastGuess) / 2.0;
        printf ("%lf\n ", nextGuess);
        }

    return nextGuess;
}
Community
  • 1
  • 1
Matthew Carlson
  • 654
  • 5
  • 12