I'm new at programming and have been working on a program that converts a saunas temperature from Fahrenheit to Celsius and then tells the user if he/she should turn the heat up or down depending on the original input number. I've done the majority of my code but now I can't see why it does not loop when I write a number below 73 degrees or over 77 degrees. Can anyone see the problem that my eyes seem to not find?
using System;
namespace BastunKP
{
class Program
{
public static int FahrToCels(int fahr)
{
int tempCels = (fahr - 32) * 5 / 9;
return tempCels;
}
public static void Main(string[] args)
{
Console.WriteLine("Skriv in Fahrenheit: ");
int fahr = int.Parse(Console.ReadLine());
int tempCels = FahrToCels(fahr);
do
{
if (tempCels < 73)
{
Console.WriteLine("Temperaturen är för kallt, skruva upp lite!");
}
else if (tempCels > 77)
{
Console.WriteLine("Temperaturen är för varmt, skruva ner lite!");
}
else
{
Console.WriteLine("Temperaturen är nu lagom, hoppa in!");
return;
}
fahr = int.Parse(Console.ReadLine());
tempCels = FahrToCels(fahr);
}
while (tempCels < 73 && tempCels > 77);
}
}
}
I also have a question regarding my assignment where the teacher has said that for a higher grade I should look into where the formula for converting fahrenheit to celsius and make it a double but I dont know how to do this change at all.
Thanks in advance
tempCels < 73 && tempCels > 77 is never true!
Most probably you wanted || so to run when temp is less than 73 or greater than 77, but who knows.
Welcome to StackOverflow! Now, let's get down to your question:
First off, consider your do-while loop.
do {
if (tempCels < 73) {
// Temperature too high
Console.WriteLine("Temperaturen är för kallt, skruva upp lite!");
} else if (tempCels > 77) {
// Temperature too low
Console.WriteLine("Temperaturen är för varmt, skruva ner lite!");
} else {
// Temperature just right, hop in!
Console.WriteLine("Temperaturen är nu lagom, hoppa in!");
return;
}
fahr = int.Parse(Console.ReadLine());
tempCels = FahrToCels(fahr);
}
while (tempCels < 73 || tempCels > 77);
As you can see, I removed the unnecessary else condition. What happens right now, is that all possible conditions are checked (temp < 73, temp > 77, and 73 < temp < 77).
One mistake you had, also pointed out in other answers, is that you had && (AND) instead of || (OR). And of course, a value cannot be both under 73 and above 77 :)
Now, I'd like to also point out some styling / general things I think you should 'fix':
1) Your temp conversion method contains an unnecessary variable creation and assignment. You can make it work just as well without it, like this:
public static int fahrToCels(int fahr) {
// It returns just the same, without needing to create a new,
// temporary temperature variable!
return (fahr - 32) * 5 / 9;
}
2) This might be debatable, but general naming conventions say that function names are written with camelCase.
3) While this is not a problem in your scenario specifically, it might become one when you scale up an application (or work on a bigger one).
It's best to use slightly more descriptive namings (in a bigger project, just fahr might be confusing). Again, it's not any big deal of a problem, just something for you to consider for the future :)
P.S. I did not change variable names in my examples, just to keep it more readable/relateable to the code you showed.
EDIT:
As per request, here is how to keep the values as double type.
// Notice the return type and the property types are both double.
public static double fahrToCels(double fahr) {
return (fahr - 32) * 5 / 9;
}
This way, values don't have to be only integers, and produce weird results on division - they can be of type double too!
Now, remember you will need to pass a variable of type double to the function, otherwise you will get a type error.
Hint:
double fahr = int.Parse(Console.ReadLine());
Will let the user pass a non-integer value (like, say, 17.7), and it will be stored properly.
Hint #2:
If you really want to do on the fly conversion, you can achieve this like this (example values):
int ourInteger = 4;
double ourNewDoubleNumber = (double)ourInteger / 23;
You can read more about types and type casting here: Types and Type Casting
tempCels (or any number, for that matter) can't be less than 73 and more than 77 at the same time. You should use the logical || operator, not the logical && operator:
do {
// code
} while (tempCels < 73 || tempCels > 77);
// Here ---------------^
while will loop when the condition is true, but tempCels cannot be <73 and >77 at the same time! Fix that condition and it will work.
Related
I'm trying to create a method that takes a user's height, weight, and age, and returns their BMI and BMR.
I think I've done this fine.
However, the last thing I need to do is add some validation to make sure the user has put in some sensible numbers. The constraints being applied to the input are:
50 [cm] ≤ height ≤ 220 [cm]
10 [kg] ≤ weight ≤ 250 [kg]
18 [years] ≤ age ≤ 70 [years]
To do this, I've tried using if statements
if (getHight >= 220 && getHight <= 50)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
else if (getAge >= 70 && getAge <= 18)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
else if (getWeight >= 250 && getWeight <= 10)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
However, regardless of what I ender, nothing shows up in the console by way of validation errors. It just outputs my BMI and BMR.
What am I missing here?
Your mistake is that you are using AND instead of OR.
You cannot both be taller than 220cm and shorter than 50cm.
Use OR operators instead of AND:
if (getHight > 220 || getHight < 50)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
else if (getAge > 70 || getAge < 18)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
else if (getWeight > 250 || getWeight < 10)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
Also as #PaulF mentioned, you should not be using <= and >= since the valid range of values is inclusive. Since your logic is the inverse (invalid values), you should drop the = and just use < and >.
As already mentioned, you should be using || instead of && when doing the comparisons and you should be using < and > since the boundary values are acceptable. You might spend some time reading up on the Boolean logical operators - AND, OR, NOT, XOR so they all make sense, because they're very common and used in just about every program you'll write.
I just wanted to add another possible solution in case you're doing a lot of these types of comparisons, which is to write an extension method for them. This way you only have to write it once, which reduces the chance of error.
Below I have an extension method that tests if a number is between a minimum and maximum value (along with an option to specify if those boundary values as valid). Note that I assumed you're testing with an int type, but you can change the type easily by changing the this int value to this double value or this float value, or whatever numeric type you're using:
public static class Extensions
{
public static bool IsBetween(this int value, int min, int max,
bool inclusive = true)
{
return inclusive ?
min <= value && value <= max:
min < value && value < max;
}
}
Now if you include that class in your project, we can use this method to test if the value is not between our accepted values by using the ! not operator. Also note that I changed the else if to separate if statements. This way, if there's more than one error, they all get reported at the same time and the user can correct them all at once. I also changed the error message so the user actually knows what's wrong and how to fix it:
// In your program class, not in the Extensions class above
if (!getHeight.IsBetween(50, 220))
{
Console.WriteLine("ERROR: Height must be an integer between 50 and 220");
}
if (!getAge.IsBetween(18, 70))
{
Console.WriteLine("ERROR: Age must be an integer between 18 and 70");
}
if (!getWeight.IsBetween(10, 250))
{
Console.WriteLine("ERROR: Weight must be an integer between 10 and 250");
}
I'm trying to solve this problem here in C#:
https://open.kattis.com/submissions/8340306 (edit: Full question below)
So, in short: Give is a number of bricks. The aim is to figure out, how high I can build a 3D-pyramid with these blocks. The top-level has 1 brick, the 2nd level from the top 9 bricks, the 3rd 25 bricks and so on.
I thought I solved it and with the given example it is correct. It is also correct in all the calculations I did. Yet: From the 5 sample-runs, in it only excepted in 3.
Edit - the full question: When initiating a larger project, like
building a pyramid, it’s best to think twice. Your task today is to
write a program that computes how high a pyramid can be built given a
certain number of blocks of stone.
We assume that the pyramid to be built is compact, i.e. there are no
cavities inside. Furthermore, we assume it is built according to the
principle in Figure 1. Each layer is square, with a side length that
is two less than the one below it. The top layer always consist of a
single block.
It is fine if you have leftover blocks, as long as you build a
complete pyramid.
Input The first and only line of input contains an integer N
(1≤N≤100000000), the number of blocks you have available.
Output Output a single integer – the maximum height of a pyramid that
can be built with at least N blocks.
The result of my solution:
Here is my code - please be gentle, I am just learning :)
public static void Main()
{
int bloecke = int.Parse(Console.ReadLine());
int neueBloecke = 1; // Bloecke, die für die neue Ebene benötigt werden
int sumBloecke = 1; // Blöcke in Summe
int seitenLaenge = 1; // Seitenlänge der Ebene
int ebene = 1; // Auf welcher Ebene wir uns aktuell befinden
while (sumBloecke < bloecke)
{
// Wenn wir weniger als 10 Blöcke haben, brauchen wir gar nicht anzufangen > wir haben 1 Ebene
if (bloecke < 10)
{
ebene = 1;
break;
}
// Andernfalls legen wir los
seitenLaenge += 2;
neueBloecke = seitenLaenge * seitenLaenge;
sumBloecke += neueBloecke;
if (sumBloecke>=bloecke)
{
break;
} else
{
ebene++;
}
}
Console.Write(ebene);
}
It looks like you've been just messing with this trying to get it to work. You've complicated it with code that has no real purpose, and now it's confusing.
Your loop has 2 exit conditions when only one is necessary, you have ebene = 1 in there for no reason, etc.
You are taking the wrong approach. If you just mess with your code until it works for whatever tests you're applying, then you'll never really be confident that it works for stuff you didn't test.
You need to prove to yourself that it is correct. Try something like this:
Ensure that, at the top of the loop, the total block count, base area, and edge length are valid for a pyramid size ebene+1. (This is called a loop invariant)
Exit the loop at the top if the total number of blocks required by that pyramid is more than you have
Otherwise, increment ebene and calculate the variables for the next size, and loop.
If you implement this simple procedure, then you will be confident that the result is correct.
This works for me:
public static void Main()
{
int availableBlocks = int.Parse(Console.ReadLine());
int newBlocks = 0; // blocks for the new level
int sumBlocks = 0; // sum of used blocks
int edgeLength = 0; // blocks on one side of the level
int level = 0; // which level are we
while (true)
{
// e.g. availableBlocks = 15
//
// edge | new | sum | ok? | level
// 0 0 0 yes 0
// 1 1 1 yes 1
// 3 9 10 yes 2
// 4 16 26 no -
// edgeLength increases by 2, except for the first top-level
if (edgeLength==0)
{
edgeLength++;
} else
{
edgeLength += 2;
}
newBlocks = edgeLength * edgeLength;
sumBlocks += newBlocks;
// Check, if we still have enought blocks
if (sumBlocks <= availableBlocks)
{
level++;
} else
{
Console.WriteLine(level);
break;
}
}
}```
I can think of some very convoluted methods with loops and nested loops to solve this problem but I'm trying to be more professional than that.
My scenario is that I need to enter a section of code every ten percent but it isn't quite working as expected. It is entering the code about every percent which is due to my code but I lack the knowledge to know how to change it.
int currentPercent = Math.Truncate((current * 100M) / total);
//avoid divide by zero error
if (currentPercent > 0)
{
if (IsDivisible(100, currentPercent))
{
....my code that works fine other than coming in too many times
}
}
Helper referenced above where the trouble is:
private bool IsDivisible(int x, int y)
{
return (x % y) == 0;
}
So obviously it works as it should. Mod eliminates currentPercent of 3 but 1 & 2 pass when really I don't want a true value until currentPercent = 10 and then not again till 20...etc.
Thank you and my apologies for the elementary question
Mod will only catch exact occurrences of your interval. Try keeping track of your next milestone, you'll be less likely to miss them.
const int cycles = 100;
const int interval = 10;
int nextPercent = interval;
for (int index = 0; index <= cycles; index++)
{
int currentPercent = (index * 100) / cycles;
if (currentPercent >= nextPercent)
{
nextPercent = currentPercent - (currentPercent % interval) + interval;
}
}
I might misunderstand you, but it seems like you're trying to do something extremely simple more complex than it needs to be. What about this?
for (int i = 1; i <= 100; i++)
{
if (i % 10 == 0)
{
// Here, you can do what you want - this will happen
// every ten iterations ("percent")
}
}
Or, if your entire code enters from somewhere else (so no loop in this scope), the important part is the i % 10 == 0.
if (IsDivisible(100, currentPercent))
{
....my code that works fine other than coming in too many times
}
try changing that 100 to a 10. And I think your x and y are also backwards.
You can try a few sample operations using google calculator.
(20 mod 10) = 0
Not sure if I fully understand, but I think this is what you want? You also reversed the order of modulo in your code (100 mod percent, rather than the other way around):
int currentPercent = current * 100 / total;
if (currentPercent % 10 == 0)
{
// your code here, every 10%, starting at 0%
}
Note that code this way only works properly if you are guaranteed to hit every percentage-mark. If you could, say, skip from 19% to 21% then you'll need to keep track of which percentage the previous time was to see if you went over a 10% mark.
try this:
for (int percent = 1; percent <= 100; percent++)
{
if (percent % 10 == 0)
{
//code goes here
}
}
Depending on how you increment your % value, this may or may not work % 10 == 0. For example jumping from 89 to 91 % would effectively skip the code execution. You should store last executed value, 80 in this case. Then check if interval is >= 10, so 90 would work, as well as 91.
I have this code that finds numbers in a given range that contain only 3 and 5 and are polynoms(symetrical, 3553 for example). The problem is that the numbers are between 1 and 10^18, so there are cases in which I have to work with big numbers, and using BigInteger makes the program way too slow, so is there a way to fix this ? Here's my code:
namespace Lucky_numbers
{
class Program
{
static void Main(string[] args)
{
string startString = Console.ReadLine();
string finishString = Console.ReadLine();
BigInteger start = BigInteger.Parse(startString);
BigInteger finish = BigInteger.Parse(finishString);
int numbersFound = 0;
for (BigInteger i = start; i <= finish; i++)
{
if (Lucky(i.ToString()))
{
if (Polyndrome(i.ToString()))
{
numbersFound++;
}
}
}
}
static bool Lucky(string number)
{
if (number.Contains("1") || number.Contains("2") || number.Contains("4") || number.Contains("6") || number.Contains("7") || number.Contains("8") || number.Contains("9") || number.Contains("0"))
{
return false;
}
else
{
return true;
}
}
static bool Polyndrome(string number)
{
bool symetrical = true;
int middle = number.Length / 2;
int rightIndex = number.Length - 1;
for (int leftIndex = 0; leftIndex <= middle; leftIndex++)
{
if (number[leftIndex] != number[rightIndex])
{
symetrical = false;
break;
}
rightIndex--;
}
return symetrical;
}
}
}
Edit: Turns out it's not BigInteger, it's my shitty implementation.
You could use ulong:
Size: Unsigned 64-bit integer
Range: 0 to 18,446,744,073,709,551,615
But I would guess that BigInteger is not a problem here. I think you should create algorithm for palindrome creation instead of brute-force increment+check solution.
Bonus
Here is a palyndrome generator I wrote in 5 minutes. I think it will be much faster than your approach. Could you test it and tell how much faster it is? I'm curious about that.
public class PalyndromeGenerator
{
private List<string> _results;
private bool _isGenerated;
private int _length;
private char[] _characters;
private int _middle;
private char[] _currentItem;
public PalyndromeGenerator(int length, params char[] characters)
{
if (length <= 0)
throw new ArgumentException("length");
if (characters == null)
throw new ArgumentNullException("characters");
if (characters.Length == 0)
throw new ArgumentException("characters");
_length = length;
_characters = characters;
}
public List<string> Results
{
get
{
if (!_isGenerated)
throw new InvalidOperationException();
return _results.ToList();
}
}
public void Generate()
{
_middle = (int)Math.Ceiling(_length / 2.0) - 1;
_results = new List<string>((int)Math.Pow(_characters.Length, _middle + 1));
_currentItem = new char[_length];
GeneratePosition(0);
_isGenerated = true;
}
private void GeneratePosition(int position)
{
if(position == _middle)
{
for (int i = 0; i < _characters.Length; i++)
{
_currentItem[position] = _characters[i];
_currentItem[_length - position - 1] = _characters[i];
_results.Add(new string(_currentItem));
}
}
else
{
for(int i = 0; i < _characters.Length; i++)
{
_currentItem[position] = _characters[i];
_currentItem[_length - position - 1] = _characters[i];
GeneratePosition(position + 1);
}
}
}
}
Usage:
var generator = new PalyndromeGenerator(6, '3', '5');
generator.Generate();
var items = generator.Results.Select(x => ulong.Parse(x)).ToList();
Strange riddle, but can be simplified if I understand the requirement.
I would first map these numbers to binary as there is only two possible
"lucky" digits, then generate the numbers by counting in binary until
I have completed nine bits. Reflect it for the full number, then
convert 0 to 3 and 1 to 5.
Example 1101
Reflect it = 10111101 --> 53555535
Do this from 0 all the way to 111111111
Declare start and finish to be static inside the class.
Change the method Lucky to:
static bool Lucky(string number)
{
return !(number.Contains("1") || number.Contains("2") || number.Contains("4") || number.Contains("6") || number.Contains("7") || number.Contains("8") || number.Contains("9") || number.Contains("0"));
}
Also, you can use Parallel library to parallelize the computation.
Instead of using a regular for loop, you could use a Parallel.For.
Look at the problem a different way - how many strings of up to 9 characters (using only '3' and '5') can you make? for each string you have 2 palindromes (one repeating the last character, one not) that you can make.
e.g.
3 -> 33
5 ->, 55
33 -> 333, 3333
35 -> 353, 3553
53 -> 535, 5335
...
The only suggestion I have is to use a 3rd party library like intx, or some unmanaged code. The intx author reports that it can work faster than BigInteger in some situations: "System.Numerics.BigInteger class was introduced in .NET 4.0 so I was interested in performance of this solution. I did some tests (grab test code from GitHub) and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example)."
Since the number has to be symmetrical, you only need to check the first half of the number. You don't need to check 18 digits, you only have to check to 9 digits and then swap the order of the characters and add them to the back as a string.
One thing I can think of is if you are only going to count integers that are containing 3 or 5 you don't need to traverse the entire list of numbers between your beginning & ending range.
Instead, look at your character set as either '3' or '5'. Then you can simply go through the allowed permutations of half of the number itself, leaving the other half to be completed to successfully create a polyndrome.
There are some rules to this method which would help, such as :
if the starting number's left-most digit was greater than 5 there is no need to attempt for that specific number of digits.
if both numbers fall on the same amount of digits but left-most digits do not traverse / include 5 or 3, no need to process.
Developing some set of rules such as this may help other than attempting to check every possible permutation.
So, for example, your Lucky function would become something more along the lines of :
static bool Lucky(string number)
{
if((number[0] != '3') && (number[0] != '5'))
{
return false;
} //and you could continue this for the entire string
...
}
I've got a program written in c# where there are a lot of comparisons between ints and strings.
So for performance reasons, I would just like to know which is more efficient?
If we have:
int a = 5;
string b = "5";
if(a == int.Parse(b)) { }
OR
if(a.ToString() == b) { }
I actually profiled this using a few examples and timed loops. It turns out Parse wins for small integers, and ToString wins for large ones. This difference is so small it should not be a concern however, as others have mentioned, you're likely to make a better choice by thinking about the cases where the string does not represent an integer at all.
Edit: For those interested, here's the source, quick 'n' dirty:
using System;
using System.Diagnostics;
namespace CompareTest
{
static class Program
{
static void Main(string[] args)
{
int iterations = 10000000;
int a = 5;
string b = "5";
Stopwatch toStringStopwatch = new Stopwatch();
toStringStopwatch.Start();
for (int i = 0; i < iterations; i++) {
bool dummyState = a.ToString() == b;
}
toStringStopwatch.Stop();
Stopwatch parseStopwatch = new Stopwatch();
parseStopwatch.Start();
for (int i = 0; i < iterations; i++) {
bool dummyState = a == int.Parse(b);
}
parseStopwatch.Stop();
Console.WriteLine("ToString(): {0}", toStringStopwatch.Elapsed);
Console.WriteLine("Parse(): {0}", parseStopwatch.Elapsed);
Console.ReadLine();
}
}
}
A few comments mentioned running a profiling tool to prove which has better performance.
This is a ok, but the simplest way to check performance of specific statements is to put them in a loop and use the Stopwatch class.
Jeff Atwood asked about making this sort of timing even simpler in this question. In that question and answer you will also find some good code examples and background details.
Heres a very simple working example:
System.Diagnostics.Stopwatch sw=new System.Diagnostics.Stopwatch();
int a = 5;
string b = "5";
sw.Start();
for (int i=0;i<1000000;i++)
{
if(a == int.Parse(b))
{
}
}
sw.Stop();
Console.WriteLine("a == int.Parse(b) milliseconds: " + sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for (int i=0;i<1000000;i++)
{
if(a.ToString() == b)
{
}
}
sw.Stop();
Console.WriteLine("a.ToString() == b milliseconds: " + sw.ElapsedMilliseconds);
On my computer it outputs:
a == int.Parse(b) milliseconds: 521
a.ToString() == b milliseconds: 697
So in this simple scenario int.Parse() is slightly faster, but not enough to really worry about.
Your choice is between the following
Code Listing A
int a = 5;
string b = "5";
//Assuming these two values are input received by the application at runtime
int bInt;
if (int.TryParse(b, NumberStyles.None, CultureInfo.InvariantCulture, out bInt)
&& a.Equals(bInt))
{
}
and
Code Listing B
int a = 5;
string b = "5";
//Assuming these two values are input received by the application at runtime
if (string.Compare(b, a.ToString(), StringComparison.Ordinal) != -1)
{
}
I have tested this with stopwatch (as given in the selected answer) and found Code Listing A to be much faster.
But Code Listing B is more readable!
Code Listing A beats if(a == int.Parse(b))
Internally, ToString and Parse do the following:
Parse
value = 0
for each char in string
value = value * 10 + valueof(char) // i.e. '0' -> 0, '7' -> 7
ToString
string=""
while value > 0
string.insert_at_front value % 10 // so that 0 -> '0' and 6 -> '6'
value /= 10
// on IA32, the % and / can be done at the same time but requires
// a 64bit source for 32bit values
The ToString should be slower than Parse since division is generally slower than multiplication. However, the above doesn't take into account any overhead the Parse and ToString functions might perform during the conversion (i.e. generating exceptions, allocating memory), which means it's not as clear-cut which will more optimal.
From the other answers it seems the difference is marginal anyway so just use whatever make more sense to you.
You've already gotten a few good responses, but let me add a couple of small points.
One of the well-known risks with micro-benchmarks is that a small number of repetitions can end up measuring noise (e.g. the timings can be skewed by an incoming email or IM), but a large number of repetitions can end up measuring the performance of your garbage collector (e.g. if your code is constantly creating and discarding strings).
When I find myself in an awkward spot in code, it's sometimes helpful to ask myself, "What assumptions or choices put me in this situation? What could I do differently?" For example (just guessing), when you wrote "...where there are a lot of comparisons between int's*[sic]* and strings", does that imply that you may be using the same values repeatedly (e.g., comparing new values against previous values)?
If so, could you convert each string to int, and cache the converted value for subsequent re-use, instead of having to convert it again later?
My case that brought me here was to check if "5" == 5 in a switch-case and because I will always receive numbers between 0 and 9 I found out that the fastest way is:
(int)b[0] == 53
So I'm taking the fist character of string "5" (b[0]) and cast it to it ACSII value which is 53 and after that compare. Here are the results:
a == int.Parse(b) milliseconds: 194
a.ToString() == b milliseconds: 142
a == (int)(b[0]) milliseconds: 8
Even though it is very unusual case the difference on a massive array is obvious;
EDIT: As Dirk Horsten requested.
Wrong as I am. I mentioned in my post that I use that on a switch case so I will use in all of my cases the ASCII values so it will look like that:
switch((int)b[0])
{
case 48: Console.WriteLine("0");
break;
case 49: Console.WriteLine("1");
break;
case 50: Console.WriteLine("2");
break;
case 51: Console.WriteLine("3");
break;
case 52: Console.WriteLine("4");
break;
case 53: Console.WriteLine("5");
break;
case 54: Console.WriteLine("6");
break;
case 55: Console.WriteLine("7");
break;
case 56: Console.WriteLine("8");
break;
case 57: Console.WriteLine("9");
break;
}
And for a good order sake here are the results as you asked me:
a == int.Parse(b) milliseconds: 184
a.ToString() == b milliseconds: 135
a + 48 ==(int)b[0] milliseconds: 8
As you could see there is no such a big difference just adding one addition.
The larger the number I'll go for the first method.
a. if b is not a number, it will failed before trying to compare.
b. string are compared by the length and number at once.
I doubt either call will really significantly impact your application unless you really are creating something on a grand scale.
Both techniques are creating a new string, however int.ToString() has to perform a lot less tasks than int.Parse().
int.ToString() is performed internally in the CLR (comnumber). int.Parse() is done inside the BCL source using Number.ParseInt32() -> Number.StringToNumber() -> Number.ParseNumber().
ParseNumber performs a huge number of checks so from a finger in the air guess you would imagine int.ToString() is faster. As others have mentioned, a proper performance test with the StopWatch class will be a better way to find out. You will want to try this out with the number format you are expecting: decimal, hex.
You can compare the C++ that the CLR is using for ToString() here: Look for
NumberToString (that's used for ToString() and other formats) which is used in FCIMPL3, called by int.ToString() as an extern call.
Int32ToDecStr is used for the "D" formatter.
The C#
var x = 5.ToString("D");
var y = 5.ToString();
I could be wrong about FCIMPL3, please correct me if I am.
Also i read somwhere (MSDN) using the following is faster than == for string comparisons
StringA.ToUpperInvariant() == StringB.ToUpperInvariant()
Parsing a String to an Int32 requires more performance and is more sensitive to errors. You will have to make sure the Int32.Parse will be successful in the first place.
Also you can use an alternative for '=='. Use .Equals(), this easier to read and understand.
if(b.Equals(a))
{
}
There are many ways of representing the same number as a string...