Math.round cant do negative numbers c# [duplicate] - c#

This question already has answers here:
Math.Round with negative parameter
(3 answers)
Closed 5 years ago.
I have a homework where im supposed to create a code which should let the user type in a decimal number and then ask how many decimals the user want the number to be rounded to. The homework assignment were given to us with minimal instruction on how to do it so we were supposed to look online. We were given a hint about Math.Round() and this is my code right now:
Console.WriteLine("Hej! Skriv in ett tal med decimaler.");
string strTal = Console.ReadLine();
double tal = Convert.ToDouble(strTal);
Console.WriteLine("Tack! Skriv nu in hur många decimaler du
vill ha med på ditt tal.");
string strAvrundaren = Console.ReadLine();
int avrundaren = Convert.ToInt32(strAvrundaren);
Console.WriteLine("Ditt tal är: " +
Math.Round(tal,avrundaren));
With this code I got it to work so that whenever the user writes a decimal number and then writes the x amount of decimals it should be rounded to it does so correctly. My problem is that I had the thought if someone were to input a negative decimal number (ex: -1, -2, -2,12313 etc..)? I tried and my code crashed when I did it. Now im coming to you guys for an explanation to why it does this.
EDIT: by saying it "crashes", whenever I write in a negative number in the terminal the window pops down to my sidebar and when I bring it back up nothing has happened on the terminal and I can write as much as I want in the terminal but nothing happens. Im on Visual Studio for the Mac if that helps.
Best Regards
Kian

Your program lacks input validation. Not only will a negative number cause it to crash, but any string that is not numeric will also cause an unhandled exception.
Typically a program should validate its inputs before attempting to use them. If the value isn't valid, you can ask the user to input it again. Example:
using System;
public class Program
{
public static void Main()
{
double tal;
while (true)
{
Console.WriteLine("Hej! Skriv in ett tal med decimaler.");
string strTal = Console.ReadLine();
var ok = double.TryParse(strTal, out tal);
if (ok) break;
}
int avrundaren;
while (true)
{
Console.WriteLine("Tack! Skriv nu in hur många decimaler du vill ha med på ditt tal.");
string strAvrundaren = Console.ReadLine();
var ok = int.TryParse(strAvrundaren, out avrundaren);
if (!ok) continue;
if (avrundaren < 0) continue;
break;
}
Console.WriteLine("Ditt tal är: " + Math.Round(tal,avrundaren));
}
}
Try it on DotNetFiddle

Rounding for negative numbers work: Here is a quick test:
var ans = Math.Round(-100.11119, 2);
Console.WriteLine(ans);
Please see fiddle as proof for above test.
If you pass a negative number for the 2nd argument like this:
var ans = Math.Round(-100.11119, -2);
Console.WriteLine(ans);
You will get a runtime error.
Run-time exception (line 7): Rounding digits must be between 0 and 15, inclusive.
Please see fiddle for above test.
Therefore, you need to check the number provided to you by the user and make sure it is between 0 and 15 (inclusive).

Related

C# guessing game only one guess

i´m stuck with my guessing game where i should only have one chance to guess and then get a "the end" line. I have tried to make a break and breakLoop commands but i´t didn´t work and i have no idé how to fick it... Can someone please help me?
here is my code, i know that it´s not optimal and it´s because i´m still learning C#.
Console.WriteLine("gissa talet\nDu ska nu gissa ett tal mellan 1 ocn 100, så
varsågod..\nskriv in ett tal");
var str = Console.ReadLine();
int guess = Convert.ToInt32(str);
//gonna make it random between 1-100
Random rd = new Random();
int rand_num = rd.Next(1, 10);
{
//when i guess right
if (guess == rand_num)
{
Console.WriteLine("Ditt Tal är rätt. grattis!");
}
//when it´s to small guess
else if (guess < rand_num)
{
Console.WriteLine("Ditt tal är för litet. gissa på ett större tal");
}
//when i guess to big
else if (guess > rand_num)
{
Console.WriteLine("Ditt tal är för stort. gissa på ett mindre tal");
}
// when i was close to the answer
else if (Math.Abs(guess - rand_num) <= 3)
{
Console.WriteLine("Du är dock nära och det bränns");
}
// when i guess a number thats over the number i chould guess
else (guess > 10)
{
Console.WriteLine("Du måste skriva in ett tal mellan 1 och 100!");
}
}
Edit:
As you indeed only want one guess to be allowed, there is no loop needed and your code should work fine (apart form an if missing after the last else statement). To have a "game ended" notice at the end, just add
Console.WriteLine("Game ended.");
at the end of your code.
Also, there is one pair of curled brackets that is not needed in your code. The opening one after int rand_num = rd.Next(1, 10); and the closing one at the very end of the code.
And here remains the original answer:
At first, you want a loop around parts of your code to repeat as long as the answer was not correct or there are no more tries left (in case tries are limited):
const int tries = 10; // Give the player 10 tries to guess correctly.
for (int i = 0; i < tries; i++)
{
if (guessedCorrectly)
{
break;
}
}
Second, you want to define the random number before starting the loop and you want to query new guesses from the player inside the loop:
//Set random number.
//Define Loop.
{
//Get new guess from player.
//Check if guess was correct.
//Decide weather the loop must continue or ended.
}
//Display some result.
Third, you need to change the order of your if else statements. In your code, the statement inside the if (Math.Abs(guess - rand_num) <= 3) guard can never be executed, because you check for guess < rand_num and guess > rand_num before. And since you use else if, the following conditions will never be evaluated if the ones before were true. When using if else statements, alsways check for the more specific cases before checking for the more broad cases. But in your case you probably would want to just remove the else, so both conditions (and both texts) can be executed.

How to do while loop/Do while loop with sentinel value with switch

Hello I am trying to figure out why my program is not working, it's supposed to output a program in which department codes would be entered and followed by a prompt to enter a mark and so on until Q is entered. I can't seem to get that part working at all. If anyone could help please I will appreciate it.
// declare variables
char deptCode = ' ';
int count = 0;
double markVal, sum = 0, average = 0.0;
{
Console.WriteLine("Enter a department code: ‘C’ or ‘c’ for Computer Science,‘B’ or ‘b’ for History, ‘P’ or ‘p’ for Physics, or enter ‘Q’ or ‘q’ to quit:");
deptCode = Convert.ToChar(Console.ReadLine());
while (char.ToUpper(deptCode) != 'Q')
do
{
Console.Write("Enter a mark between 0 and 100 => ");
markVal = Convert.ToDouble(Console.ReadLine());
{
Console.WriteLine("Enter a department code: ‘C’ or ‘c’ for Computer Science,‘B’ or ‘b’ for History, ‘P’ or ‘p’ for Physics, or enter ‘Q’ or ‘q’ to quit:");
deptCode = Convert.ToChar(Console.ReadLine());
} while (markVal >= 0 && markVal <= 100);
count++;
average = (double)sum / count;
Console.WriteLine("***Error, Please Enter Valid Mark");
Console.WriteLine("The Average mark for Computer Science Students is {0}", average);
Console.WriteLine("The Average mark for Biology Students is {0}", average);
Console.WriteLine("The Average mark for Physics Students is {0}", average);
Console.ReadLine();
{
I am sympathetic to your dilemma and know it can be challenging to learn coding when you are not familiar with it. So hopefully the suggestions below may help to get you started at least down the right path. At the bottom of this is a basic “shell” but parts are missing and hopefully you will be able to fill in the missing parts.
One idea that you will find very helpful is if you break things down into pieces (methods) that will make things easier to follow and manage. In this particular case, you need to get a handle on the endless loops that you will be creating. From what I can see there would be three (3) possible endless loops that you will need to manage.
An endless loop that lets the user enter any number of discipline marks.
An endless loop when we ask the user which discipline to use
And an endless loop when we ask the user for a Mark between 0 and 100
When I say endless loop I mean that when we ask the user for a Discipline or a Mark… then, the user MUST press the “c”, “b” “p” or “q” character to exit the discipline loop. In addition the user MUST enter a valid double value between 0 and 100 to exit the Mark loop. The first endless loop will run allowing the user to enter multiple disciplines and marks and will not exit until the user presses the q character when selecting a discipline.
And finally when the user presses the ‘q’ character, then we can output the averages.
So to help… I will create two methods for you. One that will represent the endless loop for getting the Mark from the user… i.e.…. a number between 0 and 100. Then a second endless loop method that will get the Discipline from the user… i.e. … ‘c’, ‘b’, ‘p’ or ‘q’… and it may look something like…
private static char GetDisciplineFromUser() {
string userInput;
while (true) {
Console.WriteLine("Enter a department code: ‘C’ for Computer Science,‘B’ for Biology, ‘P’ for Physics, or enter ‘Q’ to quit:");
userInput = Console.ReadLine().ToLower();
if (userInput.Length > 0) {
if (userInput[0] == 'c' || userInput[0] == 'b' ||
userInput[0] == 'p' || userInput[0] == 'q') {
return userInput[0];
}
}
Console.WriteLine("Invalid discipline => " + userInput + " try again.");
}
}
Note… the loop will never end until the user selects the characters ‘c’, ‘b’, ‘p’ or ‘q’. We can guarantee that when we call the method above, ONLY those characters are returned.
Next is the endless loop to get the Mark from the user and may look something like…
private static double GetMarkFromUser() {
string userInput;
while (true) {
Console.WriteLine("Enter a mark between 0 and 100 => ");
userInput = Console.ReadLine().Trim();
if (double.TryParse(userInput, out double mark)) {
if (mark >= 0 && mark <= 100) {
return mark;
}
}
Console.WriteLine("Invalid Mark => " + userInput + " try again.");
}
}
Similar to the previous method, and one difference is we want to make sure that the user enters a valid number between 0 and 100. This is done using a TryParse method and most numeric types have a TryParse method and I highly recommend you get familiar with it when checking for valid numeric input.
These two methods should come in handy and simplify the main code. So your next issue which I will leave to you, is how are you going to store these values? When the user enters a CS 89 mark… how are you going to store this info? In this simple case… six variables may work like…
int totalsCSMarks = 0;
int totalsBiologyMarks = 0;
int totalsPhysicsMarks = 0;
double totalOfAllCSMarks = 0;
double totalOfAllBiologyMarks = 0;
double totalOfAllPhysicsMarks = 0;
Now you have something to store the users input in.
And finally the shell that would work using the methods above and you should see this uncomplicates things a bit in comparison to your current code. Hopefully you should be able to fill in the missing parts. Good Luck.
static void Main(string[] args) {
// you will need some kind of storage for each discipline.. see above...
char currentDiscipline = 'x';
double currentMark;
while (currentDiscipline != 'q') {
currentDiscipline = GetDisciplineFromUser();
if (currentDiscipline != 'q') {
currentMark = GetMarkFromUser();
switch (currentDiscipline) {
case 'c':
// add 1 to total number of CS marks
// add currentMarkValue to the total of CS marks
break;
case 'b':
// add 1 to total number of Biology marks
// add currentMarkValue to the total of Biology marks
break;
default: // <- we know for sure that only p could be left
// add 1 to total number of Physics marks
// add currentMarkValue to the total of Physics marks
break;
}
}
}
Console.WriteLine("Averages ------");
//Console.WriteLine("The Average mark for Computer Science Students is {0}", totalOfAllCSMarks / totalCSMarks);
//Console.WriteLine("The Average mark for Biology Students is {0}", ...);
//Console.WriteLine("The Average mark for Physics Students is {0}", ...);
Console.ReadLine();
}

C# console application - Calculating an average number

I tried to create a program which would give me an average score of 5 tests. First I created 5 variables that would be declared by an user. But I have a problem that I could not fix by myself. The output of my code shows a false average score of tests, probably I have a mistake somewhere and I would like you to help me in finding it.
Here is a full code:
using System;
namespace Test
{
class MathTest
{
static void Main()
{
string a, b, c, d, e;
Console.WriteLine("1st Test Score: ");
a = Console.ReadLine();
Console.WriteLine("2nd Test Score: ");
b = Console.ReadLine();
Console.WriteLine("3rd Test Score: ");
c = Console.ReadLine();
Console.WriteLine("4th Test Score: ");
d = Console.ReadLine();
Console.WriteLine("5th Test Score: ");
e = Console.ReadLine();
Console.WriteLine("Your Average Test Score is: {0}",
Convert.ToInt32(a + b + c + d + e) / 5);
}
}
}
Hopefully there is only one mistake in the last sentence, the formula. Thanks for your attention.
As others have correctly said, you need to convert the strings to numbers first, then add them, and then divide them.
That fixes some of your problems. However, not all your problems are over yet.
Next: what if someone types in a score of 75.5 ? Teachers sometimes give half points. Integer is not the correct data type. In C#, use decimal for quantities that are exact decimal quantities, and double for quantities that are physical amounts, like length or mass. You should convert all the strings to decimal, not int.
Next: what if someone types in "Hello" or nothing at all, instead of a number? Your program will crash. You need to use a method such as TryParse that detects this situation, and then you need to prompt the user accordingly to re-enter the number correctly.
Now, you should not be rewriting all that code five times over. Make a method which prompts the user in a loop to enter a number, and returns that number when they do so successfully. Always be breaking your problem down into smaller problems and then write a method which solves that problem. That way your main routine stays simple even when your program logic gets complicated.
Finally and most important: today is a good day to learn how to use a debugger. Learn how to find problems like this on your own, rather than asking strangers on the internet to do your work for you. Most of computer programming is debugging, so learn that skill now.
You should Convert.ToInt32 each item (a..e):
...
Console.WriteLine("Your Average Test Score is: {0}",
(Convert.ToInt32(a) +
Convert.ToInt32(b) +
Convert.ToInt32(c) +
Convert.ToInt32(d) +
Convert.ToInt32(e)) / 5.0);
Another (possible) problem is integer division: if you want to have floating point result (e.g. average score 3.5) you should divide by 5.0, not 5
You're concatenating strings first, then casting the result to Int and dividing by 5.
Cast every number first, before doing maths on them.
You are converting the concatenated string. Suppose the user enters:
1
2
3
4
5
Then (a+b+c+d+e) is "12345" and you are calculating 12345/5. You need to cast all strings separately first.
You have to convert before you Sum up.
Console.WriteLine("Your Average Test Score is: {0}", (Convert.ToInt32(a) + Convert.ToInt32(b) + Convert.ToInt32(c) + Convert.ToInt32(d) + Convert.ToInt32(e)/5)
Well, I found out my mistake in the comments and answers and fixed the code (Changed only a mid part)
int a, b, c, d, e;
Console.WriteLine("1st Test Score: ");
a = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("2nd Test Score: ");
b = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("3rd Test Score: ");
c = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("4th Test Score: ");
d = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("5th Test Score: ");
e = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Your Average Test Score is: {0}", Convert.ToInt32(a + b + c + d + e) / 5.0);

Code won't give desired output or read second input

Sorry if this isn't the right. This is my first time posting here. I'm a first year Software student and for the life of me i cannot seem to get this to work. I know its something simple I'm missing but oh well. I tried doing this using methods but again no help. Maybe you guys could help me?
The problem is the code wont let me input after the "Are you a member (Y/N)" writline statement and just keeps giving me an output of 50.
static void Main(string[] args)
{
//Local Variable Declaration//
double rate1 = 10;
double rate2 = 3;
double maxCharge = 50;
double charge;
Console.WriteLine("Enter number of hours (-999 to quit) : ");
int hoursRented = Console.Read();
if (hoursRented >= 3)
{
charge = hoursRented * rate1;
}
else
{
charge = (3 * rate1) + (hoursRented * rate2);
}
if (charge > maxCharge)
{
charge = maxCharge;
}
Console.WriteLine("Are you a member? (Y/N) : ");
int memberStatus = Console.Read();
if (memberStatus.Equals("Y"))
{
charge = (charge * 1 / 10) - charge;
}
Console.WriteLine("Customer Charge : {0} Total Charge To Date : ", charge);
}
The problematic lines are below
Console.WriteLine("Enter number of hours (-999 to quit) : ");
int hoursRented = Console.Read();
if (hoursRented >= 3) {
and
Console.WriteLine("Are you a member? (Y/N) : ");
int memberStatus = Console.Read();
if (memberStatus.Equals("Y")) {
When you call Console.Read(), it reads only characters and returns it as an int. You seem to mistakenly think it will parse the character to an int.
Secondly, think what happens when you provide multiple characters as input to a single Console.Read() call. Interestingly, the remaining characters are read in the subsequent calls. So when you type any number followed by Enter in the first Console.Read it only, reads the first character, the subsequent characters, including the EOLN char are returned in the subsequent calls, instead of prompting you to enter information for the next call.
The fix is easy. Use Console.Readline() and int.parse (or its int.TryParse() variant
Then the corresponding code will look like below
Console.Write("Enter number of hours (-999 to quit) : ");
string hoursRentedStr = Console.ReadLine();
int hoursRented = int.Parse(hoursRentedStr);
if (hoursRented >= 3) {
and
Console.Write("Are you a member? (Y/N) : ");
string memberStatus = Console.ReadLine();
if (memberStatus.Equals("Y")) {
This is because you are just writing:
Console.WriteLine("Are you a member? (Y/N) : ");
and continuing through.
you must do it like this:
Console.WriteLine("Are you a member? (Y/N) : ");
Console.ReadLine();
and then:
int memberStatus = Int.Parse(Console.ReadKey());
your problem is that your are using Console.Read wich returns the ascii code of the next charachter as said by #juharr in the comments. so the solution is too simply replace Read By ReadLine and change your code like this, so that ReadLine wich is a string will be converted to the int value that you want
int hoursRented = int.Parse(Console.ReadLine());
And change your member status to a string to compare it with "Y" easily
string memberStatus = Console.ReadLine();
Note: if you want to validate the input you should use a int.TryParse instead of just a normal parse like I used as it returns a bool so you knows when it fails

Converting input of seconds to Days, Hours, Minutes using methods process in C#

I have checked a bunch of places with very minimal help to help me figure out a methods way in visual studios to open up the console when running the code to prompt the user from the Console.Writeline("Please enter seconds to convert: "); to input the number of seconds that they are trying to convert, once thats put in it would then print the results of the conversion as "Your result is 00:00:00" . Im still in the process of learning more about c# so i have one slightly basic understanding so far and a basic solution but what i currently have is not that I'm trying to have for this project. My solution so far is :
class Program
{
static void Main(string[] args)
{
TimeSpan t = TimeSpan.FromSeconds(36100556);
Console.WriteLine(t.Days);
Console.WriteLine(t.Hours);
Console.WriteLine(t.Minutes);
Console.WriteLine(t.Seconds);
Console.WriteLine(t.ToString());
}
}
I think you need to follow these steps:
1) Send the message requesting the time with the Console.WriteLine.
2) Use the command Console.ReadLine, this will make the console to wait until the user puts the time that need to convert.
3) Read the value and make the math.
4) Display the value using WriteLine.
5) After display the value, put another Consol.ReadLine in order to avoid the console to hide before the user reads the result.
Hope it helps
Console.WriteLine("Enter number of seconds:");
double sec = 0;
// Check if user input correct integer
while(!double.TryParse(Console.ReadLine(),out sec))
{
Console.WriteLine("Your data is invalid. Please input again:");
}
TimeSpan t = TimeSpan.FromSeconds(sec);
Console.WriteLine("Your result is " + t.ToString(#"hh\:mm\:ss"));
Console.ReadLine();
You can use var x = Console.ReadLine() to read input from the console. May have to do some conversions since it will read a string of characters. You can utilize something like Convert.ToDateTime(x) or something to convert to whatever data type you need.
Console.Write("Enter Number of Seconds: ");
string SecondsStr = Console.ReadLine();
Double Seconds = 0;
if(!Double.TryParse(SecondsStr, out Seconds))
{
Console.WriteLine("Invalid number entered");
}
else
{
TimeSpan Time = TimeSpan.FromSeconds(Seconds);
Console.WriteLine(string.Format("Days: {0}, Hours: {1}, Minutes: {2}, Seconds: {3}", Time.Days, Time.Hours, Time.Minutes, Time.Seconds));
}

Categories

Resources