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.
Related
The code below restricts everything I need restricted, but it allows the user to input more than 1 decimal point
if (System.Text.RegularExpressions.Regex.IsMatch(txtOperand2.Text,
"[^0-9],[.],[\b]"))
{
MessageBox.Show("Please enter only numbers.");
txtOperand2.Text = txtOperand2.Text.Remove(txtOperand2.Text.Length - 1);
}
As per #DourHighArch's worthy comment. If you are just checking for a valid decimal to a certain number of places, and you want a fast culture aware solution (and other configurability like number styles).
Instead of regex, you could do something like this. decimal.TryParse and checking how many decimal places it has via some means.
Converts the string representation of a number to its Decimal
equivalent. A return value indicates whether the conversion succeeded
or failed.
Given
// gets the decimal places by deconstruction
public static int GetDecimalPlaces(decimal d)
=> BitConverter.GetBytes(decimal.GetBits(d)[3])[2];
Usage
if (decimal.TryParse(argument, out var d) && GetDecimalPlaces(d) == 1)
Console.WriteLine("You win, play again?");
Add pepper and salt to taste
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;
I've made a simple binary to decimal converter, used to work fine, I used a string variable to declare the values, but now realise I will need to store them as integers as I wanted to add in a while loop structure to validate the users choice so they could only enter 0 or 1's.
But I now have a program which says Cannot convert from 'int' to 'System.IFormatProvider'.. As I am a beginner with C#,
I have no idea what this means, and how to over come the problem, any help appreciated.. Here is my code if anyone wants to look at it:
int iBinaryNum; //To store binary number
int iDecimalNum; //To store decimal numbers
//Validation of user choice & main program
while (iBinaryNum == 0 || iBinaryNum == 1)
{
Console.WriteLine("Enter the binary number you want to convert to decimal");
iBinaryNum = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("The Binary number you have entered is " + iBinaryNum);
iDecimalNum = Convert.ToInt32(iBinaryNum, 2);
Console.WriteLine("This converted into decimal is " + iDecimalNum);
}
//If it's not equal to 0 or 1
Console.WriteLine("Invalid binary number, Please re-enter");
//Prevent program from closing
Console.WriteLine("Press any key to close");
Console.ReadKey();
iDecimalNum = Convert.ToInt32(iBinaryNum, 2);
The arguments you passed are int, int. As you can see here, you can either choose between Object, IFormatProvider, String, IFormatProvider or String, Int32.
Since the first int can only be used as Object, this means the second argument has to be IFormatProvider.
If you want a solution, you'll have to clarify what it is you're trying to do. Why do you want to convert an integer to an integer?
Convert.ToInt32(String, Int32) requires the first argument to be a String and the second an integer. You are passing two ints, which resolves to Convert.ToInt32(Object, IFormatProvider) which generates the error. You have to convert the first argument (iBinaryNum) to a String.
But I don't think your code works as you expect, since the while condition only checks if either of the ints is either 1 or 0. If the user enters 1110 it fails. Also, if the user enters anything above Int32.Max (which wouldn't be too surprising, considering how large binary numbers can grow), your program crashes. I would store the user input in a string again and check each character whether it contains valid characters (1 or 0).
Like this:
bool IsBinaryNumber(string test){
foreach(char c in test){
// If c is not either 0 or 1, break.
if(!((c=='0') || (c== '1'))){
return false;
}
}
// If everything went well, it's a binary number.
return true;
}
Complete Solution:
You can Use Regular Expressions to Check for Particular pattern in the Input String
The following program will take the Binary input from user and converts it into the decimal till the invalid value is found
string strBinaryNum=""; //To store binary number
int iDecimalNum; //To store decimal numbers
System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex("^[0-1]+$");
Console.WriteLine("Enter the binary number you want to convert to decimal");
strBinaryNum = Console.ReadLine();
while(r.Match(strBinaryNum).Success)
{
Console.WriteLine("The Binary number you have entered is " + strBinaryNum);
iDecimalNum = Convert.ToInt32(strBinaryNum, 2);
Console.WriteLine("This converted into decimal is " + iDecimalNum);
Console.WriteLine("Enter the binary number you want to convert to decimal");
strBinaryNum = Console.ReadLine();
}
Console.WriteLine("Press any key to close");
Console.ReadKey();
If you look at the different overload of Convert.ToInt32, you will see there are none that take as parameters Int32, Int32.
The overload resolution will select the one that takes object, IFormatProvider instead and 2 is an Int32, not a type that implements IFormatProvider, hence the error.
It is not clear why you are trying to convert an Int32 into an Int32 - you already have the value in iBinaryNum.
I'm not sure I really understand the problem. However here is a loop that will keep the only continue once the binary number requirements have been met.
uint iBinaryNum = 2; //To store binary number
decimal iDecimalNum; //To store decimal numbers
//Validation of user choice & main program
while (iBinaryNum > 1)
{
Console.Write("Enter the binary number you want to convert to decimal: ");
if (!uint.TryParse(Console.ReadLine(), out iBinaryNum) || iBinaryNum > 1)
{
//If it's not equal to 0 or 1
Console.WriteLine("Invalid binary number, Please re-enter");
iBinaryNum = 2;
}
}
iDecimalNum = Convert.ToDecimal(iBinaryNum);
Console.WriteLine("This converted into decimal is " + iDecimalNum);
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
I have tried to do this - Making any float value to int value. What I tried to achieve is make it 2.00-2.99 goes to 2.
Note: Im not trying to do Approximation (lower than 2.49 goes to 2, and those 2.50+ goes to 3).
I have done this so far
public int RemoveDecimal(float value)
{
string TempText = (string)value;
TempText.Remove(IndexOf('.'));
return int.parse(TempText);
}
But this will get an error when the float value ends with .00
How can I achieve this?
Thanks for any help
Math.Floor is the function you need.
It:
Returns the largest integer less than or equal to the specified number.
Example:
var val = Math.Floor(value);
Or, you could simply cast to an integer - this will simply ignore the decimal portion, so long as the range of the decimal is within the range of an int (otherwise you will get an exception):
int noDecimals = (int)value;
you can't always convert a float to an int because most of the values in float are out of range for int. you should return a string.
the following will do just that.
public string RemoveDecimal(float value)
{
string TempText = value.ToString("#");
return TempText;
}
Simply casting a floating point number to int does what you want.
i = (int)myFloat;
It truncates the fractional digits, i.e. it always goes in the direction of 0.
(int)2 == 2
(int)1.9 == 1
(int)-1.5 == -1
This will obviously not work correctly if the result is outside the valid range of int. If you want to achieve the same thing, but with a floating point number as result, Math.Truncate is what you need.