Reversing a while loop, I don't know if it's the correct way to ask the question, but come on. I have a code that converts any whole number to a two or three digit decimal. How?
dividing the integer value by two until it is less than 10, counting in turn the times it divided it in the redo variable, thus we obtain the tenth: decimal = (integer, redo):
int InitialInteger = 190;
int Integer = InitialInteger;
int redo = 0;
while (Integer > 10)
{
Integer = Integer / 2;
redo++;
}
//Salida: 5,5
Now I want to get back the initial integer value ("reverse the loop") that is, multiply the integer part by 2 as many times as the decimal part indicates: Integer = (decimal1 * 2)^decimal2
int decimal1 = Int16.Parse(Decimal.Split(',')[0]);
int decimal2 = Int16.Parse(Decimal.Split(',')[1]);
while (decimal2 > 0)
{
redo -= 1;
InitialInteger += decimal2 * 2;
}
//Salida: 60
but it doesn't work, it never returns the initial value!
Any idea?
Note that you have to set Integer as a float instead of as int for it to work.
Use this instead
int InitialInteger = 190;
float temp = InitialInteger;
int redo = 0;
while (temp > 10)
{
temp= temp / 2;
redo++;
}
and then to reverse
while (redo > 0)
{
temp = temp * 2;
redo--;
}
At the end temp (or Integer as you called it!) is again 190
Related
Update 01
Thanks to Caius, found the main problem, the logic on the "if" was wrong, now fixed and giving the correct results. The loop still create more positions than needed on the secondary List, an extra position for each number on the main List.
I've updated the code bellow for refence for the following question:
-001 I can figure out why it create positions that needed, the for loop should run only after the foreach finishes its loops correct?
-002 To kind of solving this issue, I've used a List.Remove() to remove all the 0's, so far no crashes, but, the fact that I'm creating the extra indexes, and than removing them, does means a big performance down if I have large list of numbers? Or is an acceptable solution?
Description
It supposed to read all numbers in a central List1 (numberList), and count how many numbers are inside a certain (0|-15 / 15|-20) range, for that I use another List, that each range is a position on the List2 (numberSubList), where each number on List2, tells how many numbers exists inside that range.
-The range changes as the numbers grows or decrease
Code:
void Frequency()
{
int minNumb = numberList.Min();
int maxNumb = numberList.Max();
int size = numberList.Count();
numberSubList.Clear();
dGrdVFrequency.Rows.Clear();
dGrdVFrequency.Refresh();
double k = (1 + 3.3 * Math.Log10(size));
double h = (maxNumb - minNumb) / k;
lblH.Text = $"H: {Math.Round(h, 2)} / Rounded = {Math.Round(h / 5) * 5}";
lblK.Text = $"K: {Math.Round(k, 4)}";
if (h <= 5) { h = 5; }
else { h = Math.Round(h / 5) * 5; }
int counter = 1;
for (int i = 0; i < size; i++)
{
numberSubList.Add(0); // 001 HERE, creating more positions than needed, each per number.
foreach (int number in numberList)
{
if (number >= (h * i) + minNumb && number < (h * (i + 1)) + minNumb)
{
numberSubList[i] = counter++;
}
}
numberSubList.Remove(0); // 002-This to remove all the extra 0's that are created.
counter = 1;
}
txtBoxSubNum.Clear();
foreach (int number in numberSubList)
{
txtBoxSubNum.AppendText($"{number.ToString()} , ");
}
lblSubTotalIndex.Text = $"Total in List: {numberSubList.Count()}";
lblSubSumIndex.Text = $"Sum of List: {numberSubList.Sum()}";
int inc = 0;
int sum = 0;
foreach (int number in numberSubList)
{
sum = sum + number;
int n = dGrdVFrequency.Rows.Add();
dGrdVFrequency.Rows[n].Cells[0].Value = $"{(h * inc) + minNumb} |- {(h * (1 + inc)) + minNumb}";
dGrdVFrequency.Rows[n].Cells[1].Value = $"{number}";
dGrdVFrequency.Rows[n].Cells[2].Value = $"{sum}";
dGrdVFrequency.Rows[n].Cells[3].Value = $"{(number * 100) / size} %";
dGrdVFrequency.Rows[n].Cells[4].Value = $"{(sum * 100) / size} %";
inc++;
}
}
Screen shot showing the updated version.
I think, if your aim is to only store eg 17 in the "15 to 25" slot, this is wonky:
if (number <= (h * i) + minNumb) // Check if number is smaller than the range limit
Because it's found inside a loop that will move on to the next range, "25 to 35" and it only asks if the number 17 is less than the upper limit (and 17 is less than 35) so 17 is accorded to the 25-35 range too
FWIW the range a number should be in can be derived from the number, with (number - min) / number_of_ranges - at the moment you create your eg 10 ranges and then you visit each number 10 times looking to put it in a range, so you do 9 times more operations than you really need to
I need to divide a variable distance in a very specific way. The spacing for the divisions must be 40 units minimum, and 80 units maximum.
I've tried several different various of this code but I am struggling to wrap my head around how to include the min/max variable in my division.
double totaldist = X;
double division = totaldist / 80;
double roundup = Math.Ceiling(division);
double space = totaldist / roundup;
double increment = 0;
while (increment < totaldist)
{
increment = increment + space;
}
The attached code is obviously short of what I want to accomplish, I'm not sure how to bridge the gap. Thank you
So all you have to do is loop over all the possible divisors and pick the best one. The simplest way to accomplish this is as follows:
public static int remainder(int totalDist)
{
double minRemainder = (totalDist % 40) / 40;
int bestDivision = 40;
for (var i = 40; i <= 80; i++)
{
double cRemainder = (totalDist % i) / i;
if (totalDist % i == 0) return i;
else if (cRemainder < minRemainder) { minRemainder = cRemainder; bestDivision = i; }
}
return bestDivision;
}
This will always return the closest result. Even if there is no real solution, it will still provide an approximate answer as a fallback.
I'd test every divisor for mod 0 (no remainder)
int d = 420;
int s = 40;
for(; s <= 80; s++){
if(d%s==0)
break;
}
if(s==81)
Console.Write("There is no suitable divisor");
else
Console.Write($"{d} divides into {s} segments of {d/s} with no remainder");
If you want to minimise the segment length (greater number of segments) start at 80 and work towards 40 in the loop instead - set your d to 480, start at 80 and you should get "80 segments of length 6" rather than "40 segments of length 12"
You can even get cute with your loop and have no body:
for(; s <= 80 && d%s > 0; s++){ }
But it's not quite so readable/self explanatory
can you help me figure out how to calculate this way, for example I have some integer:
first I need condition
if (x < 10) to avoid asked calculation for single numbers
now if number contains more then 1 digit need to calculate it second way, for example, I got 134 how to separate it to calculate it this way 1 + 3 + 4 to attach this value 8 to variable.
So question is how to separate numbers
try
int num = 12345;
// holder temporarily holds the last digit of the number
int holder = 0;
int sum = 0;
while (num>0)
{
holder = num%10;
num = num/10;
sum += holder;
}
//sum would now hold the sum of each digit
This isn't C# in particular, but you can loop over your number then get it digit by digit.
// -- c
int num = 134;
int sum = 0;
while(num != 0) {
ones_digit = num % 10;
sum += ones_digit;
num = (num - ones_digit) / 10;
}
printf("sum: %d", sum);
On higher-level languages like javascript or python, accessing the digits can also be done by converting the integer to a string, then casting each char to an int type.
// -- javascript
var num = 134;
var digits = num.toString().split("").map(parseInt);
console.log(digits);
Here's the script reference document for Mathf.FloorToInt As you can see, it should round -0.5 down to -1. For some reason it seems to return it as 0 when used with my calculations.
I have two versions of the same functions that work in a very similar way but give different outputs. My code will only ever submit integers between 3 and 18 to these functions.
This version acts as if it were using Mathf.CielToInt (returns 0 in a case of statRoll = 9):
public int getBonus(int statRoll)
{
int result = Mathf.FloorToInt((statRoll - 10) / 2);
return result;
}
This is the version that works (returns -1 in a case of statRoll = 9):
public int getBonus(int statRoll)
{
float initial = statRoll - 10;
float divided = initial / 2;
int result = Mathf.FloorToInt(divided);
return result;
}
You are getting bit by integer division. Both statRoll and 10 are int type, that makes initial actually a int.
Your first code is equivalent to
public int getBonus(int statRoll)
{
int initial = statRoll - 10;
int devisor = 2;
int divided = initial / devisor;
float castDevided = (float)divided
int result = Mathf.FloorToInt(castDevided);
return result;
}
When you do -1 / 2 you have two ints, this evaluates to 0 not -0.5 because the result must also be a int. The way to fix this is make one of the two values a float
public int getBonus(int statRoll)
{
int result = Mathf.FloorToInt((statRoll - 10) / 2f); //adding f after a number makes it a float
return result;
}
This makes the division between a int and a float which results in a float. The similar code would be
public int getBonus(int statRoll)
{
int initial = statRoll - 10;
float devisor = 2f;
float divided = initial / devisor ;
int result = Mathf.FloorToInt(divided);
return result;
}
I would like to split a two digit int into 2 one digit ints! For example:
20 = 2 and 0
15 = 1 and 5
8 = 0 and 8
That's easy: use % to get the mod of the number, and / for the integer division (i.e. division where the fractional part is discarded).
Your numbers are in the decimal system (i.e. the base is 10) so you divide and mod by 10, like this:
int a = 20 / 10; // 2
int b = 20 % 10; // 0
To print a number digit-by-digit, least significant digit first, you can use this loop:
int a = 12345;
while (a != 0) {
lastDigit = a % 10;
Console.WriteLine(lastDigit);
a /= 10;
}
int i = 45; // or anything you want
int firstDigit = i / 10;
int secondDigit = i % 10;
It's quite simple really.
You can do this for 3-digit numbers using a Modulos and Division operations as well, but I'll let you figure that out by yourself. ;)
Yeah , easy.
int m =2123;
int n=m;
while (n != 0) {
y=n%10; //variable holds each digit out of the number m.
Console.WriteLine(y);
n /= 10;
}
int input = 15;
int first = 0;
int second = Math.DivRem(input, 10, out first);
If you have a array of integers then you can very well use LINQ, else just use any of the below answers.
int num = 86;
int digit1 = num / 10;
int digit2 = num % 10;
Do your numbers have only two digits?