im trying to build an algorythm which input is 10 numbers (positive and negative) and the output is the smallest positive number and the biggest negative number.
im getting the right answer for the smallest positive, but not for the biggest negative.
code and output are inserted.
If you have a collection, say, int[] numbers you can just query it with a help of Linq:
using System.Linq;
...
int[] numbers = ...
...
// Either biggest negative or 0 (if we don't have any negative values)
int biggestNegative = numbers
.Where(x => x < 0)
.DefaultIfEmpty() // <- we don't want exception on empty input
.Max();
// Either smallest positive or 0 (if we don't have any positive values)
int smallestPositive = numbers
.Where(x => x > 0)
.DefaultIfEmpty() // <- we don't want exception on empty input
.Min();
If you prefer to compute the values in a for loop:
int biggestNegative = 0;
int smallestPositive = 0;
for (int i = 0; i < 10; ++i) {
...
// Simplest, you may want to check user input
int value = int.Parse(Console.ReadLine());
...
if (value > 0)
smallestPositive = smallestPositive == 0
? value
: Math.Min(smallestPositive, value);
else if (value < 0)
biggestNegative = biggestNegative == 0
? value
: Math.Max(biggestNegativee, value);
}
Let's print the values out:
Console.WriteLine(
$"Biggest negative: {(biggestNegative == 0 ? "???" : biggestNegative.ToString())}");
Console.WriteLine(
$"Smallest positive: {(smallestPositive == 0 ? "???" : smallestPositive.ToString())}");
if (num>negMax)
There is a mistake in this condition. As your initial negMax value is 0, no negative number will meet the condition, and therefore negMax value will never be updated.
You're initializing negMax as 0.
There is no negative number that is bigger than 0.
Depending on what exactly you want to accomplish, you could do one of the following:
Initialize negMax as int.MinValue
This would be okay if it's guaranteed that there's at least one negative number, since the first negative input is guaranteed to be equal or greater. If negative input isn't guaranteed, you cannot tell if there were any and your output may end up incorrect.
Modify the condition for assigning a new value to negMax
You could instead modify the condition for assigning a new value to negMax to if (num > negMax || negMax >= 0).
Since you usually don't treat 0 as a negative number (and if you do, you can initialize negMax with any positive number instead), you'd know that there were no negative numbers if the output ends up as 0.
To do the same with posMin, you'd have to initialize it as something less than 0 and adjust the if-condition for assigning a value to that variable accordingly.
Alternatively, you could also declare negMax and posMin as int?s and check for null instead of >= 0.
If you choose this way, you can check the values for both variables and output, for example, that no negative or no positive numbers were entered instead of outputting whichever placeholder you chose.
Related
I am debugging a "Guess the Number" program between 1-100. The first user creates a secretNumber and the second user guesses the number.
I'm trying to check if the second user input is a number between 1-100, but it still accepts negative numbers for some reason, and I can't figure out why.
Please note I am very new to coding, so I'm not well-versed with the jargon yet. In my class, we have just learned while loops and relational operators and if/else statements, so I am only allowed to use those.
The (secretNumber == 0) is to make sure int.TryParse() doesn't return 0 if the user typed in letters instead of numbers.
if statement checking:
( secretNumber >= 1 && secretNumber <= 100 )
and also
( secretNumber >= 1 || secretNumber <= 100 )
This is my code:
//Create a number variable to hold the whole number
int secretNumber;
//Validate that the number is a whole number AND between 1 and 100
if ( int.TryParse(secretNumberString, out secretNumber)
|| ( secretNumber >= 1 && secretNumber <= 100 )
|| secretNumber == 0 )
{
// Tell the user the problem
Console.WriteLine("Sorry, please only type in whole numbers and it must be between 1 and 100!");
// Re-ask the question
Console.WriteLine("What is your secret number?");
// Re-catch the response in the same variable
secretNumberString = Console.ReadLine();
// Re-assign the new input
int.TryParse(secretNumberString, out secretNumber);
}
The if statement should run if the user inputs a negative value.
It runs if the user types a value above 100, but it doesn't run if the value is below 100. Otherwise, it shouldn't run if the number is correctly between 1-100.
The statement must be true if the input is either non-numeric or outside 1~100 range. Is that correct?
//if string is NOT integral (notice the !) Or less than 1 Or bigger than 100
if (!int.TryParse(str, out int secretNumber) || secretNumber < 1 || secretNumber > 100)
Also, the user could still input non-integral, out-of-range number at the second attempt as it is not validated. Ideally, I believe it's better to put the validation logic as a loop variable:
string input;
int secretNumber;
do
{
Console.WriteLine("Input an integer between 1 and 100, inclusive.");
input = Console.ReadLine();
}
while (!int.TryParse(input, out secretNumber) || secretNumber < 1 || secretNumber > 100);
The problem is your || (or), this is just a simple Boolean Algebra (Propositional Logic) mistake, it needs to be && (and)
However, a similar neater pattern is a condensed validation loop
var num = 0;
Console.WriteLine("What is your secret number between 1 and 100 inclusively?");
var str = Console.ReadLine();
// while its not a number, "or" the number is less or equal to 0 "or" greater than 100
// annoy them with a message
while (!int.TryParse(str, out num ) || num <= 0 || num > 100)
{
Console.WriteLine("Omg you had one job, a number between 1 and 100 inclusively... Try again");
str= Console.ReadLine()
}
Console.WriteLine($"You won, your number is {num } ");
You might want to read the documentation for int.TryParse() — it returns true if the string was successfully parsed as an integer and false otherwise. Your test, int.TryParse( secretNumberString, out secretNumber ) || ( secretNumber >= 1 && secretNumber <= 100 ) || secretNumber == 0 ) will only ever test the value of secretNumber if the parse failed (at which point its value will be 0).
This might get you started:
static int GetAnswer( string prompt, int min , int max )
{
if (min > max) throw new ArgumentException("min must be less than or equal to max");
int value ;
bool valid = false ;
do
{
Console.WriteLine(prompt);
string answer = Console.ReadLine().Trim() ;
valid = int.TryParse(answer, out value)
&& value >= min
&& value <= max
;
if (!valid)
{
Console.WriteLine($"Sorry, please only type in whole numbers in the range {min}-{max}.");
}
} while (!valid );
return value;
}
This question already has answers here:
C# testing to see if a string is an integer?
(10 answers)
Closed 8 years ago.
//capture input value for peak size and return
public static int GetPeakSize()
{
//declare variables, intitialize and parse after input
int peak;
Console.WriteLine("\nPlease enter the peak size (must be a number 1-10): ");
peak = int.Parse(Console.ReadLine());
//if user enter anything that is not inside the 1-10 range, default
//to 3
if (peak < 1 || peak > 10)
{
peak = 3;
}
return peak;
}
In the method above I'm just trying to gather input, parse it, and if the input does not fall in the range of 1-10, return a default value of 3. But instead of just validating numerical input, I want to return a default value of 3 if ANYTHING but the numerical values of 1-10 are entered. So if they enter "four" instead of 4, I'd like the value to default to 3. I wish I could do something along the lines of if (value != int || value < 1 || value > 10)......default = 3. I know this can't be done but is there anyway around it?
You might want to use TryParse instead:
int peak;
Console.WriteLine("\nPlease enter the peak size (must be a number 1-10): ");
if (!int.TryParse(Console.ReadLine(), out peak) || peak < 1 || peak > 10)
{
peak = 3;
}
The code above will attempt to parse the input into an int -- if it could not, or if the parsed value falls outside of your range constraints, it overrides peak to 3 before continuing on.
EDIT: Missed the range constraints.
Use int.TryParse. int.Parse will throw if the input is non-numeric.
int peak = 0;
bool parseSuccess = int.TryParse(input, out peak);
if (!parseSuccess || peak < 1 || peak > 10)
{
}
int.TryParse will return false if the input is not valid, and if it is valid, then the parsed value will be contained in the "out" parameter (peak in this case).
I've only been doing this a few days and I'm pretty confused.
Everything else works fine, and the box only displays integers, but it still calculates with decimal values.
You should be able to do a int myInt = Convert.ToInt32(numBox.Value);
numBox.Value is a decimal, but that code will cause it to get converted to an integer.
Just know that IF you do get a decimal value back, it will round it up or down.
EDIT:
Aghilas Yakoub's solution might be better if you want only positive values. My solution will convert the decimal to an int, but it could still allow for negatives. Really what you should do is set your numBox.Minimum to 0 so it can't go below 0.
EDIT 2:
If you want to warn when the value is negative, try this:
int myInt = Convert.ToInt32(numBox.Value);
if (myInt < 0)
{
MessageBox.Show("Warning, your number must be 0 or greater");
}
Do you want to warn if the value isn't a whole number (has decimal values)?
You can try with
UInt32 result = 0;
UInt32.TryParse("...",
new CultureInfo(""),
out result);
if(result == 0)
{
Console.WriteLine("No parsing");
}
else
{
Console.WriteLine("result={0}", result);
}
A more elegant solution would be:
If you have access to DevExpress controls, you should use a SpinEdit control.
To limit its range from 0 to 999 (only integer number) set its:
Properties.Mask.EditMask to "##0;"
Properties.MaxValue to 999
Then the following line should work well without exceptions:
int myInt = Convert.ToInt32(numBox.Value);
I mean :
1231 YES
121.1241 NO
121,1241 NO
-121 NO
124a NO
how can i do it faster in C#?
int x;
if (int.TryParse(str, out x) && x > 0)
You can check if it only contains digits:
if (theString.All(Char.IsDigit))
An alternative to actually parsing it is to check if the string is non-empty and only contains digits, optionally with a leading + sign if you want to allow that.
Note that this won't perform any range checking - so 9999999999999999999999999999999999 would be valid, even though it wouldn't fit into an int or a long.
You could use a regex for that, or possibly LINQ:
var nonNegative = text.Length > 0 && text.All(c => c >= '0' && c <= '9');
(This is similar to Guffa's Char.IsDigit approach, but restricts itself to ASCII digits. There are numerous non-ASCII digits in Unicode.)
Note that this will restrict it to non-negative values - not just positive values. How would you want to treat "0" and "0000"?
Simple code indeed :
int number = int.MaxValue;
number = number+1;
Console.WriteLine(number);
Questions :
1) there's should be overflowException. there isn't. why is that?
2) Does the number -2147483648 indicates something about :
) how many bytes is beyond limit size ?
) if i see -2147483648 , How can I know ( if there wasnt an exception) - if this number came from exception ? - must I wrap it with Try Catch ?
p.s. when i wrote :
int number = int.MinValue;
number = number-1;
Console.WriteLine(--number);
I got : 2147483647 (still no exception).
There's should be overflowException. there isn't. why is that?
By default, C# doesn't do overflow checking. You can enable it for a whole assembly (in the "Advanced" bit of the build tab in VS, or /checked+ from the command line) or for a block/expression using the checked keyword
For the second part of your question, -2147483648 is just int.MinValue - signed integers do that, rolling from a very large positive number to a very large negative number.
For example, if you use sbyte (the signed byte type):
sbyte number = 127; // sbyte.MaxValue
number++;
Console.WriteLine(number); // Prints -128
There's nothing funny going on here - it's just normal 2s complement overflow.
Or using byte (unsigned)
byte number = 255; // byte.MaxValue
number++;
Console.WriteLine(number); // Prints 0
Wrap it in a checked block to get an exception. Arithmetic overflow is unchecked by default.
Does the number -2147483648 indicates something about:
It's the min value. When you overflow you'll wrap, so maxValue+1 == MinValue, MaxValue + 2 == MinValue + 1, etc.
The same logic applies in the other direction; MinValue - 1 == MaxValue.
int has a minimal value and a maximal value. If you are overflowing the max value, it simply cycles down to the minimal value.
Example:
int cant have numbers from -10 to 10.
int i = 8; // 8
i++; // 9
i++; // 10
i++; // -10
i++; // -9
i -= 2; // 10
i += 10; // -1
To get overflow exception, use a check block, since it is not checked by default.
checekd
{
int i = int.MaxValue;
i++; // throws
}