pls pls help me understand how Console.WriteLine() work - c#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Program
{
class Program
{
static void Main(string[] args)
{
int num, reverse = 0;
Console.WriteLine("Enter a Number : ");
num = int.Parse(Console.ReadLine());
while (num != 0)
{
reverse = reverse * 10;
reverse = reverse + num % 10;
num = num / 10;
}
Console.WriteLine("Reverse of Entered Number is : "+reverse);
}
}
}
I can grasp at the concept of the previous values of reverse accumulating during the iterations of the loop but why doesnt WriteLine() also output the string "Reverse of Entered Number is: " 3 times? I know it somewhat happens if I enter it in the loop body but the reverse output is still:
blah blah blah: 3 // I understand this
" " : 32 // I thought this was going to output 2
" " : 321 // while this outputs 1
Why is the "+ reverse" bit the only command executed? and not the whole line?
im sorry if this is a very basic or dumb question, its really bothering me had to create a SO account for it.

Let's walk through the program:
It starts with the variables num and reverse are initialized to 0;
int num, reverse = 0;
Now, a prompt is written to the console and Console.ReadLine() is used to read input from the user, which is parsed as an integer into the variable of num:
Console.WriteLine("Enter a Number : ");
num = int.Parse(Console.ReadLine());
For this example, let's assume the user entered the value 123.
Now, the application will loop as long as num doesn't get set to 0
while (num != 0)
{
Inside the loop, the value of reverse is multiplied by 10. The first time through, this will still be 0, since 0 * 10 is 0.
reverse = reverse * 10;
This is followed by adding num modulus 10 to reverse. Basically, this will return the last digit of whatever number the user entered. So if the user entered 123, this will be set to 3 the first time through the loop.
reverse = reverse + num % 10;
Now, the user's entered value stored in num is devided by 10. Since it's an int, fractional values are truncated, so 123 becomes 12.
num = num / 10;
We now restart the loop, but with num set to 12 and reverse set to 3.
At the top of the loop, reverse gets multiplied by 10 again, so it's new value is 30.
Then we add the last digit of num, which is 2, making reverse set to 32.
Followed by dropping the last digit of num, making it 1.
Once more, we loop, since num still doesn't equal 0, this time with num set to 1 and reverse set to 32.
At the top of the loop, reverse gets multiplied by 10 again, so it's new value is 320.
Then we add the last digit of num, which is 1, making reverse set to 321.
Followed by dropping the last digit of num, making it 0.
This time, num does equal 0, so the loop ends.
}
Console.WriteLine("Reverse of Entered Number is : "+reverse);
The program completes by printing the string "Reverse of Entered Number is : " followed by the final value of reverse.

Related

C# trying to fill up a binary number to 4 digit blocks

I have a base-n-converter and I wanted it to output all values in 4 digit blocks (1111 -> 1111, 101 -> 0101, 110101 -> 00110101). For this, I made this piece in vscode to try and make it work.
using System;
namespace Test
{
using static intUtilities;
class Program
{
static void Main(string[] args)
{
string number = "";
int[] wholenumbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for(;;)
{
Console.WriteLine("enter binary number");
number = Console.ReadLine();
Console.WriteLine("is number length divisible by 4? " + Contains(wholenumbers, number.Length/4f));
Console.WriteLine(number.Length/4f);
while(!Contains(wholenumbers, number.Length/4f))
{
number = "0" + number;
}
Console.WriteLine(number);
Console.ReadLine();
}
}
}
public class intUtilities
{
public static bool Contains(int[] array, float number)
{
foreach(int i in array)
{
if(i == number)
{
return true;
}
else {return false;}
}
return false;
}
}
}
For inputting 111, I am expecting an output of 0111, which does happen, but if I input 111111, I am expecting 00111111, but there is no output. When executing the while loop, it should catch the moment when numbers.Length / 4 is "2" (which is when therre would be 8 digits) and break the loop, but for some reason, it doesnt and keeps on adding zeros to the string. It even reads out numbers.Length / 4 as "2" at some point but doesnt break the loop. The code only seems to work for a target size of 4 digits, where numbers.Length / 4 would be "1". Is there a way to correct that? Or even an easier workaround?
There are a number of "interesting" issues with this code, but to answer your immediate question, you need to remove the else {return false;} line. This prevents you from searching over every element in the wholeNumbers array - or more specifically, you only query the first element in the wholeNumbers array (which is the value 1) which is why the code only works correctly for the first 4-bit block of binary digits.
In the spirit of your approach, a possible implementation is:
void Main()
{
string number = "";
Console.WriteLine("enter binary number");
number = Console.ReadLine();
while (number.Length % 4 != 0)
{
number = "0" + number;
}
Console.WriteLine(number);
}
The original question ('why doesn't this work') is answered by Phillip Ngan.
Just fyi the correct result can be gotten in a simple calculation without a loop:
void Main
{
Console.WriteLine("enter binary number");
string number = Console.ReadLine();
int padLength = (4 - (number.Length % 4)) % 4;
number = "000".Substring(0, padLength)+number;
Console.WriteLine(number);
}
edit: Just noticed this is simply a variant for the solution proposed by John Glenn.
Or even an easier workaround?
Relying on the usual "round an integer up to the nearest N" of "integer, divide by N, add one and times by N" we can use this to pad the left of the binary string out to the next "multiple of 4" up from the current length
var x= "01111";
var y = x.PadLeft(((x.Length/4)+1)*4, '0');
y is "00001111";
If you don't like all the parentheses you can use precedence to the same effect
.PadLeft(x.Length/4*4+4, '0');
Hopefully most future readers of the code will remember their high school maths lessons 😀
You can use the modulus function to determine the remainder of one number (the string length) divided by another number (4). The entire effect can be shortened to this:
// find how many characters don't fit into a block of four
int leftovers = numbers.Length % 4;
// determine how many numbers to pad
int padding =
(4 - leftovers) // this is the number of characters we have to add to get an even group of 4
% 4; // this will ensure that if leftovers is 0, then instead of padding 4 characters we don't pad any
// pad the string
string displayMe = numbers.PadLeft(numbers.Length + padding, '0');

I have this code to find Prime numbers with in the range please anyone to tell why used i=2 in the nested loop?

I know to change the value in nested for loop i=2 the program will not give result in prime numbers. But I want to know the reason and purpose of assigning only 2 to i. Also a Plus if someone explain this using pseudo code.
using System;
namespace Prime_number
{
class Program
{
static void Main(string[] args)
{
int num, i, count, start, end;
Console.Write("Enter Start of range: ");
start = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter End of range : ");
end = Convert.ToInt32(Console.ReadLine());
Console.Write("The prime numbers between {0} and {1} are : \n", start, end);
for (num = start; num <= end; num++)
{
count = 0;
for (i = 2; i <= num / 2; i++)
{
if (num % i == 0)
{
count++;
break;
}
}
if (count == 0 && num != 1)
Console.Write(num + "\n");
}
Console.Write("\n");
}
}
}
It is a self explanatory code:
Read the range_start value.
Read the range_end value.
For each value from range_start to range_end
Check if valueis divisible by any number in range 2 to the half of value
It will be prime if it is not divisible.
The divisors 0 and 1 are not tested for obvious reasons, all numbers are divisible by 1 and any number divided by 0 gives same result, infinity, in limits theory, or divide by zero exception, in a real CPU implementation. only numbers up to value / 2 are tested for an also obvious reason, value would not be divisible by any number in that range but itself.
EDIT: As you're working with integer values, one small optimization would be to use value >> 1 instead of value / 2, shift operations are way faster than div operations at CPU level, yet compilers often apply this optimization when the divisor is known at compile-time.

Setting final value to zero makes the program not count or output, but setting to the lowest value does

This is practice for a separate larger program, just a little console output showing how many of certain values are used. For some reason if I set the final while num value to zero, it won't output anything in the console. If I set it to 20 it will output, count the hundreds and the 20's, but skips the fact that there is a 50 because the while value won't allow it to go below 20. I tried while num is >= to zero as well. At > zero or >=, I would expect it would count the 50 and output 4 100's, 1 50 and 0 20's. I arbitrarily set the while value to 10 and it still gave 2 20's and the hundreds, but set at 1 it didn't output again, same as when set to zero. Before I can incorporate the logic into the bigger program which has a lot more values and returns I imagine I'll need to understand where I'm failing. I looked into recursion and trackback algorithms and they were just a bit beyond where I'm at yet. I did wonder if I could use modulus too. That's off track tho, I'm most curious about why that while value won't allow itself to be set to greater than or greater than/equal to zero.
using System;
namespace dollars_back_test
{
class Program
{
static void Main(string[] args)
{
int num = 450, hundos = 0, fifties = 0, twenties = 0;
do
{
if (num > 100)
{
num -= 100;
hundos++;
}
else if (num > 50)
{
num -= 50;
fifties++;
}
else if (num > 20)
{
num -= 20;
twenties++;
}
} while (num > 20);
Console.WriteLine($"Dispensing {hundos} 100's, {fifties} 50's, {twenties} 20's.");
Console.ReadLine();
}
}
}
I'm not sure I correctly understand the issue, but I believe what your asking is why the while loop is not printing any 50's. This is because you are checking if number is bigger than 50, but since you subtract 100 four times the values shall be:
1st loop: num 450
2nd loop: num 350
3rd loop: num 250
4th loop: num 150
5th loop: num 50 --> explenation: number isn't larger than 50, it is >= 50, that's why it will continue with printing the num>20 two times until 10 remains.
6th loop: num 30
7th loop: num 10
To solve this issue you can simply replace this:
num>50
by
num>=50
if that's what you would like to see. Then it will print the 50's.

When I put a number larger than 1 in my binary-to-decimal converter, I get the error startIndex cannot be larger than length of string

I'm trying to create a program that converts a 5 digit binary number to decimal. As it stands, the conversion works perfectly, but I'm having trouble with giving an error message if the user inputs a number larger than 1.
for (int i = 4; i>=0; i--)
{
digit = txt_input.Text.Substring(i,1);
num = Convert.ToInt32(digit);
//If a digit is 1 or 0
if (num <= 1)
{
total += num * (Math.Pow(2, x));
x += 1;
goahead = 1;
}
//If a digit is not 1 or 0
if (num > 1)
{
lst_output.Items.Add("All digits must be either 1 or 0.");
i = 10;
goahead = 0;
}
}
When the user inputs 1's or 0's the program works as intended, but when a number larger than 1 is inputted, I get the error "startIndex cannot be larger than length of string" on line 3.
If a number with more or less than 5 digits is inputted, the user gets a message saying that the number must be 5 digits long. So as far as I can tell, the problem isn't the size of the startIndex. Especially since, no matter what the user inputs, startIndex remains unchanged.
Imagine your input is 10103.
Now pay attention to this part of the code:
if (num > 1)
{
lst_output.Items.Add("All digits must be either 1 or 0.");
i = 10;
goahead = 0;
}
Why are you making i = 10 here?
So if you input is the above string, in the first iteration you'd go into the if statement above, add the message to lst_output, then set i to 10. Then you go back to the for loop and the i >= 0 condition is still true so you go inside the for loop once again. Now your i = 1, but your string is of length 5.
So;
digit = txt_input.Text.Substring(i,1);
Here now you're trying to take a substring of length 1 that starts at the index = 10, from a string that is only 5 characters long.
Of course it would throw
startIndex cannot be larger than length of string.
Parameter name: startIndex.

Request for explanation of for-loop logic as it is applied in this C# armstrong number checker

Homework alert! I am trying to build a console app to determine whether a given integer is an Armstrong number. I found a working solution online, but after spending far too much time analyzing it, I still don't understand the logic well enough to reproduce it on my own... The two pain points I've identified are 1) I do not understand exactly how the Parse method is acting upon the integer that the user inputs, and 2) the logic sequence of the for loop is not self-evident (see code and my logic description below):
int number, remainder, sum = 0;
Console.WriteLine("Enter a number: ");
number = int.Parse(Console.ReadLine());
for (int i = number; i > 0; i = i / 10)
{
remainder = i % 10;
sum = sum + remainder * remainder * remainder;
}
if (sum == number)
{
Console.Write("Entered Number is an Armstrong Number");
}
else
Console.Write("Entered Number is not an Armstrong Number");
Console.ReadLine();
This is how my understanding of the for loop logic breaks down:
The integer is passed into the for loop and assigned to int i
//e.g. i = 153//
If the value of i is greater than 0, then re-assign the value of i to i/10 //e.g. 153/10 == 15r3 //
Assign the remainder value of i/10 to int remainder //e.g. remainder = 3//
Compute the sum as sum + remainder * remainder * remainder //e.g. sum = 0 + 3 * 3 * 3//
if the sum is equal to the number, then print "Entered number is Armstrong number" //e.g. however, 27 !== 153//
What am I missing here?
Since this is self-admitted homework, I'm not going to give you a complete answer, but pointers instead.
Make number a string variable. You can then use your for loop to go through each character in the string and perform the math on them.
Use math.pow to create your sum, not sum = sum + remainder * remainder * remainder, since this makes the assumption that you are always using a 3-digit number. (hint: int N = number.Length()
Helper links:
math.pow
Armstrong Numbers

Categories

Resources