How can I generate a random BigInteger within a certain range? - c#

Consider this method that works well:
public static bool mightBePrime(int N) {
BigInteger a = rGen.Next (1, N-1);
return modExp (a, N - 1, N) == 1;
}
Now, in order to fulfill a requirement of the class I'm taking, mightBePrime must accept a BigInteger N, but that means that I need a different way to generate my random BigInteger a.
My first idea was to do something like BigInteger a = (N-1) * rGen.NextDouble (), but a BigInteger can't be multiplied by a double.
How can I generate a random BigInteger between 1 and N-1, where N is a BigInteger?

Paul suggested in a comment that I generate a number using random bytes, then throw it away if it's too big. Here's what I came up with (Marcel's answer + Paul's advice):
public static BigInteger RandomIntegerBelow(BigInteger N) {
byte[] bytes = N.ToByteArray ();
BigInteger R;
do {
random.NextBytes (bytes);
bytes [bytes.Length - 1] &= (byte)0x7F; //force sign bit to positive
R = new BigInteger (bytes);
} while (R >= N);
return R;
}
http://amirshenouda.wordpress.com/2012/06/29/implementing-rsa-c/ helped a little too.

Use the Random-Class
public BigInteger getRandom(int length){
Random random = new Random();
byte[] data = new byte[length];
random.NextBytes(data);
return new BigInteger(data);
}

The naive implementation will fail on average 64 times before finding a valid BigInteger within the specified range.
On the worst case, my implementation will retry on average only 0.5 times (read as: 50% of the times it will find a result on the first try).
Also, unlike with modular arithmetic, my implementation maintains a uniform distribution.
Explanation
We must generate a random BigInteger between min and max.
If min > max, we swap min with max
To simplify the implementation we shift our range from [min, max] to [0, max-min], this way we won't have to deal with the sign bit
We count how many bytes max contains (bytes.Length)
From the most significant bit, we count how many bits are 0 (zeroBits)
We generate a random sequence of bytes.Length bytes
We know that for our sequence to be < max, at least zeroBits bits from the most significant bit must be 0, so we use a zeroBitMask to set them with a single bit-to-bit & operation over the most significant byte, this will save a lot of time by reducing the change of generating a number out of our range
We check if the number we generated is > max, and if so we try again
We unshift the range back from [0, max-min] to [min, max] by adding min to our result
And we have our number. 😊
Implementation
public static BigInteger RandomInRange(RandomNumberGenerator rng, BigInteger min, BigInteger max)
{
if (min > max)
{
var buff = min;
min = max;
max = buff;
}
// offset to set min = 0
BigInteger offset = -min;
min = 0;
max += offset;
var value = randomInRangeFromZeroToPositive(rng, max) - offset;
return value;
}
private static BigInteger randomInRangeFromZeroToPositive(RandomNumberGenerator rng, BigInteger max)
{
BigInteger value;
var bytes = max.ToByteArray();
// count how many bits of the most significant byte are 0
// NOTE: sign bit is always 0 because `max` must always be positive
byte zeroBitsMask = 0b00000000;
var mostSignificantByte = bytes[bytes.Length - 1];
// we try to set to 0 as many bits as there are in the most significant byte, starting from the left (most significant bits first)
// NOTE: `i` starts from 7 because the sign bit is always 0
for (var i = 7; i >= 0; i--)
{
// we keep iterating until we find the most significant non-0 bit
if ((mostSignificantByte & (0b1 << i)) != 0)
{
var zeroBits = 7 - i;
zeroBitsMask = (byte)(0b11111111 >> zeroBits);
break;
}
}
do
{
rng.GetBytes(bytes);
// set most significant bits to 0 (because `value > max` if any of these bits is 1)
bytes[bytes.Length - 1] &= zeroBitsMask;
value = new BigInteger(bytes);
// `value > max` 50% of the times, in which case the fastest way to keep the distribution uniform is to try again
} while (value > max);
return value;
}
Test
using (var rng = RandomNumberGenerator.Create())
{
BigInteger min = 0;
BigInteger max = 5;
var attempts = 10000000;
var count = new int[(int)max + 1];
var sw = Stopwatch.StartNew();
for (var i = 0; i < attempts; i++)
{
var v = BigIntegerUtils.RandomInRange(rng, min, max);
count[(int)v]++;
}
var time = sw.Elapsed;
Console.WriteLine("Generated {0} big integers from {1} to {2} in {3}", attempts, min, max, time);
Console.WriteLine("On average: {0} ms/integer or {1} integers/second", time.TotalMilliseconds / attempts, attempts / time.TotalSeconds);
for (var i = 0; i <= max; i++)
Console.WriteLine("{0} generated {1}% of the times ({2} times)", i, count[i] * 100d / attempts, count[i]);
}
Test output on my i7-6500U:
Generated 10000000 big integers from 0 to 5 in 00:00:09.5413677
On average: 0.00095413677 ms/integer or 1048067.77334449 integers/second
0 generated 16.66633% of the times (1666633 times)
1 generated 16.6717% of the times (1667170 times)
2 generated 16.66373% of the times (1666373 times)
3 generated 16.6666% of the times (1666660 times)
4 generated 16.68271% of the times (1668271 times)
5 generated 16.64893% of the times (1664893 times)
Another test output on my i7-6500U
Generated 10000000 big integers from 0 to 10^100 in 00:00:17.5036570
On average: 0.0017503657 ms/integer or 571309.184132207 integers/second

Here is a NextBigInteger extension method for the Random class. It is based on the excellent Fabio Iotti's implementation, modified for succinctness.
/// <summary>
/// Returns a random BigInteger that is within a specified range.
/// The lower bound is inclusive, and the upper bound is exclusive.
/// </summary>
public static BigInteger NextBigInteger(this Random random,
BigInteger minValue, BigInteger maxValue)
{
if (minValue > maxValue) throw new ArgumentException();
if (minValue == maxValue) return minValue;
BigInteger zeroBasedUpperBound = maxValue - 1 - minValue; // Inclusive
Debug.Assert(zeroBasedUpperBound.Sign >= 0);
byte[] bytes = zeroBasedUpperBound.ToByteArray();
Debug.Assert(bytes.Length > 0);
Debug.Assert((bytes[bytes.Length - 1] & 0b10000000) == 0);
// Search for the most significant non-zero bit
byte lastByteMask = 0b11111111;
for (byte mask = 0b10000000; mask > 0; mask >>= 1, lastByteMask >>= 1)
{
if ((bytes[bytes.Length - 1] & mask) == mask) break; // We found it
}
while (true)
{
random.NextBytes(bytes);
bytes[bytes.Length - 1] &= lastByteMask;
var result = new BigInteger(bytes);
Debug.Assert(result.Sign >= 0);
if (result <= zeroBasedUpperBound) return result + minValue;
}
}
The percentage of BigInteger instances that are discarded, in order to return a value within the desirable range, is 30% on average (best case 0%, worst case 50%).
The distribution of random numbers is uniform.
Usage example:
Random random = new();
BigInteger value = random.NextBigInteger(BigInteger.Zero, new BigInteger(1000));
Note: The structure of the bytes returned from the BigInteger.ToByteArray is well documented (in the Remarks section), so it should be fairly safe to assume that the BigInteger's byte[] representation is not going to change in future versions of the .NET platform. In case that happened, the above NextBigInteger implementation could fail in nasty ways, like entering an infinite loop or generating numbers within a wrong range. I've added some debugging assertions that should never fail with the current representation, but the coverage of checking for invalid conditions is by no means thorough.

Here's an alternate way to generate numbers within range without throwing away values and allowing BigIntegers for min and max.
public BigInteger RandomBigInteger(BigInteger min, BigInteger max)
{
Random rnd = new Random();
string numeratorString, denominatorString;
double fraction = rnd.NextDouble();
BigInteger inRange;
//Maintain all 17 digits of precision,
//but remove the leading zero and the decimal point;
numeratorString = fraction.ToString("G17").Remove(0, 2);
//Use the length instead of 17 in case the random
//fraction ends with one or more zeros
denominatorString = string.Format("1E{0}", numeratorString.Length);
inRange = (max - min) * BigInteger.Parse(numeratorString) /
BigInteger.Parse(denominatorString,
System.Globalization.NumberStyles.AllowExponent)
+ min;
return inRange;
}
For generality you may want to specify precision as well. This seems to work.
public BigInteger RandomBigIntegerInRange(BigInteger min, BigInteger max, int precision)
{
Random rnd = new Random();
string numeratorString, denominatorString;
double fraction = rnd.NextDouble();
BigInteger inRange;
numeratorString = GenerateNumeratorWithSpecifiedPrecision(precision);
denominatorString = string.Format("1E{0}", numeratorString.Length);
inRange = (max - min) * BigInteger.Parse(numeratorString) / BigInteger.Parse(denominatorString, System.Globalization.NumberStyles.AllowExponent) + min;
return inRange;
}
private string GenerateNumeratorWithSpecifiedPrecision(int precision)
{
Random rnd = new Random();
string answer = string.Empty;
while(answer.Length < precision)
{
answer += rnd.NextDouble().ToString("G17").Remove(0, 2);
}
if (answer.Length > precision) //Most likely
{
answer = answer.Substring(0, precision);
}
return answer;
}

For my use case, I did the following:
Random rnd = new Random();
BigInteger myVal = rnd.NextBigInteger(50,100); //returns a 50-99 bit BigInteger
The code:
/// <summary>
/// Returns a random BigInteger with a minimum bit count between <paramref name="minBitLength"/>(inclusive) and <paramref name="maxBitLength"/>(exclusive).
/// </summary>
/// <param name="minBitLength">The inclusive lower bit length of the random BigInteger returned.</param>
/// <param name="maxBitLength">The exclusive upper bit length of the random BigInteger returned. <paramref name="maxBitLength"/> must be greater than or equal to minValue.</param>
public static BigInteger NextBigInteger(this Random rnd, int minBitLength, int maxBitLength)
{
if (minBitLength < 0) throw new ArgumentOutOfRangeException();
int bits = rnd.Next(minBitLength, maxBitLength);
if (bits == 0) return BigInteger.Zero;
byte[] bytes = new byte[(bits + 7) / 8];
rnd.NextBytes(bytes);
// For the top byte, place a leading 1-bit then downshift to achieve desired length.
bytes[^1] = (byte)((0x80 | bytes[^1]) >> (7 - (bits - 1) % 8));
return new BigInteger(bytes, true);
}
Example Results:
____Example Lengths___ ___Example Results___
NextBigInteger(0,0) ==> 0 0 0 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0
NextBigInteger(0,1) ==> 0 0 0 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0
NextBigInteger(0,2) ==> 1 1 1 0 1 0 0 1 0 0 1 | 1 1 1 1 0 1 0
NextBigInteger(0,3) ==> 2 2 2 1 2 0 0 0 1 0 2 | 0 1 0 2 0 1 2
NextBigInteger(0,4) ==> 3 2 0 3 0 0 0 3 1 3 3 | 0 1 1 0 3 1 0
NextBigInteger(0,5) ==> 1 4 1 2 4 1 2 0 3 1 2 | 1 1 10 10 14 11 8
NextBigInteger(0,6) ==> 3 5 1 1 5 5 3 5 1 4 3 | 0 0 1 3 2 7 27
NextBigInteger(1,1) ==> 1 1 1 1 1 1 1 1 1 1 1 | 1 1 1 1 1 1 1
NextBigInteger(1,2) ==> 1 1 1 1 1 1 1 1 1 1 1 | 1 1 1 1 1 1 1
NextBigInteger(1,3) ==> 2 1 2 1 2 2 2 2 1 1 1 | 1 1 1 1 2 2 3
NextBigInteger(1,4) ==> 1 2 3 3 2 1 1 2 2 2 1 | 7 3 1 1 6 1 5
NextBigInteger(1,5) ==> 4 3 1 2 3 1 4 4 1 1 3 | 1 3 1 6 6 12 7
NextBigInteger(1,6) ==> 5 5 4 1 1 2 3 2 1 1 1 | 1 28 7 5 25 15 13
NextBigInteger(2,2) ==> 2 2 2 2 2 2 2 2 2 2 2 | 2 2 3 2 3 2 3
NextBigInteger(2,3) ==> 2 2 2 2 2 2 2 2 2 2 2 | 2 2 3 2 2 3 3
NextBigInteger(2,4) ==> 3 3 2 3 3 3 3 3 3 2 3 | 3 2 7 6 3 3 3
NextBigInteger(2,5) ==> 2 4 2 2 4 4 2 2 4 3 2 | 6 3 13 2 6 4 11
NextBigInteger(2,6) ==> 5 3 5 3 2 3 2 4 4 5 3 | 2 3 17 2 27 14 18
NextBigInteger(3,3) ==> 3 3 3 3 3 3 3 3 3 3 3 | 4 4 5 7 6 7 4
NextBigInteger(3,4) ==> 3 3 3 3 3 3 3 3 3 3 3 | 6 5 4 7 6 4 6
NextBigInteger(3,5) ==> 3 3 3 3 4 4 4 4 3 4 4 | 6 10 12 6 6 15 7
NextBigInteger(3,6) ==> 4 4 3 3 3 4 3 5 4 3 4 | 28 22 5 11 25 8 6
NextBigInteger(4,4) ==> 4 4 4 4 4 4 4 4 4 4 4 | 12 8 8 9 8 10 13
NextBigInteger(4,5) ==> 4 4 4 4 4 4 4 4 4 4 4 | 15 10 10 8 14 8 13
NextBigInteger(4,6) ==> 5 5 5 5 4 5 5 4 5 5 5 | 15 13 14 31 19 15 21
Some Random Stuff:
One issue with many large random number generators is they can produce output that are all similar in scale to the maxValue. Example: if we had something like RandomBigIntegerUsingValues(min: 100, max:999999999999999) then 99% of our results will be between 9999999999999 and 999999999999999. The odds of getting something under 1000000 are 1 in 1000000000.
Some range checking is implicitly handled by the Random.Next().
Matched .net libraries extension methods as best as possible so the name NextBigInteger() was used since it matches Random's built-in NextSingle(), NextDouble(), NextInt64() naming. And also .net's Random signature was was used: minBitLength(inclusive), maxBitLength(exclusive).
Releasing under the MIT License.

The following Range method will return an IEnumerable<BigInteger> within the range you specify.
A simple Extension method will return a random element within the IEnumerable.
public static IEnumerable<BigInteger> Range(BigInteger from, BigInteger to)
{
for(BigInteger i = from; i < to; i++) yield return i;
}
public static class Extensions
{
public static BigInteger RandomElement(this IEnumerable<BigInteger> enumerable, Random rand)
{
int index = rand.Next(0, enumerable.Count());
return enumerable.ElementAt(index);
}
}
usage:
Random rnd = new Random();
var big = Range(new BigInteger(10000000000000000), new BigInteger(10000000000000020)).RandomElement(rnd);
// returns random values and in this case it was 10000000000000003

Related

Generating a for while foreach algorithm in c# with a pyramidal structure

I have been trying to get this to work for 3 days, and I feel like I'm using the wrong approach, if anyone can correct me I will wax your car. Background, client asked to me make a simple pyramid algorithm. I want to select add everything to a list of objects and make everything on the left side true and everything on the right side false. Every other line reads the line 2 lines prior and adds multiple entries. The first time it adds a number like 1 it's one time, then it adds two 1's for each 1 until there is 4. So the first time it enters a 1 on line 1, then on line 3 it adds a 1 two times, then on line 5 it reads from line 3 and adds each of those 1's 2 times.
Here is a visual representation.
|1|
|2| |3|
|1|1| |4|5|
|2|2|3|3| |6|7|8|9|
|1|1|1|1|4|4|5|5| |10|11|12|13|14|15|16|17|
|2|2|2|2|3|3|3|3|6|6|7|7|8|8|9|9| |18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33
The order this list would be is:
1|2|3|1|1|4|5|2|2|3|3|6|7|8|9|1|1|1|1|4|4|5|5|10|11|12|13|14|15|16|17...
I keep getting close, but it fails to generate the correct output. `
for (int i = 1; i < 50; i = i * 2)
{
Response.Write(i.ToString() + " - ");
var previousLevel = (i / 2 / 2);
foreach (var oc in infoRows.Where(x => x.level == previousLevel))
{
for (int p = i; p > 0; p--)
{
Response.Write(oc.id + "*");
}
}
while (level <= i)
{
for (int r = 1; r <= i; r++)
{
InfoRow tempInforow = new InfoRow();
tempInforow.customerCode = GenerateCustomerNumber(position);
tempInforow.id = customerId;
tempInforow.sendtoidnumber = level.ToString();
tempInforow.status = 0; // GetStatus(position, totalCount);
tempInforow.position = position;
tempInforow.level = i;
infoRows.Add(tempInforow);
customerId++;
position++;
Response.Write(tempInforow.id + "-");
level++;
}
}
}
`
Essentially this generates the following:
1 - 1-
2 - 2-3-
4 - 1*1*1*1*4-5-6-7-
8 - 2*2*2*2*2*2*2*2*3*3*3*3*3*3*3*3*8-9-10-11-12-13-14-15-
16 - 4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*6*6*6*6*6*6*6*6*6*6*6*6*6*6*6*6*7*7*7*7*7*7*7*7*7*7*7*7*7*7*7*7*16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-
32 -
I've tried 30 different ways with switch statements, while statements, for and foreach statements, the closest I can get to this working is level 4.
Can someone suggest another way. Maybe a multidimensional array or idk what. Thank you.
Let's write the sequence down and have a look on what's going on:
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ...
seq 1 2 3 1 1 4 5 2 2 3 3 6 7 8 9 1 1 1 1 4 4 5 5 10 ...
^ ^ ^ ^ ^ ^
| |
if # is power of 2 (e.g. 8 == 2**3)
we should copy and double # / 4 items (here 8 / 4 == 2 items)
starting from # / 4 item (here 8 / 4 == 2, starting from item #2)
Time to implement this algorithm
Code:
using System.Linq;
...
private static List<int> Pyramid(int size) {
if (size < 0)
throw new ArgumentOutOfRangeException(nameof(size));
if (size <= 3)
return Enumerable.Range(1, size).ToList();
List<int> result = new List<int>(size) { 1, 2, 3 };
for (int value = 4; result.Count < size; )
if (BitOperations.IsPow2(result.Count + 1)) {
int chunk = (result.Count + 1) / 4;
for (int i = 0; i < chunk && result.Count < size; ++i) {
result.Add(result[chunk - 1 + i]);
if (result.Count >= size)
return result;
result.Add(result[chunk - 1 + i]);
}
}
else
result.Add(value++);
return result;
}
Demo:
// First 31 items from the pyramid
Console.Write(string.Join("|", Pyramid(31)));
Output:
1|2|3|1|1|4|5|2|2|3|3|6|7|8|9|1|1|1|1|4|4|5|5|10|11|12|13|14|15|16|17

Identify Sequence and Provide 4th Integer

I was tasked to solve this challenge on a programming exam, but I'm not sure that I have properly solved it. I am inquisitive about what really is the solution to this task:
Make an application that will tell the user to input 3 numbers, identify the sequence, and provide the 4th integer. It should prompt if no relations is found
Note: Possible operators may include addition, subtraction, multiplication, division, exponent, and modulo division.
Sample Output:
2, 4, 6, 8
10, 9, 7, 4
1, 4, 9, 16
1, 1, 2, 6
120, 120, 60, 20
Here is my solution so far:
using System;
using System.IO;
namespace TestQuestionnaire
{
class Program
{
static void Main(string[] args)
{
var numbers = new int[3];
string answer;
bool exit = false;
while (!exit)
{
// Loop for 5 times
for (int n = 0; n <= 5; n++)
{
// User Input
Console.WriteLine("Please Enter 3 Numbers.");
for (var i = 0; i < numbers.Length; i++)
{
var error = false;
while (!error)
{
Console.Write("Enter Number: ");
error = int.TryParse(Console.ReadLine(), out numbers[i]);
if (!error) Console.WriteLine("Invalid Number! Enter a Valid Number and Try Again. ");
}
}
NextNumber(numbers);
}
// Prompt for exit
Console.WriteLine("Finished! Try Again? Y/N");
answer = Console.ReadLine()?.ToUpper();
if (answer == "N")
{
exit = true;
}
}
}
private static void NextNumber(int[] numbers)
{
int next = 0;
int interval_one = 0;
int interval_two = 0;
// determine if first two number is descending, ascending or equal (addition and subtraction)
if (numbers[0] < numbers[1])
{
interval_one = (numbers[1] - numbers[0]);
if (numbers[1] > numbers[2])
{
interval_two = (numbers[1] - numbers[2]);
}
else
{
interval_two = (numbers[2] - numbers[1]);
}
//determine if constant interval (eg, 2,4,6,8 or 1,2,3,4) otherwise evaluate more
if (interval_one == interval_two)
{
next = numbers[2] + interval_two;
}
else
{
next = numbers[2] + interval_two + (interval_two - interval_one);
}
}
else if (numbers[0] > numbers[1])
{
interval_one = numbers[0] - numbers[1];
if (numbers[1] > numbers[2])
{
interval_two = (numbers[1] - numbers[2]);
}
else
{
interval_two = (numbers[2] - numbers[1]);
}
if (interval_one == interval_two)
{
next = numbers[2] - interval_two;
}
else
{
next = numbers[2] - interval_two + (interval_one - interval_two);
}
}
else
{
if (numbers[0]/1 == numbers[1] && numbers[1]/2 == numbers [2])
{
next = numbers[2] / 3;
}
else if (numbers[0] * 1 == numbers[1] && numbers[1]*2 == numbers[2])
{
next = numbers[2] * 3;
}
}
Console.WriteLine("Predicted 4th Number: {0}", next);
}
}
}
Thanks!
I just have an Idea but I hope this can help
using +
2 4 6 8
2 2 2
10 9 7 4
1 2 3
1 1
1 4 9 16
3 5 7
2 2
diffrent way(*)
1 1 2 6
1 2 3# now +
1 1
use '/'
120 120 60 20
1 2 3# use +
1 1
There is no way to recognize all sequences of numbers, as each is defined by a very different relation. You would essentially have to hardcode each case as listed in the examples. And even then, there is no one correct answer. For your fourth example, I could see the sequence 1 1 2 2 3 3... being just as reasonable as 1 1 2 6.... In fact, the Online Encyclopedia of Integer Sequences finds 35,000 results for the the sequence 1 1 2 (see https://oeis.org/search?q=1%2C1%2C2&sort=&language=english&go=Search)
Putting that aside though, I'll give some pseudocode for the examples (I'm assuming, given that you are fine with Python or C#, that the language itself is not particularly important, and that you probably already know how to do the "getting input" and "returning results" portions.).
if the difference between each number is equal, add that difference to the last number and return it
if the difference between each number is the sequence 1 2 3..., return the last number plus the next difference (4 in this case)
If the numbers are the squares, return the next square (16 in this case)
If each number divided by the previous number is the sequence 1 2 3, return 4 * the last number
If each number divided by the next number is the sequence 1 2 3, return the last number divided by 4.
Of course, a more robust solution would account for negative sequences, or those that bounce back and forth between positive and negative. But again, it is an underdetermined problem.

Separate digits from integer (without string functions)

I have an integer with only two digits, let's say n = 52, i want to be able to separate these two digits, like 5 and 2.
Left Digit:
int left = (n / 10);
This gives me left = 5 for n = 52.
Right Digit:
int right = (int)(((n / 10f) - (n / 10)) * 10)
Error
The left digit is always true, but the right digits are sometimes right and sometimes wrong, and here are the test cases:
1. 29, 48 , 10 , 50 : Correct
2. 52 : Wrong, gives 5 , 1
3. 99 : Wrong, gives 9 , 8
4. 26 : Wrong, gives 2 , 5
int n = 52 ;
Solution 1 :
int left =int.Parse( n.toString().Substring(0,1)) ;
int right =int.Parse( n.toString().Substring(1,1)) ;
Solution 2 :
int left = n / 10 ;
int right = n % 10 ;

Binding Variable Nested List to GridView

I am trying to make a multiplication table appear on a page based on input from the user. This is my code:
<asp:GridView runat="server" ID="TableData"></asp:GridView>
List<List<int>> nestedList = new List<List<int>>();
protected void LoadTable(int val)
{
for (int y = 0; y <= val; y++)
{
List<int> list = new List<int>();
for (int x = 0; x <= val; x++)
list.Add(x * y);
nestedList.Add(list);
}
TableData.DataSource = nestedList;
TableData.DataBind();
}
But this displays as:
Capacity Count
16 14
16 14
16 14
16 14
16 14
16 14
16 14
16 14
16 14
16 14
16 14
16 14
16 14
16 14
What am I doing wrong?
For clarification, if the user enters 5, the output should be:
0 0 0 0 0 0
0 1 2 3 4 5
0 2 4 6 8 10
0 3 6 9 12 15
0 4 8 12 16 20
0 5 10 15 20 25
I am not worried about column or row headers at this time.
The problem is with your items Source.
a list< list < ?? > > is not a good choice (as i think).
For a Linear view you can use this approach
Code Snippet
var objList = new List<object>();
for (int i = 0; i < 5; i++)
{
var temp = new { operation = string.Format("{0} * {1}", i, i + 1), result = i * (i + 1) };
objList.Add(temp);
}
GridView does not support 2d list binding, consider using another methode.
For exemple, use a simple List , each string will represent a row, you can fill up each string by using a loop that goes like :
(first loop)
{
string s;
for(int x = 0; x < val; x ++)
{
s += (x * y).Tostring() + " ");
}
nestedList.Add(s);
}

% (mod) explanation

Today I was writing a program in C#, and I used % to calculate some index... My program didn't work, so I debugged it and I realized that "%" is not working like in other program languages that I know.
For example:
In Python % returns values like this:
for x in xrange (-5, 6):
print x, "% 5 =", x % 5
-5 % 5 = 0
-4 % 5 = 1
-3 % 5 = 2
-2 % 5 = 3
-1 % 5 = 4
0 % 5 = 0
1 % 5 = 1
2 % 5 = 2
3 % 5 = 3
4 % 5 = 4
5 % 5 = 0
In C#:
for (int i = -5; i < 6; i++)
{
Console.WriteLine(i + " % 5 = " + i % 5);
}
-5 % 5 = 0
-4 % 5 = -4
-3 % 5 = -3
-2 % 5 = -2
-1 % 5 = -1
0 % 5 = 0
1 % 5 = 1
2 % 5 = 2
3 % 5 = 3
4 % 5 = 4
5 % 5 = 0
Did I do something wrong or is % not working like it should?
As explained in the comments, the different behaviour is by design. The different languages just ascribe different meanings to the % operator.
You ask:
How can I use modulus operator in C#?
You can define a modulus operator yourself that behaves the same way as the Python % operator:
int mod(int a, int n)
{
int result = a % n;
if ((result<0 && n>0) || (result>0 && n<0)) {
result += n;
}
return result;
}
Both answers are correct. Although personally I think the "always positive" one makes more sense.
You can define your own modulus function that only gives positive answers like this:
int mod(int a, int n) {
return ((a%n)+n) % n;
}
In modular arithmetic, one defines classes of numbers based on the modulo. In other words, in modulo m arithmetic, a number n is equivalent (read: the same) to n + m, n - m, n + 2m, n - 2m, etc.
One defines m "baskets" and every number falls in one (and only one) of them.
Example: one can say "It's 4:30 pm" or one can say "It's 16:30". Both forms mean exactly the same time, but are different representations of it.
Thus both, the Python and C# results are correct! The numbers are the same in the modulo 5 arithmetic you chose. It would also have been mathematically correct to return (5, 6, 7, 8, 9) for example. Just a bit odd.
As for the choice of representation (in other words, the choice on how to represent negative numbers), that is just a case of different design choices between the two languages.
However, that is not at all what the % operator actually does in C#. The % operator is not the canonical modulus operator; it is the remainder operator. The A % B operator actually answer the question "If I divided A by B using integer arithmetic, what would the remainder be?"
— What's the difference? Remainder vs Modulus by Eric Lippert
Quick snippet to get the canonical modulus:
return ((n % m) + m) % m;
Test implementation:
Mono/C#:
machine:~ user$ cat mod.cs
using System;
public class Program
{
public static void Main (string[] args)
{
Console.WriteLine(Mod(-2, 5));
Console.WriteLine(Mod(-5, 5));
Console.WriteLine(Mod(-2, -5));
}
public static int Mod (int n, int m)
{
return ((n % m) + m) % m;
}
}
machine:~ user$ mono mod.exe
3
0
-2
Python:
machine:~ user$ cat mod.py
print -2%5;
print -5%5;
print -2%-5;
machine:~ user$ python mod.py
3
0
-2

Categories

Resources