C# String multiplication error - c#

I have an assignment for TAFE in which i have to create a console program in Visual Studio that calculates the cost of a consultation based on consultation time (at $25 an hour).
string hours, rate, total;
Console.Write("Enter consultation time in hours");
hours = Console.ReadLine();
rate = ;
total = hours * rate;
Console.WriteLine("Fee is " + total);
My problem is on line 5, I get the error "operator '*' cannot be applied to operands of type 'string' and 'string;"
Can someone explain to me what is wrong, why 2 strings cant be multiplied and also supply an alternate method of getting that line to work?
EDIT: Thank you everyone. All info given was helpful. I've completed it leaving the rate as an Integer as its a set value not changed by user input, the hours and total are still strings, The hours converting to decimal via the convert.ToDecimal line GianlucaBobbio gave me. The only problem now is console doesnt stay open after calculating rate * hour, but i can fix that.
You may just have a new regular user :D! appreciate the help. you're all life savers :)

You're looking for a numeric type like int or decimal. You'll need to parse those from the input.

Console.ReadLine() returns a string so naturally, you can't multiply a string with a number. You have to parse the string as a double/int/float/decimal (whatever the case is) and then do the multiplication.
One example would be:
double hours = 0.0;
if(double.TryParse(Console.ReadLine(),out hours))
{
total = (decimal)hours * rate;
Console.WriteLine("Fee is " + total);
}
else
Console.WriteLine("You did not enter a valid number of hours.");
Since this is a calculation about money, your rate and total variables should be of type decimal.

You should convert both strings to decimal, so you can multiple them and finally convert them to string again. So you can use de Convert method.
string hours, rate, total;
Console.Write("Enter consultation time in hours");
hours = Console.ReadLine();
rate = ;
total = Convert.ToString(Convert.ToDecimal(hours) * Convert.ToDecimal(rate));
Console.WriteLine("Fee is " + total);
To handle if he puts a valid number you can use decimal.TryParse(string, decimal) which returns a bool value, and if the string is a decimal value it'll be in the out variable like decimal
string hours, rate, total;
Console.Write("Enter consultation time in hours");
hours = Console.ReadLine();
rate = ;
decimal hourInput = 0;
if(!decimal.TryParse(hours, out hourInput)
{
Console.Write("Thats not a number!");
}
else
{
total = Convert.ToString(hourInput * Convert.ToDecimal(rate));
Console.WriteLine("Fee is " + total);
}
Sorry for my bad english

C#'s type system doesn't allow for a lot of inference; unlike JavaScript or Ruby, for example, it won't implicitly convert strings to numeric types when you attempt to perform arithmetic on them. Instead, you must explicitly convert the user's input from a String to some numeric type. Here's one approach:
string hours;
decimal numericHours, rate, total;
Console.Write("Enter consultation time in hours");
hours = Console.ReadLine();
if (!Decimal.TryParse(hours, out numericHours))
{
Console.WriteLine(String.Format("{0} doesn't appear to be a valid number of hours. Please enter a numeric value.", hours));
}
else
{
rate = 35.6;
total = numericHours * rate;
Console.WriteLine("Fee is " + total);
}
That if statement deserves some further explanation: Decimal.TryParse() is one of the rare methods in the .NET framework that has two effects: it returns true or false depending on whether the first parameter can be successfully parsed as data of type decimal. The second parameter, decorated with the out keyword, will contain the resulting decimal value if the parse was successful.
A couple of bonus .NET tips: Notice the use of String.Format() to control the insertion of variables into strings - I find it nicer to use than the + string-concatenation operator. Also, as other answers have pointed out, arithmetic is performed somewhat differently on double and decimal types, due to different binary representations. When dealing with precise fractional values, especially monetary, prefer the decimal type.

Related

An interest calculation task I'm working on doesn't output the proper results

So I'm currently taking a C# fundamentals course as the entrance stage of a 6 month C# learning program. One of the tasks we have under the "Data Types and Variables" is an interest calculator.
The premise is such: You have a "deposit" that you write in the first line. The deposit has a 5% interest to it. The program needs to output the deposit's value for 3 years, for each year, all at once.
So 100.00, 105.00, 110.25, 115.76. The numbers after the decimal point need to be rounded to 2 digits, as well as "The rules of math for rounding apply here".
double deposit = double.Parse(Console.ReadLine());
double interest = (deposit*5)/100;
double yearOne = deposit + interest;
double yearTwo = yearOne + interest;
double yearThree = yearTwo + interest;
string totalSums = ($"{yearOne:N2}\n{yearTwo:N2}\n{yearThree:N2}\n");
Console.WriteLine( totalSums );
This is the code I've written so far. It SEEMS to work, but it's not as accepted.
If I put the deposit value as 100 (one of the examples), I get this output:
100
105.00
110.00
115.00
I've put the calculation for the interest percentage as double interest = (deposit*5)/100, which checks out if I use an external calculator to test it. But the program doesn't give the right output.
Say if I put 100.23 as the deposit input, I'll get: 105.24, 110.25, 115.26 when I should get 105.24, 110.50, 116.02. However, a round 100.00 doesn't even display the digits after the decimal point, just rounds them down to the whole number.
I thought the problem comes from using double and not decimal due to floating-point precision issues, so I changed everything to decimal. I still get this exact problem. Nothing changes.
I've had other issues that I at least have ideas on where I'm going wrong, but this one has been screwing with me since 3 days. So I resorted to some help here.
Why am I not getting the correct outputs ? Where is my problem coming from ? Is it the math ? Or logic ? Maybe I'm not using the correct method ? I'm at a loss... And the learning resources I've been given don't seem to help me with this issue, too. Like it's the ONLY task that the resources don't help with.
I've also seen other posts about compound interest, but they use arrays and other things that I'm not yet at the point of learning within the program. So code like that isn't gonna pass the automatic tester. I'm not asking for a complete code solving or "cheat" if you will; I just need some guidance on what my issue here is, because I'm clueless at this point.
Your question is about compound interest, not simple interest. Therefore, you need to calculate the new interest every year.
double deposit = double.Parse(Console.ReadLine());
double yearOne = deposit + (deposit * 5)/100;
double yearTwo = yearOne + (yearOne * 5)/100;
double yearThree = yearTwo + (yearTwo * 5)/100;
string totalSums = ($"{yearOne:N2}\n{yearTwo:N2}\n{yearThree:N2}\n");
Console.WriteLine( totalSums );
If you know about loops, you can create a loop over 3 years and update the amount in the account:
static class Program
{
static void Main(string[] args)
{
// set interest rate (fixed)
decimal rate = 5m/100;
// get deposit amount from user
Console.WriteLine("Enter Initial Amount:");
string input = Console.ReadLine();
decimal amount = decimal.Parse(input);
// loop over three years
Console.WriteLine($"{"year"}\t{"amount"}");
for (int year = 1; year <= 3; year++)
{
// calculate interest for the year based on
// current amount in the account
decimal interest = rate * amount;
// deposit interest in account
amount += interest;
Console.WriteLine($"{year}\t{amount:c2}");
}
}
}
with output
Enter Initial Amount:
1000
year amount
1 $1,050.00
2 $1,102.50
3 $1,157.63
you need to recalculate the interest amount each year.
double deposit = double.Parse(Console.ReadLine());
//Use deposit to calculate interest
double yearOneinterest = (deposit*5)/100;
double yearOne = deposit + yearOneinterest;
//Use yearOne amount to calculate interest
double yearTwointerest = (yearOne*5)/100;
double yearTwo = yearOne + yearTwointerest;
//Use yearTwo amount to calculate interest
double yearThreeinterest = (yearTwointerest*5)/100;
double yearThree = yearTwo + yearThreeinterest;
string totalSums = ($"{yearOne:N2}\n{yearTwo:N2}\n{yearThree:N2}\n");
Console.WriteLine( totalSums );

Compound Interest Calculation

I have this C# code which calculate compound interest plus principal amount every year.
static void CompoundInterest(double principal, double interestRate, double years, double annualCompound)
{
var total = 0.0;
for (int t = 1; t < years + 1; t++)
{
total = principal * Math.Pow((1 + interestRate / annualCompound),
(annualCompound * t));
Console.Write("Your Total for Year {0} "
+ "is {1}. \n", t, total);
}
}
When I tested it with
CompoundInterest(1000, 0.05, 3, 12);
and the output is
Your Total for Year 1 is 1051.161897881733.
Your Total for Year 2 is 1104.941335558327.
Your Total for Year 3 is 1161.4722313334678.
How should I round it accurately? Another question is Math.Pow uses double but in financial calculation, we need decimal. How do I fix this? Convert into decimal after Math.Pow?
I made some test by rounding first and converting to decimal and by converting to decimal and then rounding afterword. Both gave the same results.
But from the logic point of view, I would convert first than rounding after words. This way I will have better control of testing what is converted and what is rounded.
For converting there are different answers, but I found this method Convert.ToDecimal is supported by all .net frameworks and cores.
ex. decimal value = Convert.ToDecimal(double_value);
And then you decimal.Round, which some one has asked and got answer here Why does .NET use banker's rounding as default?
Just in case reference to Floating-point numeric types.
You can convert a double to a decimal directly if you'd like
decimal decimalTotal = (decimal)total;
As for rounding, there is a built-in function, Math.Round, that takes a variety of number formats. It has a overload to specify how many decimal points you want.
decimal roundedDecimal = Math.Round(decimalTotal, 2);

Code for calculating amount of currency thinks it’s quirky. (Unintended Decimals keep appearing)

I’m just starting out learning C# through CodeAcademy. I’m supposed to write a program to calculate the least amount of “coins” of different values that are needed to reach a specified amount. It all went fine while following the instructions, but at the end of the exercise you are encouraged to write some more code to make the program work with decimal inputs (instead of just whole numbers).
I essentially copied the same code used for the complete amounts with slight modifications (multiplying the initial amount by 100) so that it could still run and give the required results. However, the last value (bronze cents) keeps giving me numbers with decimals for some reason. I thought about using Math.Floor() but after a few trials I realized it isn’t always an excess. Can anyone provide some help? Are there any inherent limits to the Math.Floor() command that I should have been aware of? Did I just do a big dumb?
tl;dr: noob coder here, wondering why code not do what i want it to do
using System;
namespace MoneyMaker
{
class MainClass
{
public static void Main(string[] args)
{
// This code is meant to divide an (user given) amount of money into coins of different values.
// First we ask for an input.
Console.WriteLine("Welcome to Money Maker!.00");
Console.WriteLine("Please enter the amount you want to divide in Coins:");
string strAmount = Console.ReadLine();
Console.WriteLine($"${strAmount} Canopy is equal to:");
double wholeAmount = Convert.ToDouble(strAmount);
// These are the values of each coin.
// The cents are multiplied by 100 for the purposes of using then in the code.
// The bronze coins are listed, but unused, since their value is essentially 1.
double gold = 10;
double silver = 5;
//double bronze = 1;
double smolGold = .1 * 100;
double smolSilver = .05 * 100;
//double smolBronze = .01 * 100;
// These lines calculate the integral values (gold, silver and bronze coins).
double douAmount = Math.Floor(wholeAmount);
double goldCoins = Math.Floor(douAmount / gold);
double silAmount = douAmount % gold;
double silverCoins = Math.Floor(silAmount / silver);
double bronzeCoins = silAmount % silver;
// These lines calculate the decimal values (gold, silver and bronze cents).
// They start by multiplying the cents by 100, rendering the rest of the lines the same as in the integral values.
double smolAmount = 100 * (wholeAmount - douAmount);
double goldCents = Math.Floor(smolAmount / smolGold);
double littleSilver = smolAmount % smolGold;
double silverCents = Math.Floor(littleSilver / smolSilver);
//ERROR: There seems to be an issue with the bronze cents, returning a value with decimals.
double bronzeCents = littleSilver % smolSilver;
// Finally, the output string with the results:
Console.WriteLine($"\n Gold Coins: {goldCoins} \n Silver Coins: {silverCoins} \n Bronze Coins: {bronzeCoins} \n Gold Cents: {goldCents} \n Silver Cents: {silverCents} \n Bronze Cents: {bronzeCents}");
}
}
}
Never use doubles for currency. Use decimal.
Use double when representing a physical quantity, like length, mass, speed, and so on, where insignificant representation errors do not matter. Use decimal to represent money, where every penny or fraction of a penny matters.
The difference is: double represents numbers as a fraction where the denominator is a power of two, like "5/32nds". decimal represents numbers as a fraction where the denominator is a power of ten, like "3/100ths". The former will tend to accumulate representation errors for fractions like "3/100ths", but the latter will not.
If your tutorial is suggesting that you use double arithmetic for computations involving money, get a better tutorial.
All that said, I suspect you may misunderstand what the % operator is for if you are using it on non-integer quantities. It is primarily for use on integer quantities, so if you're using it on decimals or doubles, something strange is probably going on.

Is there any drawback if i convert a string to Double then compare the result to integer value (such as 2000, 1000)

I am not sure if i am doing things correctly inside my asp.net application. now i have 3 fields which represents currency fields, which allow maximum of 2 decimals:-
OneTimeCost
MonthlyCost
AnnualCost
and i am calculating this value:-
var totalcost = double.Parse(currentItem["OnTimeCost"].ToString()) + (double.Parse(currentItem["MonthlyCost"].ToString()) * 12) + double.Parse(currentItem["AnnualCost"].ToString());
then i am comparing the result as follow:-
if( totalcost >= 2000)
{
}
else if (totalcost > 1000)
{
}
//and so on
Now i am not sure if i am doing things correctly or not? now the 3 fields i have, represents currency values which can allow 2 decimal points. so not sure if converting my values to double and then compare the result to integer values (2000 and 1000) is a correct and safe operation?
second question. is it better to use decimal.parse instead of double.parse? since decimal is more appropriate for financial calculations ?
so not sure if converting my values to double and then compare the
result to integer values (2000 and 1000) is a correct and safe
operation?
Yes, it's safe.
second question. is it better to use decimal.parse instead of
double.parse? since decimal is more appropriate for financial
calculations ?
if you're dealing with money then use decimal as that's why it's there.

input string is not in a correct format

I want to calculate the percentage. But the compiler is giving an error that the input string is not in a correct format. Can some one elaborate what i am missing here?
private double per()
{
double a = Convert.ToDouble(tbEnglish.Text+tbUrdu.Text+tbPhysics.Text+tbChemistry.Text+tbMaths.Text);
double d = 500;
double lblResult = (a / d)*100;
return lblResult;
}
You're concatenating the strings and then trying to convert that one result into a double. So for results of 75.6, 92.1, 56.3 78.2 and 72.3 you'd end up trying to parse "75.692.156.378.272.3".
Parse each value and then sum them.
However, I would strongly recommend that you use decimal for this instead of double. You should also consider using TryParse instead of Parse so that you can handle user input errors gracefully. Here's the solution sticking with Parse:
public decimal AveragePercentage()
{
decimal sum = decimal.Parse(tbEnglish.Text) +
decimal.Parse(tbUrdu.Text) +
decimal.Parse(tbPhysics.Text) +
decimal.Parse(tbChemistry.Text) +
decimal.Parse(tbMaths.Text);
return sum / 5m;
}
Out of interest, in your original code why are you dividing by 500 and then multiplying by 100? Why not just divide by 5 (as mine does now that I've noticed what was going on)?
As a side note, it's very important to differentiate between compile-time errors and execution-time errors. It wasn't the compiler saying that the input string wasn't in the correct format - it was the Convert.ToDouble method, at execution time. In this case it was relatively obvious, but in other situations we could have been chasing our tails for a while trying to find a compile-time problem when it was actually failing at execution time.
I don't have Visual Studio available to me here on my Linux box, but I think you're better off with code like this.
private double per()
{
double a = Convert.ToDouble(tbEnglish.Text);
a += Convert.ToDouble(tbPhysics.Text);
a += Convert.ToDouble(tbChemistry.Text);
a += Convert.ToDouble(tbMaths.Text);
double d = 500;
double lblResult = (a / d)*100;
return lblResult;
}
In your example, you end up building a string that will look like: "75.692.156.372.3", which cannot be parsed into a double.
You need to convert all the TextBox.Text values into Decimals before using the + operator.

Categories

Resources