I need to get a number from the user and display the sum of that number's digits. For example, the sum of the digits in the number 12329 is 17.
Here's what I tried to do and it is giving me the ASCII code instead:
Console.WriteLine("please enter a number: ");
string num = Console.ReadLine();
int len = num.Length;
int[] nums = new int[len];
int sum = 0;
int count = 0;
while (count < len)
{
nums[count] = Convert.ToInt32(num[count]);
count++;
}
for (int i = 0; i < len; i++)
sum += nums[i];
Console.WriteLine(sum);
This is a very common mistake. char is really just a number - the encoding value of the character represented by the char. When you do Convert.ToInt32 on it, it sees the char as a number and says "alright let's just convert this number to 32 bits and return!" instead of trying to parse the character.
"Wait, where have I used a char in my code?" you might ask. Well, here:
Convert.ToInt32(num[count]) // 'num[count]' evaluates to 'char'
To fix this, you need to convert the char to a string:
nums[count] = Convert.ToInt32(num[count].ToString());
^^^^^^^^^^^^^^^^^^^^^
Now you are calling a different overload of the ToInt32 method, which actually tries to parse the string.
When you access your string with a index (in your case num[count]) you get a char type and because of that you are getting ASCII values. You can convert char to string with .ToString() in your case nums[count] = Convert.ToInt32(num[count].ToString());.I posted here another approach to your problem:
string number = Console.ReadLine();
int sum = 0;
foreach (var item in number)
{
sum += Convert.ToInt32(item.ToString());
}
Console.WriteLine(sum);
As you noticed the Convert.ToInt32(num[count]) will only return the Unicode code of the char you want to convert, because when you use the [] operator on a string, you will get readonly access to [the] individual characters of a string [1].
And so you are using Convert.ToInt32(Char), which
Converts the value of the specified Unicode character to the equivalent 32-bit signed integer.
One way to cast the numeric value from a char to a digit, is using Char.GetNumericValue(), which
Converts a specified numeric Unicode character to a double-precision floating-point number.
By using System.Linq; you can cut your code to just a few lines of code.
Console.WriteLine("please enter a number: ");
string num = Console.ReadLine(); // "12329"
int sum = (int)num.Select(n => Char.GetNumericValue(n)).Sum();
Console.WriteLine(sum); // 17
What does this line of code?
The num.Select(n => Char.GetNumericValue(n)) will iterate over each char in your string, like your while and converts each value to a double value and return an IEnumerable<double>. The Sum() itself will iterate over each value of the IEnumerable<double> and calculate the sum as a double. And since you want an integer as result the (int) casts the double into an integer value.
Side-Note:
You could check your input, if it is really an integer.
For example:
int intValue;
if(Int32.TryParse(num, out intValue))
{
// run the linq
}
else
{
// re-prompt, exit, ...
}
If you are using Char.GetNumericValue() on an letter it will return -1 so for example the sum of string num = "123a29"; will be 16.
Related
I'm a C# newbie learning how to work with arrays. I wrote a small console app that converts binary numbers to their decimal equivalents; however, the sytax I've used seems to be causing the app to - at some point - use the unicode designation of integers instead of the true value of the integer itself, so 1 becomes 49, and 0 becomes 48.
How can I write the app differently to avoid this? Thanks
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sandbox
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Key in binary number and press Enter to calculate decimal equivalent");
string inputString = Console.ReadLine();
////This is supposed to change the user input into character array - possible issue here
char[] digitalState = inputString.ToArray();
int exponent = 0;
int numberBase = 2;
int digitIndex = inputString.Length - 1;
int decimalValue = 0;
int intermediateValue = 0;
//Calculates the decimal value of each binary digit by raising two to the power of the position of the digit. The result is then multiplied by the binary digit (i.e. 1 or 0, the "digitalState") to determine whether the result should be accumulated into the final result for the binary number as a whole ("decimalValue").
while (digitIndex > 0 || digitIndex == 0)
{
intermediateValue = (int)Math.Pow(numberBase, exponent) * digitalState[digitIndex]; //The calculation here gives the wrong result, possibly because of the unicode designation vs. true value issue
decimalValue = decimalValue + intermediateValue;
digitIndex--;
exponent++;
}
Console.WriteLine("The decimal equivalent of {0} is {1}", inputString, intermediateValue);
Console.ReadLine();
}
}
}
Simply use the following code
for (int i = 0; i < digitalState.Length; i++)
{
digitalState[i] = (char)(digitalState[i] - 48);
}
After
char[] digitalState = inputString.ToArray();
Note that the value of a character, for example '1' is different from what it represents. As you already noticed '1' is equal to ASCII code 49. When you subtract 48 from its value (49) it becomes 1.
there were two errors: you missed the "-48" and wrote the intermediate instead of the result (last line). Not sure how to unline some parts in the codeblock ;)
intermediateValue = (int)Math.Pow(numberBase, exponent) * (digitalState[digitIndex]-48;
//The calculation here gives the wrong result,
//possibly because of the unicode designation vs. true value issue
decimalValue += intermediateValue;
(.....)
Console.WriteLine("The decimal equivalent of {0} is {1}", inputString, decimalValue);
#CharlesMager says it all. However, I assume this is a homework assignment. So as you said multiplying by the ASCII value is wrong. So just subtract '0' (decimal value 48) from ASCII value.
intermediateValue = (int)Math.Pow(numberBase, exponent)
* ((int)digitalState[digitIndex] - 48);
You code is ugly, there is no need to go backwards from the string. Also using Math.Power is inefficient, shifting (<<) is equivalent for binary powers.
long v = 0;
foreach (var c in inputString)
{
v = (v << 1) + ((int)c - 48);
}
Console.WriteLine("The decimal equivalent of {0} is {1}", inputString, v);
Console.ReadLine();
static void Main()
{
Console.Write("Please input a number: ");
Console.WriteLine("\n The number you selected was {0} \n", method());
}
static int method()
{
int var = int.Parse(Console.ReadLine());
return var;
}
The above code throws a format exception. I tried storing the input in a string variable and then parsing, but it had the same problem. I also tried using the Convert class and still had the same problem. I would appreciate if someone could show me where I am wrong.
I am trying to convert 23.4, for example. (It works for Natural numbers but why not 4345.5, for example)
23.4 is not an integer, so you cannot use int.Parse (or int.TryParse). Instead you have to parse it to a decimal number like decimal or double. You can use the TryParse methods like Double.TryParse to prevent an exception if it's not a valid number:
string input = Console.ReadLine();
double number;
if(double.TryParse(input.Trim(), out number))
{
// valid number
Console.WriteLine("\n The number you selected was {0} \n", number);
}
else
{
Console.WriteLine("Please enter a real number.");
}
Update from your comments i can see that you want to display an integer.
You can use (int)number to get an integer where the decimal part is simply truncated. If you want that it gets rounded use Math.Round first.
int integer = (int) number; // decimal part is truncated
integer = (int) Math.Round(number, 2, MidpointRounding.AwayFromZero); // rounded to two digits
If you just want to display a string without the decimal part you can also use format strings.
string numberString = number.ToString("N0");
You should be using double or float for rational numbers:
float num = float.Parse(Console.ReadLine())
You can return the integer part of your input string (3.6 becomes 3, for example) like this:
static int method()
{
float var = float.Parse(Console.ReadLine());
return (int)Math.Floor(var);
}
Integer32.Parse is for parsing 32 bit integers. It cannot parse numbers that cannot be represented as a 32 bit integer, such as 23.4, and it will throw an exception when it cannot parse the data. Use a different numeric representation if you wish to represent non-integer numbers.
I need to travers the string ,which should be the string of digits and make some arithmetic operations on these digits
for (int i = data.Length - 1; i >= 0; --i)
{
uint curDigit;
//Convert to uint the current rightmost digit, if convert fails return false (the valid data should be numeric)
try
{
curDigit = Convert.ToUInt32(data[i]);
//arithmetic ops...
}
catch
{
return false;
}
I test it with the following input data string.
"4000080706200002"
For i = 15,corresponding to the rightmost digit 2,I get 50 as an output from
curDigit = Convert.ToUInt32(data[i]);
Can someone please explain me what is wrong?and how to correct the issue
50 is the ascii code for '2'. what you need is '2' - '0' (50-48)
byte[] digits = "4000080706200002".Select(x => (byte)(x - '0')).ToArray();
http://www.asciitable.com/
What you are getting back is the ascii value of character 2, You can use call ToString on the character item and then call Convert.ToUnit32, Consider the example:
char x = '2';
uint curDigit = Convert.ToUInt32(x.ToString());
this will give you back 2 as curDigit
For your code you can just use:
curDigit = Convert.ToUInt32(data[i].ToString());
Another option is to use char.GetNumericValue like:
uint curDigit = (UInt32) char.GetNumericValue(data[i]);
char.GetNumericValue returns double and you can cast the result back to UInt32
The problem is that data[i] returns a char variable, that essentialy is an integer holding the ASCII code of the character. So '2' corresponds to 50.
There are 2 things you can do to overcome this behaviour:
Better curDigit = Convert.ToUInt32(data[i] - '0'); //Substract the ASCII representation of '0' from the char
curDigit = Convert.ToUInt32(data.Substring(i,1)); //Use substring to return a string instead of char. Note, that this method is less efficient, as Convert from string essentially splits the string into chars, and substract '0' from each and every one of them.
Your getting the ASCII (or Unicode) values for those characters. The problem is that the code points for the characters '0' … '9' are not 0 … 9, but 48 … 57. To fix this, you need to adjust by that offset. For example:
curDigit = Convert.ToUInt32(data[i] - '0');
Or
curDigit = Convert.ToUInt32(data[i] - 48);
Rather than messing around with ASCII calculations you could use UInt32.TryParse as an alternative solution. However, this method requires a string input not char, so you would have to modify your approach a little:
string input = "4000080706200002";
string[] digits = input.Select(x => x.ToString()).ToArray();
foreach(string digit in digits)
{
uint curDigit = 0;
if(UInt32.TryParse(digit, out curDigit))
{
//arithmetic ops...
}
//else failed to parse
}
I have this program that gets all the numbers from a double variable, removes decimal marks and minuses and adds every digit separately. Here is is:
static void Main(string[] args)
{
double input = double.Parse(Console.ReadLine());
char[] chrArr = input.ToString().ToCharArray();
input = 0;
foreach (var ch in chrArr)
{
string somestring = Convert.ToString(ch);
int someint = 0;
bool z = int.TryParse(somestring, out someint);
if (z == true)
{
input += (ch - '0');
}
}
The problem is for example when I enter "9999999999999999999999999999999...." and so on, it gets represented as 1.0E+254 and what so my program just adds 1+0+2+5+4 and finishes. Is there efficient way to make this work properly ? I tried using string instad of double, but it works too slow..
You can't store "9999999999999999999999999999999..." as a double - a double only has 15 or 16 digits of precision. The compiler is giving you the closest double it can represent to what you're asking, which is 1E254.
I'd look into why using string was slow, or use BigInteger
As other answers indicate, what's stored will not be exactly the digits entered, but will be the closest double value that can be represented.
If you want to inspect all of it's digits though, use F0 as the format string.
char[] chrArr = input.ToString("F0").ToCharArray();
You can store a larger number in a Decimal as it is a 128 bit number compared to the 64 bit of a Double.
But there is obviously still a limit.
I have an integer variable with max value of 9999.
I can convert to fixed length string (4-characters):
value.ToString("0000");
and I can convert it to hex:
value.ToString("X");
I want to convert it to a hex string of four characters (padded with 0 at the left if the value is converted to less than four digits hex value). I tried the following which didn't work.
value.ToString("0000:X");
OK, I can check the length of hex string and pad left with zeros.
But is there any straightforward way?
Use a number after the X format specifier to specify the left padding : value.ToString("X4")
String.Format( "{0:X2}", intValue)
Here is another method,
You can define a function and pass it 2 values, one the actual number and the second is the max length to fix.
i.e.
public string FixZero(string str, int maxlength)
{
string zero = "000000000000000000000000000000000000000";
int length = str.Length;
int diff = maxlength- length;
string z = zero.Substring(1, diff);
z = z + str;
return z;
}
you need integers in the format 0012, FixZero("12", 4)
or for 0001234, FixZero("1234", 7)