math.sqrt vs. Newton-Raphson Method for finding roots in c# - c#

I'm doing a homework project that requires this:
Below you will find the code that I have written to compute the square root of a number using the Newton-Raphson method. Include it in your project. For this project your job will be to write a test harness that tests the code that I have written. Carefully read the method prologue to understand how the function should work. Your test harness will provide a loop that:
Prompts the user to enter in a test value.
Gets the user's input. If a zero is entered, your program will print out a report and terminate.
Calls the Sqrt method provided in this project, and saves the return value in a double variable.
Calls the Sqrt method that is built into the Math class and saves the return value in a second double variable.
Compare these two values to see if they are equal.
When the user indicates that they are done (by entering a zero) display a report that shows this information:
* How many test cases you executed
* How many passed
* How many failed
So I've done all this without any problems in about 15 minutes, however for extra credit he asks us to find what is wrong with his Sqrt method and fix it so its return value equals the Math.Sqrt return value of the .net framework. I can't seem to find the problem in his method, and I want to find it, so I was wondering if anyone could point me in the right direction as to what the problem is with his Sqrt method? Thanks.
Here is my complete code:
// declare variables
double userInput = 0.0;
double debrySqrtReturnValue = 0.0;
double dotNetSqrtReturnValue = 0.0;
int testCasesExecuted = 0;
int testsPassed = 0;
int testsFailed = 0;
bool isEqual = false;
do
{
// Prompt the user to enter in a test value
Console.Write("Please enter a positive integer value: ");
userInput = double.Parse(Console.ReadLine());
if (userInput != 0)
{
debrySqrtReturnValue = Sqrt(userInput);
dotNetSqrtReturnValue = Math.Sqrt(userInput);
Console.WriteLine("The square root of {0} is: {1}", userInput, debrySqrtReturnValue);
Console.WriteLine("The real square root of {0} is: {1}\n", userInput, dotNetSqrtReturnValue);
if (debrySqrtReturnValue == dotNetSqrtReturnValue)
isEqual = true;
else
isEqual = false;
if (isEqual)
testsPassed++;
else
testsFailed++;
testCasesExecuted++;
}
} while (userInput != 0);
Console.WriteLine("\n\n--------------------------------Report---------------------------------");
Console.WriteLine("test cases excecuted: {0}", testCasesExecuted);
Console.WriteLine("tests passed: {0}", testsPassed);
Console.WriteLine("tests failed: {0}", testsFailed);
Console.ReadLine();
}
// The Sqrt method
// Purpose: to compute the square root of a number
// Parameters: a positive, non-zero integer
// returns: a double, which is the square root of the number
// ---------------------------------------------------------
static double Sqrt(double number)
{
// constants to use in the calculation
const int FIRST_APPROX = 2;
const double EPS = 0.001;
// a local variable
double xN = 0;
// pick 2 as first approximation
double xNPlus1 = FIRST_APPROX;
do
{
xN = xNPlus1;
xNPlus1 = xN - ((xN * xN - number) / (FIRST_APPROX * xN));
} while (Math.Abs(xNPlus1 - xN) > EPS);
return xN;
}
}

Try setting const double EPS = 0.000000001; - that's your epsilon. That's what determines the precision of your answer.

Math.sqrt returns NaN if the argument is negative. Also, I think EPS would be much smaller.

Related

I can't imagine what the code should be to solve these kinds of problems

Given the limit of changing the value of variables, calculate the function according to the formula.
enter image description here
This function is a little more difficult to imagine, before that I made a regular function and I can not imagine the essence of complex functions.
class Program
{
static void Main(string[] args)
{
double x <= 1.4;
Console.WriteLine("Enter the value of x:");
double x = Convert.ToDouble(Console.ReadLine());
double result = Math.sqr(x)-(7 / x);
double result2 = a * Math.pow(3, x) + 7 * Math.Sqrt(x);
double result3 = Math.log10(x + 7);
Console.WriteLine("The result of the function is: ");
}
}
Probably you should create a method for this function like:
public double f(double x)
{
if (x < 0.7 || x > 2)
throw new ArgumentOutOfRangeException(...);
if (x < 1.4)
return ...
else if (x == 1.4)
return ...
else
return ...
}
And then you can call this method from your Main() method, where you can get the value of x from user input, as you already do, and call f(x) to calculate the result.
There is an issue though. Floating point numbers are represented only approximately. E.g. value 1.4 can be actually stored as 1.399999999998... or 1.40000000000013..., so x == 1.4 comparison is not really correct.
Usually floating point values are checked against some interval, something like Math.Abs(x - 1.4) < 1E-15.
Another option is to use decimal type (see Difference between decimal, float and double in .NET?)

A program that determines if the user feed is integer of decimal

I'm doing a school assignment in which we are assigned to make a program that asks the user to input a number. It then changes the input into a number and determines if the number is an integer or a decimal. If not possible, it says this to the user. The program cannot have errors that the users input can cause.
My problem is the part where the program determines if the feed is an integer or a decimal, if I input an integer, it says the number is integer and decimal, if I input a decimal, it ends in an error. The program never reaches catch (Exception) if the input is wrong.
public static void ITellYouYourNumbers(float number)
{
try
{
float d = number;
int isInt = (int)d;
Console.WriteLine("The number is a integer");
float isFloat = (float)d;
Console.WriteLine("The number is a decimal");
}
catch (Exception)
{
Console.WriteLine("Your input cannot be changed into a number. Try again.");
Console.ReadLine();
throw;
}
}
static void Main(string[] args)
{
Console.WriteLine("Write a number");
float num = float.Parse(Console.ReadLine());
ITellYouYourNumbers(num);
}
I've tried determening the d in different ways, such as:
decimal d = number
Console.WriteLine((d % 1) == 0);
d = number
Console.WriteLine((d % 1) == 0);
and
(d % 1) < epsilon
but nothing I've tried works. If the input is integer, it shows as an integer and decimal, if I input a decimal, it says that an error occured in the float num = float.Parse(Console.ReadLine()); , but it doesn't show up as an error in the program itself.
First, float.Parse() will fail with an exception if the string you put in can not be parsed as a float (beware of the high and low limits too, there are minimum and maximum values) and the exception will not be stopped by the catch since it was not generated in the try-catch block.
Second, a float can always be casted to an int.
Third, you are casting d to a float while d is already a float so why would it not work ?
Fourth, you are putting your float parameter (called "number") in another float inside the function (called "d"). While not wrong technically speaking, it bothers me to duplicate a value when you have no plan to modify either instance of it.
If you can modify the main, call directly your ITellYouYourNumbers function and put the string in without trying to parse it. If I understand the instructions of your exercise correctly, all you have to do is check that
1/ The string is not empty even after removing all blank characters at both ends.
2/ After trimming, it contains only numbers and at most one '.' or ',' character.
3/ If it contains a '.' or ',', it is a decimal. Otherwise, it is an integer.
If you are actually supposed to cast the input as a number, you can check if it represents an integer by exploiting the fact that int x = (int)y will get the integer part of y and put it in x.
After that, you just have to check whether x==y or not.

3 equals 51 in C# [duplicate]

I want to get a number from the user, and then multiply that number with Pi. my attempt at this is below. But a contains gibberish. For example, if I insert 22, then a contains 50. What am I doing wrong? I don't get any compiler errors.
double a,b;
a = Console.Read();
b = a * Math.PI;
Console.WriteLine(b);
I'm not sure what your problem is (since you haven't told us), but I'm guessing at
a = Console.Read();
This will only read one character from your Console.
You can change your program to this. To make it more robust, accept more than 1 char input, and validate that the input is actually a number:
double a, b;
Console.WriteLine("istenen sayıyı sonuna .00 koyarak yaz");
if (double.TryParse(Console.ReadLine(), out a)) {
b = a * Math.PI;
Console.WriteLine("Sonuç " + b);
} else {
//user gave an illegal input. Handle it here.
}
a = double.Parse(Console.ReadLine());
Beware that if the user enters something that cannot be parsed to a double, an exception will be thrown.
Edit:
To expand on my answer, the reason it's not working for you is that you are getting an input from the user in string format, and trying to put it directly into a double. You can't do that. You have to extract the double value from the string first.
If you'd like to perform some sort of error checking, simply do this:
if ( double.TryParse(Console.ReadLine(), out a) ) {
Console.Writeline("Sonuç "+ a * Math.PI;);
}
else {
Console.WriteLine("Invalid number entered. Please enter number in format: #.#");
}
Thanks to Öyvind and abatischev for helping me refine my answer.
string input = Console.ReadLine();
double d;
if (!Double.TryParse(input, out d))
Console.WriteLine("Wrong input");
double r = d * Math.Pi;
Console.WriteLine(r);
The main reason of different input/output you're facing is that Console.Read() returns char code, not a number you typed! Learn how to use MSDN.
I think there are some compiler errors.
Writeline should be WriteLine (capital 'L')
missing semicolon at the end of a line
double a, b;
Console.WriteLine("istenen sayıyı sonuna .00 koyarak yaz");
a = double.Parse(Console.ReadLine());
b = a * Math.PI; // Missing colon!
Console.WriteLine("Sonuç " + b);
string str = Console.ReadLine(); //Reads a character from console
double a = double.Parse(str); //Converts str into the type double
double b = a * Math.PI; // Multiplies by PI
Console.WriteLine("{0}", b); // Writes the number to console
Console.Read() reads a string from console A SINGLE CHARACTER AT A TIME (but waits for an enter before going on. You normally use it in a while cycle). So if you write 25 + Enter, it will return the unicode value of 2 that is 50. If you redo a second Console.Read() it will return immediately with 53 (the unicode value of 5). A third and a fourth Console.Read() will return the end of line/carriage characters. A fifth will wait for new input.
Console.ReadLine() reads a string (so then you need to change the string to a double)
Sometime in the future .NET4.6
//for Double
double inputValues = double.Parse(Console.ReadLine());
//for Int
int inputValues = int.Parse(Console.ReadLine());
double a,b;
Console.WriteLine("istenen sayıyı sonuna .00 koyarak yaz");
try
{
a = Convert.ToDouble(Console.ReadLine());
b = a * Math.PI;
Console.WriteLine("Sonuç " + b);
}
catch (Exception)
{
Console.WriteLine("dönüştürme hatası");
throw;
}
Console.Read() takes a character and returns the ascii value of that character.So if you want to take the symbol that was entered by the user instead of its ascii value (ex:if input is 5 then symbol = 5, ascii value is 53), you have to parse it using int.parse() but it raises a compilation error because the return value of Console.Read() is already int type. So you can get the work done by using Console.ReadLine() instead of Console.Read() as follows.
int userInput = int.parse(Console.ReadLine());
here, the output of the Console.ReadLine() would be a string containing a number such as "53".By passing it to the int.Parse() we can convert it to int type.
You're missing a semicolon: double b = a * Math.PI;

Request for explanation of for-loop logic as it is applied in this C# armstrong number checker

Homework alert! I am trying to build a console app to determine whether a given integer is an Armstrong number. I found a working solution online, but after spending far too much time analyzing it, I still don't understand the logic well enough to reproduce it on my own... The two pain points I've identified are 1) I do not understand exactly how the Parse method is acting upon the integer that the user inputs, and 2) the logic sequence of the for loop is not self-evident (see code and my logic description below):
int number, remainder, sum = 0;
Console.WriteLine("Enter a number: ");
number = int.Parse(Console.ReadLine());
for (int i = number; i > 0; i = i / 10)
{
remainder = i % 10;
sum = sum + remainder * remainder * remainder;
}
if (sum == number)
{
Console.Write("Entered Number is an Armstrong Number");
}
else
Console.Write("Entered Number is not an Armstrong Number");
Console.ReadLine();
This is how my understanding of the for loop logic breaks down:
The integer is passed into the for loop and assigned to int i
//e.g. i = 153//
If the value of i is greater than 0, then re-assign the value of i to i/10 //e.g. 153/10 == 15r3 //
Assign the remainder value of i/10 to int remainder //e.g. remainder = 3//
Compute the sum as sum + remainder * remainder * remainder //e.g. sum = 0 + 3 * 3 * 3//
if the sum is equal to the number, then print "Entered number is Armstrong number" //e.g. however, 27 !== 153//
What am I missing here?
Since this is self-admitted homework, I'm not going to give you a complete answer, but pointers instead.
Make number a string variable. You can then use your for loop to go through each character in the string and perform the math on them.
Use math.pow to create your sum, not sum = sum + remainder * remainder * remainder, since this makes the assumption that you are always using a 3-digit number. (hint: int N = number.Length()
Helper links:
math.pow
Armstrong Numbers

How to make a method taking unknown amount of values?

To explain the question on a simple example, let's say:
I have a method which takes the average of two numbers:
private double TakeAverage(double n1,double n2)
{
average = (number1 + number2) / 2.0000;
return average;
}
And I call it like:
textBox3.Text = (TakeAverage(number1, number2)).ToString();
Q1:
How to make this function able to run without calling it multiple times like:
TakeAverage(number1, number2, number3, number4, number5) // as wanted number of times...
Q2:how to make this function changing return value by number of values which it takes?
For example
Substring(1) //if it takes just one value, it returns all the chars after first char but
Substring(1,2)//if it takes two values, it returns 2 characters after first char
Check this out:
public double TakeAverage(params double[] numbers)
{
double result = 0.0;
if (numbers != null && numbers.Length > 0)
result = numbers.Average();
return result;
}
As params allows the client to send nothing, we should test whether numbers exists and has items.
Usage:
double average = TakeAverage(1, 2, 3, 4.4); //2.6
double anotherAverage = TakeAverage(); //0
double yetAnotherAverage = TakeAverage(null); //0
UPDATE
Based on your comments, I understand that you're looking for something that's called overload: you want that a given method behaves differently based on its arguments.
I'll give an example, you must modify it to suit your needs.
Let's pretend that, besides our original TakeAverage method, we want another one that does an average and multiplies it for a given number. It would be something like:
public double TakeAverage(int factor, params double[] numbers)
{
double result = 0.0;
if (numbers != null && numbers.Length > 0)
result = numbers.Average() * factor;
return result;
}
Usage:
double average = TakeAverage(1.0, 2, 3, 4.4); //2.6
double notAnAverage = TakeAverage(1, 2, 3, 4.4); //3.1333...
Note that I had to explicitly say that the first number is a double (1.0), otherwise it would fall on the second overload and multiply it.
There is the params-keyword where you can say that you take a not-specified amount of arguments.
From MSDN
The params keyword lets you specify a method parameter that takes a variable number of arguments.
You can send a comma-separated list of arguments of the type specified in the parameter declaration, or an array of arguments of the specified type. You also can send no arguments.
No additional parameters are permitted after the params keyword in a method declaration, and only one params keyword is permitted in a method declaration.
Example:
private double TakeAverage(params double[] numbers)
{
double average = 0.0;
if(numbers != null && numbers.Length > 0){
foreach(double d in numbers)
average += d;
average /= numbers.Length;
}
return average;
}
In response to your substring function question.
If you specify one argument, sub string(5) for example, it will return all the characters AFTER the 5th character in the string.
if I have the string "elephant", it would return "ant".
If I add a second argument to the function, it will start at the first given argument, as above, and go on x amount of characters before stopping.
if we use the above example string, "elephant" and do sub string(5,1) it would return "a".
(a good way to work this out is to add both numbers, that will be the last character in your string!)
What I'm asking it to do is create a new string going from the 5th character in the given string, and for my new string to be 1 character long.
This is because the string class has overloaded the sub-string method.
See here : http://msdn.microsoft.com/en-us/library/system.string.substring(v=vs.71).aspx

Categories

Resources