How to convert number to next higher multiple of five? - c#

I am coding a program where a form opens for a certain period of time before closing. I am giving the users to specify the time in seconds. But i'd like this to be in mutliples of five. Or the number gets rounded off to the nearest multiple.
if they enter 1 - 4, then the value is automatically set to 5.
If they enter 6 - 10 then the value is automatically set to 10.
max value is 60, min is 0.
what i have, but i am not happy with this logic since it resets it to 10 seconds.
if (Convert.ToInt32(maskedTextBox1.Text) >= 60 || Convert.ToInt32(maskedTextBox1.Text) <= 0)
mySettings.ToastFormTimer = 10000;
else
mySettings.ToastFormTimer = Convert.ToInt32 (maskedTextBox1.Text) * 1000;

use the Modulus Operator
if(num % 5 == 0)
{
// the number is a multiple of 5.
}

what about this:
int x = int.Parse(maskedTextBox1.Text)/5;
int y = Math.Min(Math.Max(x,1),12)*5; // between [5,60]
// use y as the answer you need

5 * ((num - 1) / 5 + 1)
Should work if c# does integer division.

For the higher goal of rounding to the upper multiple of 5, you don't need to test whether a number is a multiple. Generally speaking, you can round-up or round-to-nearest by adding a constant, then rounding down. To round up, the constant is one less than n. Rounding an integer down to a multiple of n is simple: divide by n and multiply the result by n. Here's a case where rounding error works in your favor.
int ceil_n(int x, int n) {
return ((x+n-1) / n) * n;
}
In dynamic languages that cast the result of integer division to prevent rounding error (which doesn't include C#), you'd need to cast the quotient back to an integer.
Dividing by n can be viewed as a right-shift by 1 place in base n; similarly, multiplying by n is equivalent to a left-shift by 1. This is why the above approach works: it sets the least-significant digit of the number in base n to 0.
2410=445, 2510=505, 2610=515
((445+4 = 535) >>5 1) <<5 1 = 505 = 2510
((505+4 = 545) >>5 1) <<5 1 = 505 = 2510
((515+4 = 605) >>5 1) <<5 1 = 605 = 3010
Another way of zeroing the LSD is to subtract the remainder to set the least significant base n digit to 0, as Jeras does in his comment.
int ceil_n(int x, int n) {
x += n-1;
return x - x%n;
}

Related

c sharp finding a specific digit in an int [duplicate]

This question already has answers here:
Get the seventh digit from an integer
(9 answers)
Get individual digits from an Int without using strings?
(1 answer)
Closed 4 years ago.
I'm trying to find the nth digit of an integer (from right to left). I'm new to programming but have been using this site a lot for reference - up until now I've resisted passing my problems on but I cannot understand this one in the least, even after hours of effort.
This is the code I have so far but for FindDigit(int 5673, int 4) it gives 53 instead of 5, FindDigit(int 5673, int 3) gives 51 instead of 6
public class DigitFinder
{
public static int FindDigit(int num, int nth)
{
num = Math.Abs(num);
string answer = Convert.ToString(num);
int i = answer.Length;
return ans[i-nth];
}
}
I cannot understand at all why it returns a 2 digit number. Any guidance at all appreciated!
I'd just use
int result = (num / (int)Math.Pow(10,nth-1)) % 10;
Where num is the number to get the nth digit from (counted right to left) and nth is the "index" of digits you want (again: counted from right to left). Mind that it is 1-based. That is "1" is the rightmost digit. "0" would be out of range.
To explain the math:
(int)Math.Pow(10,nth-1) takes your desired index and decreases it by 1, then takes that as the power of 10. So if you want the 3rd digit, that makes 10 to the power of two equals 100.
BTW: the cast to int is necessary because Math.Pow works on double and returns double. But we want to keep on working in integer arithmetic.
Dividing by the result of above equation "shifts" your number to the right, so your desired digit becomes the rightmost digit. Example: 1234, we want 3rd digit from right ("2") => 1234 / (10^(3-1))= 1234 / 100 = 12
You then "cut out" that rightmost digit by applying the "remainder" (modulo) operator with divisor 10. Example: 12 % 10 = [12 / 10 = 1, Remainder =] 2.
Mind that I also would check nth to be > 0 and num >= 10 ^ (nth-1). (never trust user input)
53 is the ASCII code of the character 5. Just subtract the character 0, i.e. numeric 48.
However, it is usually a good idea to avoid string manipulation for things like this; if possible you should probably prefer division/remainder (modulo) arithmetic.
Just because no one else did, and also because i have Printable Character OCD
public static int GetLeastSignificantDigit(int number, int digit)
{
for (var i = 0; i < digit - 1; i++)
number /= 10;
return number % 10;
}
Demo here

Percentile algorithm

I am writing a program that finds percentile. According to eHow:
Start to calculate the percentile of your test score (as an example we’ll stick with your score of 87). The formula to use is L/N(100) = P where L is the number of tests with scores less than 87, N is the total number of test scores (here 150) and P is the percentile. Count up the total number of test scores that are less than 87. We’ll assume the number is 113. This gives us L = 113 and N = 150.
And so, according to the instructions, I wrote:
string[] n = Interaction.InputBox("Enter the data set. The numbers do not have to be sorted.").Split(',');
List<Single> x = new List<Single> { };
foreach (string i in n)
{
x.Add(Single.Parse(i));
}
x.Sort();
List<double> lowerThan = new List<double> { };
Single score = Single.Parse(Interaction.InputBox("Enter the number."));
uint length = (uint)x.Count;
foreach (Single index in x)
{
if (index > score)
{
lowerThan.Add(index);
}
}
uint lowerThanCount = (uint)lowerThan.Count();
double percentile = lowerThanCount / length * 100;
MessageBox.Show("" + percentile);
Yet the program always returns 0 as the percentile! What errors have I made?
Your calculation
double percentile = lowerThanCount / length * 100;
is all done in integers, since the right hand side consist of all integers. Atleast one of the operand should be of floating point type. So
double percentile = (float) lowerThanCount / length * 100;
This is effectively a rounding problem, lowerThanCount / length are both unit therefore don't support decimal places so any natural percentage calculation (e.g. 0.2/0.5) would result in 0.
For example, If we were to assume lowerThanCount = 10 and length = 20, the sum would look something like
double result = (10 / 20) * 100
Therefore results in
(10 / 20) = 0.5 * 100
As 0.5 cannot be represented as an integer the floating point is truncated which leaves you with 0, so the final calculation eventually becomes
0 * 100 = 0;
You can fix this by forcing the calculation to work with a floating point type instead e.g.
double percentile = (double)lowerThanCount / length * 100
In terms of readability, it probably makes better sense to go with the cast in the calculation given lowerThanCount & length won't ever naturally be floating point numbers.
Also, your code could be simplified a lot using LINQ
string[] n = Interaction.InputBox("Enter the data set. The numbers do not have to be sorted.")
.Split(',');
IList<Single> x = n.Select(n => Single.Parse(n))
.OrderBy(x => x);
Single score = Single.Parse(Interaction.InputBox("Enter the number."));
IList<Single> lowerThan = x.Where(s => s < score);
Single percentile = (Single)lowerThan.Count / x.Count;
MessageBox.Show(percentile.ToString("%"));
The problem is in the types that you used for your variables: in this expression
double percentile = lowerThanCount / length * 100;
// ^^^^^^^^^^^^^^^^^^^^^^^
// | | |
// This is integer division; since length > lowerThanCount, its result is zero
the division is done on integers, so the result is going to be zero.
Change the type of lowerThanCount to double to fix this problem:
double lowerThanCount = (double)lowerThan.Count();
You are using integer division instead of floating point division. Cast length/lowerThanCount to a float before dividing.
Besides the percentile calculation (should be with floats), I think your count is off here:
foreach (Single index in x)
{
if (index > score)
{
lowerThan.Add(index);
}
}
You go through indexes and if they are larger than score, you put them into lowerThan
Just a logical mistake?
EDIT: for the percentile problem, here is my fix:
double percentile = ((double)lowerThanCount / (double)length) * 100.0;
You might not need all the (double)'s there, but just to be safe...

How can you separate a string of numbers to single digits using division and the modulo operator?

Lets say someone enter a four digit number 1234 in the console. How can you separate this number in to 1 2 3 4 using only division and the modulo operator?
public static void MathProblem()
{
Console.WriteLine("Type a four digit number:");
//Ex input: 1234
string inputNumber = Console.ReadLine();
// I'm guessing you first need to parse the
// string as an int in some way?
// And then assign it to some variable
// Now, for seperating the digits to be: 1 2 3 4,
// you can (and must) use both division (/), and the remainder (%).
// The first one will be simple, just dividing value with 1000, but
// how about the others? (Remember, % also need to be used at least
// once)
Console.Write("{0},{1},{2},{3}", value/1000, ?, ?, ?;
}
Any guidelines for making this possible for any given four digit input?
Since this seems like a homework problem, I'll simply explain the method in a few steps rather than giving you the code. Having parsed the input as an integer,
A number modulo 10 allows you to obtain its last digit.
Dividing (integer division) the number by 10 removes the last digit.
Repeat while the number is greater than 0.
int num = int.Parse(inputNumber);
Console.Write(string.Format("{0},{1},{2},{3}", (num/1000) % 100, (num/100) % 10, (num/10) % 10, num % 10));
OR
List<int> listOfInts = new List<int>();
while(num > 0)
{
listOfInts.Add(num % 10);
num = num / 10;
}
Console.Write("{0},{1},{2},{3}", listOfInts[3], listOfInts[2], listOfInts[1], listOfInts[0]);
No need to do this by division or modulo operators. Use LINQ. You can get an integer array using LINQ as below:
string inputNumber= "1234"
var intList = inputNumber.Select(digit => int.Parse(digit.ToString()));
Then, you can simply use it as you want like this:
Console.Write("{0},{1},{2},{3}", intList[0]/1000, intList[1], intList[2], intList[3]);
Or simply the way you wanted it using Division and Modulo Operator:
public int[] ParseIntString(int number)
{
List<int> digits= new List<int>();
while(number> 0)
{
digits.Add(number% 10);
number= number/ 10;
}
digits.Reverse();
return digits.ToArray();
}
I hope this helps you
int[] values;
Seperate(inputNumber, out values);
Console.Write("{0},{1},{2},{3}", values[0] / 1000, values[1], values[2], values[3]);
Console.ReadKey();
}
public static void Seperate(string numbers, out int[] values)
{
values = new int[numbers.Length];
for (int x = 0; x <= numbers.Length - 1; x++)
{
values[x] = int.Parse(numbers[x].ToString());
}
}
I just started a course in coding and had this as homework as well. I did it in excel first because I thought it was easier than running code over and over and it's more a math problem than a coding one.
Say the number is 4352.
The first digit is easy, it's the integer of the number / 1000 = 4.
Then you simply multilpy by 1000 to get 4000. Remove that and you get 352. The integer of that / 100 is 3.
Then you times that by 100 to get 300 and remove that and you get 52, the integer of that / 10 is 5. Multiply that by 10 and remove that and you're left with 2.
Just read that you must use % so I suggest getting the last number as a modular of 10

Project euler number 10#

The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
And my answer is:
bool IsRishoni;
int soap = 0;
for (int i = 3; i < 2000000; i++)
{
IsRishoni = true;
for (int a = 2; (a <= Math.Sqrt(i)) && (IsRishoni); a++)
{
if (i % a == 0)
IsRishoni = false;
}
if (IsRishoni)
{
soap = i + soap;
}
}
Console.WriteLine(soap + 2);
Console.ReadLine();
Why is this not working? the answer I got is 1179908154 ... help please.
Replace
soap = i + soap;
with
soap = checked(i + soap);
..and the problem should be exposed.
This question has more details: No overflow exception for int in C#?
Your answer (stored in soap) is a value greater than int.Maxvalue (2,147,483,647).
Your answer is ~ 150,000,000,000
In other words you need to use an data type which is bigger than that.
long.MaxValue = 9,223,372,036,854,775,807
int.Maxvalue = 2,147,483,647
The result you’re after might be too large to represent through a 32-bit signed integer (int).
Let’s first determine the result’s upper bound by assuming that all numbers are prime. Through summation, we know that the sum of all numbers up to N (inclusive) is N * (N + 1) / 2; thus, the upper bound for the sum of all primes up to 2,000,000 is 2,000,001,000,000. This is larger than the maximum value allowed by int, 2,147,483,647, so you’re probably getting a numeric overflow which is silently ignored.
If you wanted a more accurate estimate of your answer, you could use the prime number theorem, which states that the probability of a random integer between 0 and N being prime is approximately 1 / ln(N). Combining this with our previous formula, the approximate sum of all primes up to N is N * (N + 1) / (2 * ln(N)). For 2,000,000, this evaluates to around 138,000,000,000, which is still larger than the maximum value for int.
To resolve your problem, you could simply switch the integral data type you’re using for the soap variable to a 64-bit integer representation, such as long. Its maximum value is 9,223,372,036,854,775,807, so it would definitely be able to represent your number.
long soap = 0;
On a separate note: Since you’re working with sequences of primes, you could achieve a huge performance gain (at least 100×) if you change your implementation to a Sieve of Eratosthenes.

How to know the repeating decimal in a fraction?

I already know when a fraction is repeating decimals. Here is the function.
public bool IsRepeatingDecimal
{
get
{
if (Numerator % Denominator == 0)
return false;
var primes = MathAlgorithms.Primes(Denominator);
foreach (int n in primes)
{
if (n != 2 && n != 5)
return true;
}
return false;
}
}
Now, I'm trying to get the repeated number. I'm checking this web site: http://en.wikipedia.org/wiki/Repeating_decimal
public decimal RepeatingDecimal()
{
if (!IsRepeatingDecimal) throw new InvalidOperationException("The fraction is not producing repeating decimals");
int digitsToTake;
switch (Denominator)
{
case 3:
case 9: digitsToTake = 1; break;
case 11: digitsToTake = 2; break;
case 13: digitsToTake = 6; break;
default: digitsToTake = Denominator - 1; break;
}
return MathExtensions.TruncateAt((decimal)Numerator / Denominator, digitsToTake);
}
But I really realized, that some numbers has a partial decimal finite and later infinite. For example: 1/28
Do you know a better way to do this? Or an Algorithm?
A very simple algorithm is this: implement long division. Record every intermediate division you do. As soon as you see a division identical to the one you've done before, you have what's being repeated.
Example: 7/13.
1. 13 goes into 7 0 times with remainder 7; bring down a 0.
2. 13 goes into 70 5 times with remainder 5; bring down a 0.
3. 13 goes into 50 3 times with remainder 11; bring down a 0.
4. 13 goes into 110 8 times with remainder 6; bring down a 0.
5. 13 goes into 60 4 times with remainder 8; bring down a 0.
6. 13 goes into 80 6 times with remainder 2; bring down a 0.
7. 13 goes into 20 1 time with remainder 7; bring down a 0.
8. We have already seen 13/70 on line 2; so lines 2-7 have the repeating part
The algorithm gives us 538461 as the repeating part. My calculator says 7/13 is 0.538461538. Looks right to me! All that remains are implementation details, or to find a better algorithm!
If you have a (positive) reduced fraction numerator / denominator, the decimal expansion of the fraction terminates if and only if denominator has no prime factor other than 2 or 5. If it has any other prime factor, the decimal expansion will be periodic. However, the cases where the denominator is divisible by at least one of 2 and 5 and where it isn't give rise to slightly different behaviour. We have three cases:
denominator = 2^a * 5^b, then the decimal expansion terminates max {a, b} digits after the decimal point.
denominator = 2^a * 5^b * m where m > 1 is not divisible by 2 or by 5, then the fractional part of the decimal expansions consists of two parts, the pre-period of length max {a, b} and the period, whose length is determined by m and independent of the numerator.
denominator > 1 is not divisible by 2 or by 5, then the decimal expansion is purely periodic, meaning the period starts immediately after the decimal point.
The treatment of cases 1. and 2. has a common part, let c = max {a, b}, then
numerator / denominator = (numerator * 2^(c-a) * 5^(c-b)) / (10^c * m)
where m = 1 for case 1. Note that one of the factors 2^(c-a) and 5^(c-b) with which we multiply the numerator is 1. Then you get the decimal expansion by expanding
(numerator * 2^(c-a) * 5^(c-b)) / m
and shifting the decimal point c places to the left. In the first case (m = 1) that part is trivial.
The treatment of cases 2. and 3. also has a common part, the calculation of a fraction
n / m
where n and m have no common prime factor (and m > 1). We can write n = q*m + r with 0 <= r < m (division with remainder, r = n % m), q is the integral part of the fraction and rather uninteresting.
Since the fraction was assumed reduced, we have r > 0, so we want to find the expansion of a fraction r / m where 0 < r < m and m is not divisible by 2 or by 5. As mentioned above, such an expansion is purely periodic, so finding the period means finding the complete expansion.
Let's go about finding the period heuristically. So let k be the length of the (shortest) period and p = d_1d1_2...d_k the period. So
r / m = 0.d_1d_2...d_kd_1d_2...d_kd_1...
= (d_1d_2...d_k)/(10^k) + (d_1d_2...d_k)/(10^(2k)) + (d_1d_2...d_k)/(10^(3k)) + ...
= p/(10^k) * (1 + 1/(10^k) + 1/(10^(2k)) + 1/(10^(3k)) + ...)
The last term is a geometric series, 1 + q + q^2 + q^3 + ... which, for |q| < 1 has the sum 1/(1-q).
In our case, 0 < q = 1/(10^k) < 1, so the sum is 1 / (1 - 1/(10^k)) = 10^k / (10^k-1). Thus we have seen that
r / m = p / (10^k-1)
Since r and m have no common factor, that means there is an s with 10^k - 1 = s*m and p = s*r. If we know k, the length of the period, we can simply find the digits of the period by calculating
p = ((10^k - 1)/m) * r
and padding with leading zeros until we have k digits. (Note: it is that simple only if k is sufficiently small or a big integer type is available. To calculate the period of for example 17/983 with standard fixed-width integer types, use long division as explained by #Patrick87.)
So it remains to find the length of the period. We can revert the reasoning above and find that if m divides 10^u - 1, then we can write
r / m = t/(10^u - 1) = t/(10^u) + t/(10^(2u)) + t/(10^(3u)) + ...
= 0.t_1t_2...t_ut_1t_2...t_ut_1...
and r/m has a period of length u. So the length of the shortest period is the minimal positive u such that m divides 10^u - 1, or, put another way, the smallest positive u such that 10^u % m == 1.
We can find it in O(m) time with
u = 0;
a = 1;
do {
++u;
a = (10*a) % m;
while(a != 1);
Now, finding the length of the period that way is not more efficient than finding the digits and length of the period together with long division, and for small enough m that is the most efficient method.
int[] long_division(int numerator, int denominator) {
if (numerator < 1 || numerator >= denominator) throw new IllegalArgumentException("Bad call");
// now we know 0 < numerator < denominator
if (denominator % 2 == 0 || denominator % 5 == 0) throw new IllegalArgumentException("Bad denominator");
// now we know we get a purely periodic expansion
int[] digits = new int[denominator];
int k = 0, n = numerator;
do {
n *= 10;
digits[k++] = n / denominator;
n = n % denominator;
}while(n != numerator);
int[] period = new int[k];
for(n = 0; n < k; ++n) {
period[n] = digits[n];
}
return period;
}
That works as long as 10*(denominator - 1) doesn't overflow, of course int could be a 32-bit or 64-bit integer as needed.
But for large denominators, that is inefficient, one can find the period length and also the period faster by considering the prime factorisation of the denominator. Regarding the period length,
If the denominator is a prime power, m = p^k, the period length of r/m is a divisor of (p-1) * p^(k-1)
If a and b are coprime and m = a * b, the period length of r/m is the least common multiple of the period lengths of 1/a and 1/b.
Taken together, the period length of r/m is a divisor of λ(m), where λ is the Carmichael function.
So to find the period length of r/m, find the prime factorisation of m and for all prime power factors p^k, find the period of 1/(p^k) - equivalently, the multiplicative order of 10 modulo p^k, which is known to be a divisor of (p-1) * p^(k-1). Since such numbers haven't many divisors, that is quickly done.
Then find the least common multiple of all these.
For the period itself (the digits), if a big integer type is available and the period isn't too long, the formula
p = (10^k - 1)/m * r
is a quick way to compute it. If the period is too long or no big integer type is available, efficiently computing the digits is messier, and off the top of my head I don't remember how exactly that is done.
One way would be to repeat the way that you do long division by hand, and keep note of the remainder at each stage. When the remainder repeats, the rest of the process must repeat as well. E.g. the digits of 1.0/7 are 0.1 remainder 3 then 0.14 remainder 2 then 0.142 remainder 6 then 0.1428 remainder 4 then 0.14285 remainder 5 then 0.142857 remainder 1 which is the 1 that starts it off again amd so you get 0.1428571 remainder 3 and it repeats again from there.
The long division algorithm is pretty good, so I have nothing to add there.
But note that your algorithm IsRepeatingDecimal may not work and is inneficient.
It will not work if your fraction is not irreductible, that is if there exists an integer larger than 1 that divides both your numerator and your denominator. For example, if you feed 7/14 then your algorithm will return true when it should return false.
To reduce your fraction, find the gcd between both numerator and denominator and divide both by this gcd.
If you assume that the fraction is irreducible, then your test
if (Numerator % Denominator == 0)
can simply be replaced with
if (Denominator == 1)
But that is still unnecessary since if Denominator is 1, then your list 'primes' is going to be empty and your algorithm will return false anyway.
Finally, calling MathAlgorithms.Primes(Denominator) is going to be expensive for large numbers and can be avoided. Indeed, all you need to do is divide your denominator by 5 (respectively 2) untill it is no longer divisible by 5 (resp. 2). If the end result is 1, then return false, otherwise return true.
I came here expecting to be able to copy & paste the code to do this, but it didn't exist. So after reading #Patrick87's answer, I went ahead and coded it up. I spent some time testing it thoroughly and giving things a nice name. I thought I would leave it here so others don't have to waste their time.
Features:
If the decimal terminates, it handles that. It calculates the period and puts that in a separate variable called period, in case you want to know the length of the reptend.
Limitations:
It will fail if the transient + reptend is longer than can be represented by a System.Decimal.
public static string FormatDecimalExpansion(RationalNumber value)
{
RationalNumber currentValue = value;
string decimalString = value.ToDecimal().ToString();
int currentIndex = decimalString.IndexOf('.');
Dictionary<RationalNumber, int> dict = new Dictionary<RationalNumber, int>();
while (!dict.ContainsKey(currentValue))
{
dict.Add(currentValue, currentIndex);
int rem = currentValue.Numerator % currentValue.Denominator;
int carry = rem * 10;
if (rem == 0) // Terminating decimal
{
return decimalString;
}
currentValue = new RationalNumber(carry, currentValue.Denominator);
currentIndex++;
}
int startIndex = dict[currentValue];
int endIndex = currentIndex;
int period = (endIndex - startIndex); // The period is the length of the reptend
if (endIndex >= decimalString.Length)
{
throw new ArgumentOutOfRangeException(nameof(value),
"The value supplied has a decimal expansion that is longer" +
$" than can be represented by value of type {nameof(System.Decimal)}.");
}
string transient = decimalString.Substring(0, startIndex);
string reptend = decimalString.Substring(startIndex, period);
return transient + $"({reptend})";
}
And for good measure, I will include my RationalNumber class.
Note: It inherits from IEquatable so that it works correctly with the dictionary:
public struct RationalNumber : IEquatable<RationalNumber>
{
public int Numerator;
public int Denominator;
public RationalNumber(int numerator, int denominator)
{
Numerator = numerator;
Denominator = denominator;
}
public decimal ToDecimal()
{
return Decimal.Divide(Numerator, Denominator);
}
public bool Equals(RationalNumber other)
{
return (Numerator == other.Numerator && Denominator == other.Denominator);
}
public override int GetHashCode()
{
return new Tuple<int, int>(Numerator, Denominator).GetHashCode();
}
public override string ToString()
{
return $"{Numerator}/{Denominator}";
}
}
Enjoy!

Categories

Resources