C# Program that converts decimal number to binary - c#

So, I have to make a program that converts a decimal number to binary and prints it, but without using Convert. I got to a point where I can print out the number, but it's in reverse(for example: 12 comes out as 0011 instead of 1100), anyone has an idea how to fix that ? Here's my code:
Console.Write("Number = ");
int n = int.Parse(Console.ReadLine());
string counter = " ";
do
{
if (n % 2 == 0)
{
counter = "0";
}
else if (n % 2 != 0)
{
counter = "1";
}
Console.Write(counter);
n = n / 2;
}
while (n >= 1);

simple solution would be to add them at the beginning:
Console.Write("Number = ");
int n = int.Parse(Console.ReadLine());
string counter = "";
while (n >= 1)
{
counter = (n % 2) + counter;
n = n / 2;
}
Console.Write(counter);
You actually don't even need the if statement

Instead of write them inmediately you may insert them in a StringBuidler
var sb = new StringBuilder();
....
sb.Insert(0, counter);
And then use that StringBuilder
var result = sb.ToString();

You can reverse the String when you finish calculating it

You are generated the digits in the reverse order because you are starting with the least significiant digits when you use % 2 to determine the bit value. What you are doing is not bad though, as it is convenient way to determine the bits. All you have to do is reverse the output by collecting it until you have generated all of the bits then outputing everything in reverse order. ( I did not try to compile and run, may have a typo)
One easy solution is
System.Text.StringBuilder reversi = new System.Text.StringBuilder();
Then in your code replace
Console.Write(counter);
with
reversi.Append(counter);
Finally add the end of your loop, add code like this
string s = reversi.ToString();
for (int ii = s.Length-1; ii >= 0; --ii)
{
Console.Write(s[ii]);
}
There are better ways to do this, but this is easy to understand why it fixes your code -- It looks like you are trying to learn C#.

If I'm not mistaken
int value = 8;
string binary = Convert.ToString(value, 2);

Related

appending string horizontally in c#

I am new to C# and trying a demo program in this program my intended output is:
Id 1 2 3 4 5 6 7 8 9
Roll # 1 2 3 4 5 6 7 8 9
and this is what I have tried :
static void Main(string[] args)
{
StringBuilder sb = new StringBuilder();
sb.Append("Id ");
for (int i = 0; i < 10; i++)
{
sb.Append(i+" ");
}
sb.AppendLine();
sb.Append("Roll# ");
for (int i = 0; i < 10; i++)
{
sb.Append(i + " ");
}
Console.WriteLine(sb);
}
though it gives me desired output but here I have to iterate through for loop twice. Is there any way by which only iterating once I can get the same output, using some string formatting of C#?
This can be done without explicit looping, using Enumerable.Range to "generate a sequence of integral numbers within a specified range", along with string.Join() to concatenate the previously created range with the string " " :
// using System.Linq;
string range = string.Join(" ", Enumerable.Range(1, 10)); // "1 2 3 4 5 6 7 8 9 10"
sb.AppendLine($"Id {range}");
sb.AppendLine($"Roll# {range}");
If you really want to use a for loop to build your sequence, you can build your own Range method such as :
public static IEnumerable<int> Range(int min, int max)
{
if (min > max)
{
throw new ArgumentException("The min value can't be greater than the max");
}
for (int i = min; i <= max; i++)
{
yield return i;
}
}
And then Join like previously :
var range = string.Join(" ", Range(1, 10));
sb.AppendLine($"Id {range}");
sb.AppendLine($"Roll# {range}");
Or build an array/List/whatever collection and then use string.Join() :
var arr = new int [10];
for (int i = 1; i <= 10; i++)
{
arr[i - 1] = i;
}
string range = string.Join(" ", arr);
sb.AppendLine($"Id {range}");
sb.AppendLine($"Roll# {range}");
Or directly build a string in the loop :
var sbRange = new StringBuilder();
for (int i = 1; i <= 10; i++)
{
sbRange.Append($"{i} ");
}
// You can use a string and trim it (there is a space in excess at the end)
string range = sbRange.ToString().Trim();
sb.AppendLine($"Id {range}");
sb.AppendLine($"Roll# {range}");
Instead of 1, use 2 StringBuilder instances:
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
sb1.Append("Id ");
sb2.Append("Roll# ");
for (int i = 0; i < 10; i++)
{
sb1.Append(i + " ");
sb2.Append(i + " ");
}
Console.WriteLine(sb1);
Console.WriteLine(sb2);
This will always require at least 3 loops:
One for the creation for the array.
One for each WriteLine.
At best you can have somebody elses code do the looping for you.
Unless you are interested in pulling stunts like manually inserting the Newline into a really long string, there is no way to save even a single loop. But such a thing is just unreliable and should not be atempted.
It honestly sounds a lot like a Speed Question, and for those we have the speed rant. You should read it either way, but can skip part 1.
The only improovement I can think of is building those strings with a stringbuilder. String concatenation in loops can be a bit troublesome. But on this scale it works either way.

Calculate 2^(n) where 0<n<10000

So, this is my problem to solve:
I want to calculate 2^(n) where 0 < n< 10000
I am representing each element of array as a space where 4digit number should be "living" and if extra digit appears, I am replacing it to the next element of this array.
The principle I am using looks like this:
The code I am using is the following:
static string NotEfficient(int power)
{
if (power < 0)
throw new Exception("Power shouldn't be negative");
if (power == 0)
return "1";
if (power == 1)
return "2";
int[] A = new int[3750];
int current4Digit = 0;
//at first 2 is written in first element of array
A[current4Digit] = 2;
int currentPower = 1;
while (currentPower < power)
{
//multiply every 4digit by 2
for (int i = 0; i <= current4Digit; i++)
{
A[i] *= 2;
}
currentPower++;
//checking every 4digit if it
//contains 5 digit and if yes remove and
//put it in next 4digit
for (int i = 0; i <= current4Digit; i++)
{
if (A[i] / 10000 > 0)
{
int more = A[i] / 10000;
A[i] = A[i] % 10000;
A[i + 1] += more;
//if new digit should be opened
if (i + 1 > current4Digit)
{
current4Digit++;
}
}
}
}
//getting data from array to generate answer
string answer = "";
for (int i = current4Digit; i >= 0; i--)
{
answer += A[i].ToString() + ",";
}
return answer;
}
The problem I have is that it doesn't display correctly the number, which contains 0 in reality. for example 2 ^ (50) = 1 125 899 906 842 624 and with my algorithm I get 1 125 899 96 842 624 (0 is missing). This isn't only for 50...
This happens when I have the following situation for example:
How I can make this algorithm better?
Use BigInteger, which is already included in .Net Core or available in the System.Runtime.Numerics Nuget Package.
static string Efficient(int power)
{
var result = BigInteger.Pow(2, power);
return result.ToString(CultureInfo.InvariantCulture);
}
On my machine, NotEfficient takes roughly 80ms, where Efficient takes 0.3ms. You should be able to manipulate that string (if I'm understanding your problem statement correctly):
static string InsertCommas(string value)
{
var sb = new StringBuilder(value);
for (var i = value.Length - 4; i > 0; i -= 4)
{
sb.Insert(i, ',');
}
return sb.ToString();
}
One way to resolve this is to pad your 4-digit numbers with leading zeroes if they are less than four digits by using the PadLeft method:
answer += A[i].ToString().PadLeft(4, '0') + ",";
And then you can use the TrimStart method to remove any leading zeros from the final result:
return answer.TrimStart('0');

Display of digits from 1 to 100 in c# such that each line ends with a modulus of 10

I am a beginner learning c#, I have this code
static void Main(string[] args)
{
int a = 0;
while (a < 100)
{
a = a + 1;
if ((a % 10) == 0)
{
Console.WriteLine(a);
}
else
{
Console.Write(a);
Console.Write(",");
}
}
}
Is there a more efficient way of writing this code? I feel there might be a better way of doing this in c#. This is my very first code. I will appreciate a response. Thanks
the short version would look like this:
int stepSize = 10;
for (int i = 1; i < 100; i+=stepSize )
{
Console.WriteLine(String.Join(",", Enumerable.Range(i, stepSize)));
}
Explanation:
You walk in steps of 10 through your for-loop. at each step the
Enumerable.Range method creates an array which holds numbers enumerated from a start value (i) until the count value (10).
The String.Join method takes each element of this array and combines them into a string separated by a ,
Since it looks like homework:
You should research how to useString.Format. This way you could arrange elements in one line at certain positions.
For iterations with a counter variable a for-loop is preferable, because it is exactly made for it with a clearly readable head signature.
You actually wrote a very readable code, which in my opinion is efficient. A shortening of codelines does not make it necessarily more efficient or faster or more readable. Sometimes the only advantage is that it looks a little more elegant ;) that's all
EDIT:
You can even get it down to one line:
Console.WriteLine(Enumerable.Range(0, 10).Select(x => String.Join(",", Enumerable.Range(x * 10 + 1, 10))));
it is short, but it is horrible to read and understand :)
First step would be using a foor loop instead.
for(int i = 0; i <= 100; i++)
{
if ((i % 10) == 0)
{
Console.WriteLine(i);
}
else
{
Console.Write(i);
Console.Write(",");
}
}
You could replace
Console.Write(i);
Console.Write(",");
with
Console.Write(string.Format("{0},", i));
or even better with
Console.Write($"{i},");
Just yet another approach
for (var i = 1; i <= 100; i++)
{
Console.Write(i);
Console.Write(i % 10 == 0 ? Environment.NewLine : ",");
}

Find all possible combinations of word with and without hyphens

For a string that may have zero or more hyphens in it, I need to extract all the different possibilities with and without hyphens.
For example, the string "A-B" would result in "A-B" and "AB" (two possibilities).
The string "A-B-C" would result in "A-B-C", "AB-C", "A-BC" and "ABC" (four possibilities).
The string "A-B-C-D" would result in "A-B-C-D", "AB-C-D", "A-BC-D", "A-B-CD", "AB-CD", "ABC-D", "A-BCD" and "ABCD" (eight possibilities).
...etc, etc.
I've experimented with some nested loops but haven't been able to get anywhere near the desired result. I suspect I need something recursive unless there is some simple solution I am overlooking.
NB. This is to build a SQL query (shame that SQL Server does't have MySQL's REGEXP pattern matching).
Here is one attempt I was working on. This might work if I do this recursively.
string keyword = "A-B-C-D";
List<int> hyphens = new List<int>();
int pos = keyword.IndexOf('-');
while (pos != -1)
{
hyphens.Add(pos);
pos = keyword.IndexOf('-', pos + 1);
}
for (int i = 0; i < hyphens.Count(); i++)
{
string result = keyword.Substring(0, hyphens[i]) + keyword.Substring(hyphens[i] + 1);
Response.Write("<p>" + result);
}
A B C D are words of varying length.
Take a look at your sample cases. Have you noticed a pattern?
With 1 hyphen there are 2 possibilities.
With 2 hyphens there are 4 possibilities.
With 3 hyphens there are 8 possibilities.
The number of possibilities is 2n.
This is literally exponential growth, so if there are too many hyphens in the string, it will quickly become infeasible to print them all. (With just 30 hyphens there are over a billion combinations!)
That said, for smaller numbers of hyphens it might be interesting to generate a list. To do this, you can think of each hyphen as a bit in a binary number. If the bit is 1, the hyphen is present, otherwise it is not. So this suggests a fairly straightforward solution:
Split the original string on the hyphens
Let n = the number of hyphens
Count from 2n - 1 down to 0. Treat this counter as a bitmask.
For each count begin building a string starting with the first part.
Concatenate each of the remaining parts to the string in order, preceded by a hyphen only if the corresponding bit in the bitmask is set.
Add the resulting string to the output and continue until the counter is exhausted.
Translated to code we have:
public static IEnumerable<string> EnumerateHyphenatedStrings(string s)
{
string[] parts = s.Split('-');
int n = parts.Length - 1;
if (n > 30) throw new Exception("too many hyphens");
for (int m = (1 << n) - 1; m >= 0; m--)
{
StringBuilder sb = new StringBuilder(parts[0]);
for (int i = 1; i <= n; i++)
{
if ((m & (1 << (i - 1))) > 0) sb.Append('-');
sb.Append(parts[i]);
}
yield return sb.ToString();
}
}
Fiddle: https://dotnetfiddle.net/ne3N8f
You should be able to track each hyphen position, and basically say its either there or not there. Loop through all the combinations, and you got all your strings. I found the easiest way to track it was using a binary, since its easy to add those with Convert.ToInt32
I came up with this:
string keyword = "A-B-C-D";
string[] keywordSplit = keyword.Split('-');
int combinations = Convert.ToInt32(Math.Pow(2.0, keywordSplit.Length - 1.0));
List<string> results = new List<string>();
for (int j = 0; j < combinations; j++)
{
string result = "";
string hyphenAdded = Convert.ToString(j, 2).PadLeft(keywordSplit.Length - 1, '0');
// Generate string
for (int i = 0; i < keywordSplit.Length; i++)
{
result += keywordSplit[i] +
((i < keywordSplit.Length - 1) && (hyphenAdded[i].Equals('1')) ? "-" : "");
}
results.Add(result);
}
This works for me:
Func<IEnumerable<string>, IEnumerable<string>> expand = null;
expand = xs =>
{
if (xs != null && xs.Any())
{
var head = xs.First();
if (xs.Skip(1).Any())
{
return expand(xs.Skip(1)).SelectMany(tail => new []
{
head + tail,
head + "-" + tail
});
}
else
{
return new [] { head };
}
}
else
{
return Enumerable.Empty<string>();
}
};
var keyword = "A-B-C-D";
var parts = keyword.Split('-');
var results = expand(parts);
I get:
ABCD
A-BCD
AB-CD
A-B-CD
ABC-D
A-BC-D
AB-C-D
A-B-C-D
I've tested this code and it is working as specified in the question. I stored the strings in a List<string>.
string str = "AB-C-D-EF-G-HI";
string[] splitted = str.Split('-');
List<string> finalList = new List<string>();
string temp = "";
for (int i = 0; i < splitted.Length; i++)
{
temp += splitted[i];
}
finalList.Add(temp);
temp = "";
for (int diff = 0; diff < splitted.Length-1; diff++)
{
for (int start = 1, limit = start + diff; limit < splitted.Length; start++, limit++)
{
int i = 0;
while (i < start)
{
temp += splitted[i++];
}
while (i <= limit)
{
temp += "-";
temp += splitted[i++];
}
while (i < splitted.Length)
{
temp += splitted[i++];
}
finalList.Add(temp);
temp = "";
}
}
I'm not sure your question is entirely well defined (i.e. could you have something like A-BCD-EF-G-H?). For "fully" hyphenated strings (A-B-C-D-...-Z), something like this should do:
string toParse = "A-B-C-D";
char[] toParseChars = toPase.toCharArray();
string result = "";
string binary;
for(int i = 0; i < (int)Math.pow(2, toParse.Length/2); i++) { // Number of subsets of an n-elt set is 2^n
binary = Convert.ToString(i, 2);
while (binary.Length < toParse.Length/2) {
binary = "0" + binary;
}
char[] binChars = binary.ToCharArray();
for (int k = 0; k < binChars.Length; k++) {
result += toParseChars[k*2].ToString();
if (binChars[k] == '1') {
result += "-";
}
}
result += toParseChars[toParseChars.Length-1];
Console.WriteLine(result);
}
The idea here is that we want to create a binary word for each possible hyphen. So, if we have A-B-C-D (three hyphens), we create binary words 000, 001, 010, 011, 100, 101, 110, and 111. Note that if we have n hyphens, we need 2^n binary words.
Then each word maps to the output you desire by inserting the hyphen where we have a '1' in our word (000 -> ABCD, 001 -> ABC-D, 010 -> AB-CD, etc). I didn't test the code above, but this is at least one way to solve the problem for fully hyphenated words.
Disclaimer: I didn't actually test the code

Binary to Decimal Conversion - Formula?

I've been searching a while and haven't gotten anything too useful yet, I'm working on a subnet calculator, and well I have used the decimal to binary which I found here, though, I haven't found a good way to convert binary to decimal.
Note: Remember its FROM binary TO decimal, anyways, im in need of the formula or something like that (meaning calculating it, not the automated one).
What I've understood by reading some other posts that you can somehow get the result by dividing by 10, but I didn't really understand it, so if anyone could point me in the right direction, I'd be glad.
Any and all help is very much appreciated guys! :)
Doing it without LINQ:
var s = "101011"; // my binary "number" as a string
var dec = 0;
for( int i=0; i<s.Length; i++ ) {
// we start with the least significant digit, and work our way to the left
if( s[s.Length-i-1] == '0' ) continue;
dec += (int)Math.Pow( 2, i );
}
A number in any base can be thought of as the sum of its digits multiplied by their place value. For example, the decimal number 3906 can be written as:
3*1000 + 9*100 + 0*10 + 6*1
The place values are simply powers of ten:
3*10^3 + 9*10^2 + 0*10^1 + 6*10^0
(Remember that any number taken to the power of zero is 1.)
Binary works exactly the same way, except the base is 2, not 10. For example, the binary number 101011 can be written as:
1*2^5 + 0*2^4 + 1*2^3 + 0*2^2 + 1*2^1 + 1*2^0
I hope that gives you a better understanding of binary numbers and how to convert them.
On a practical note, the best solution is Matt Grande's; it's always preferable to use a library method instead of rolling your own (unless you have a very good reason to do so).
You can do it like this:
string bin = "10010101010101";
long l = Convert.ToInt64(bin,2);
11010101 = 1*2^7 + 1*2^6 + 0*2^5 + 1*2^4 + 0*2^3 + 1*2^2 + 0*2^1 + 1*2^0
.................= 128 + 64 + 0 + 16 + 0 + 4 + 0 + 1
This works fine
using System;
class BinaryToDecimal
{
static void Main()
{
double sum = 0;
int n = 1111111; // binary number
int strn = n.ToString().Length; //how many digits has my number
for (int i = 0; i < strn; i++)
{
int lastDigit = n % 10; // get the last digit
sum = sum + lastDigit * (Math.Pow(2, i));
n = n / 10; //remove the last digit
}
Console.WriteLine(sum);
}
}
The answer is pretty straightforward. Let's assume you have x as a binary number:
string x = "10010101010101";
Since we know that the general formula to calculate is, starting from right, 2^index_1 + 2^index_2 + 2^index_n
we can use LINQ to do something like (not tested):
x.Reverse()
.Select((element, i) => new { Index = i, Element = char.GetNumericValue(element) })
.Where(a => a.Element != 0)
.Aggregate(0.0, (a, b) => a + (Math.Pow(2, b.Index)));
//a is an integer array which has binary value
sum = 0;
Array.Reverse(a);
for (int j = 0; j < a.Length;j++)
{
if (a[j] == 1)
sum = sum + (Math.Pow(2, j));
}
Here is mine..
private string binary2DecimalCal(string bin)
{
string res;
char[] cArr = bin.ToCharArray();
Array.Reverse(cArr); // Reverse binary string
List<string> sArr = new List<string>();
for (int i = bin.Length - 1; i > -1; i--) // Get the bits
sArr.Add(cArr[i].ToString()+"x2^"+i.ToString()); // Calculation step for each bits
res = String.Join(" + ", sArr.ToArray()); // Join the string with +
return res;
}

Categories

Resources