本博客所有文章分类的总目录:【总目录】本博客博文总目录-实时更新
开源Math.NET基础数学类库使用总目录:【目录】开源Math.NET基础数学类库使用总目录
前言
数论就是指研究整数性质的一门理论。数论=算术。不过通常算术指数的计算,数论指数的理论。整数的基本元素是素数,所以数论的本质是对素数性质的研究。它是与平面几何同样历史悠久的学科。它大致包括代数数论、解析数论、计算数论等等。
Math.NET也包括了很多数论相关的函数,这些函数都是静态的,可以直接调用,如判断是否奇数,判断幂,平方数,最大公约数等等。同时部分函数已经作为扩展方法,可以直接在对象中使用。
如果本文资源或者显示有问题,请参考 本文原文地址:http://www.cnblogs.com/asxinyu/p/4301097.html
1.数论函数类Euclid
Math.NET包括的数论函数除了一部分大家日常接触到的,奇数,偶数,幂,平方数,最大公约数,最小公倍数等函数,还有一些欧几里得几何的函数,当然也是比较简单的,这些问题的算法有一些比较简单,如最大公约数,最小公倍数等,都有成熟的算法可以使用,对于使用Math.NET的人来说,不必要了解太小,当然对于需要搞清楚原理的人来说,学习Math.NET的架构或者实现,是可以参考的。所以这里先给出Math.NET关于数论函数类Euclid的源代码:
1 /// <summary>
2 /// 整数数论函数
3 /// Integer number theory functions.
4 /// </summary>
5 public static class Euclid
6 {
7 /// <summary>
8 /// Canonical Modulus. The result has the sign of the divisor.
9 /// </summary>
10 public static double Modulus(double dividend, double divisor)
11 {
12 return ((dividend%divisor) + divisor)%divisor;
13 }
14
15 /// <summary>
16 /// Canonical Modulus. The result has the sign of the divisor.
17 /// </summary>
18 public static float Modulus(float dividend, float divisor)
19 {
20 return ((dividend%divisor) + divisor)%divisor;
21 }
22
23 /// <summary>
24 /// Canonical Modulus. The result has the sign of the divisor.
25 /// </summary>
26 public static int Modulus(int dividend, int divisor)
27 {
28 return ((dividend%divisor) + divisor)%divisor;
29 }
30
31 /// <summary>
32 /// Canonical Modulus. The result has the sign of the divisor.
33 /// </summary>
34 public static long Modulus(long dividend, long divisor)
35 {
36 return ((dividend%divisor) + divisor)%divisor;
37 }
38
39 #if !NOSYSNUMERICS
40 /// <summary>
41 /// Canonical Modulus. The result has the sign of the divisor.
42 /// </summary>
43 public static BigInteger Modulus(BigInteger dividend, BigInteger divisor)
44 {
45 return ((dividend%divisor) + divisor)%divisor;
46 }
47 #endif
48
49 /// <summary>
50 /// Remainder (% operator). The result has the sign of the dividend.
51 /// </summary>
52 public static double Remainder(double dividend, double divisor)
53 {
54 return dividend%divisor;
55 }
56
57 /// <summary>
58 /// Remainder (% operator). The result has the sign of the dividend.
59 /// </summary>
60 public static float Remainder(float dividend, float divisor)
61 {
62 return dividend%divisor;
63 }
64
65 /// <summary>
66 /// Remainder (% operator). The result has the sign of the dividend.
67 /// </summary>
68 public static int Remainder(int dividend, int divisor)
69 {
70 return dividend%divisor;
71 }
72
73 /// <summary>
74 /// Remainder (% operator). The result has the sign of the dividend.
75 /// </summary>
76 public static long Remainder(long dividend, long divisor)
77 {
78 return dividend%divisor;
79 }
80
81 #if !NOSYSNUMERICS
82 /// <summary>
83 /// Remainder (% operator). The result has the sign of the dividend.
84 /// </summary>
85 public static BigInteger Remainder(BigInteger dividend, BigInteger divisor)
86 {
87 return dividend%divisor;
88 }
89 #endif
90
91 /// <summary>
92 /// Find out whether the provided 32 bit integer is an even number.
93 /// </summary>
94 /// <param name="number">The number to very whether it's even.</param>
95 /// <returns>True if and only if it is an even number.</returns>
96 public static bool IsEven(this int number)
97 {
98 return (number & 0x1) == 0x0;
99 }
100
101 /// <summary>
102 /// Find out whether the provided 64 bit integer is an even number.
103 /// </summary>
104 /// <param name="number">The number to very whether it's even.</param>
105 /// <returns>True if and only if it is an even number.</returns>
106 public static bool IsEven(this long number)
107 {
108 return (number & 0x1) == 0x0;
109 }
110
111 /// <summary>
112 /// Find out whether the provided 32 bit integer is an odd number.
113 /// </summary>
114 /// <param name="number">The number to very whether it's odd.</param>
115 /// <returns>True if and only if it is an odd number.</returns>
116 public static bool IsOdd(this int number)
117 {
118 return (number & 0x1) == 0x1;
119 }
120
121 /// <summary>
122 /// Find out whether the provided 64 bit integer is an odd number.
123 /// </summary>
124 /// <param name="number">The number to very whether it's odd.</param>
125 /// <returns>True if and only if it is an odd number.</returns>
126 public static bool IsOdd(this long number)
127 {
128 return (number & 0x1) == 0x1;
129 }
130
131 /// <summary>
132 /// Find out whether the provided 32 bit integer is a perfect power of two.
133 /// </summary>
134 /// <param name="number">The number to very whether it's a power of two.</param>
135 /// <returns>True if and only if it is a power of two.</returns>
136 public static bool IsPowerOfTwo(this int number)
137 {
138 return number > 0 && (number & (number - 1)) == 0x0;
139 }
140
141 /// <summary>
142 /// Find out whether the provided 64 bit integer is a perfect power of two.
143 /// </summary>
144 /// <param name="number">The number to very whether it's a power of two.</param>
145 /// <returns>True if and only if it is a power of two.</returns>
146 public static bool IsPowerOfTwo(this long number)
147 {
148 return number > 0 && (number & (number - 1)) == 0x0;
149 }
150
151 /// <summary>
152 /// Find out whether the provided 32 bit integer is a perfect square, i.e. a square of an integer.
153 /// </summary>
154 /// <param name="number">The number to very whether it's a perfect square.</param>
155 /// <returns>True if and only if it is a perfect square.</returns>
156 public static bool IsPerfectSquare(this int number)
157 {
158 if (number < 0)
159 {
160 return false;
161 }
162
163 int lastHexDigit = number & 0xF;
164 if (lastHexDigit > 9)
165 {
166 return false; // return immediately in 6 cases out of 16.
167 }
168
169 if (lastHexDigit == 0 || lastHexDigit == 1 || lastHexDigit == 4 || lastHexDigit == 9)
170 {
171 int t = (int)Math.Floor(Math.Sqrt(number) + 0.5);
172 return (t * t) == number;
173 }
174
175 return false;
176 }
177
178 /// <summary>
179 /// Find out whether the provided 64 bit integer is a perfect square, i.e. a square of an integer.
180 /// </summary>
181 /// <param name="number">The number to very whether it's a perfect square.</param>
182 /// <returns>True if and only if it is a perfect square.</returns>
183 public static bool IsPerfectSquare(this long number)
184 {
185 if (number < 0)
186 {
187 return false;
188 }
189
190 int lastHexDigit = (int)(number & 0xF);
191 if (lastHexDigit > 9)
192 {
193 return false; // return immediately in 6 cases out of 16.
194 }
195
196 if (lastHexDigit == 0 || lastHexDigit == 1 || lastHexDigit == 4 || lastHexDigit == 9)
197 {
198 long t = (long)Math.Floor(Math.Sqrt(number) + 0.5);
199 return (t * t) == number;
200 }
201
202 return false;
203 }
204
205 /// <summary>
206 /// Raises 2 to the provided integer exponent (0 <= exponent < 31).
207 /// </summary>
208 /// <param name="exponent">The exponent to raise 2 up to.</param>
209 /// <returns>2 ^ exponent.</returns>
210 /// <exception cref="ArgumentOutOfRangeException"/>
211 public static int PowerOfTwo(this int exponent)
212 {
213 if (exponent < 0 || exponent >= 31)
214 {
215 throw new ArgumentOutOfRangeException("exponent");
216 }
217
218 return 1 << exponent;
219 }
220
221 /// <summary>
222 /// Raises 2 to the provided integer exponent (0 <= exponent < 63).
223 /// </summary>
224 /// <param name="exponent">The exponent to raise 2 up to.</param>
225 /// <returns>2 ^ exponent.</returns>
226 /// <exception cref="ArgumentOutOfRangeException"/>
227 public static long PowerOfTwo(this long exponent)
228 {
229 if (exponent < 0 || exponent >= 63)
230 {
231 throw new ArgumentOutOfRangeException("exponent");
232 }
233
234 return ((long)1) << (int)exponent;
235 }
236
237 /// <summary>
238 /// Find the closest perfect power of two that is larger or equal to the provided
239 /// 32 bit integer.
240 /// </summary>
241 /// <param name="number">The number of which to find the closest upper power of two.</param>
242 /// <returns>A power of two.</returns>
243 /// <exception cref="ArgumentOutOfRangeException"/>
244 public static int CeilingToPowerOfTwo(this int number)
245 {
246 if (number == Int32.MinValue)
247 {
248 return 0;
249 }
250
251 const int maxPowerOfTwo = 0x40000000;
252 if (number > maxPowerOfTwo)
253 {
254 throw new ArgumentOutOfRangeException("number");
255 }
256
257 number--;
258 number |= number >> 1;
259 number |= number >> 2;
260 number |= number >> 4;
261 number |= number >> 8;
262 number |= number >> 16;
263 return number + 1;
264 }
265
266 /// <summary>
267 /// Find the closest perfect power of two that is larger or equal to the provided
268 /// 64 bit integer.
269 /// </summary>
270 /// <param name="number">The number of which to find the closest upper power of two.</param>
271 /// <returns>A power of two.</returns>
272 /// <exception cref="ArgumentOutOfRangeException"/>
273 public static long CeilingToPowerOfTwo(this long number)
274 {
275 if (number == Int64.MinValue)
276 {
277 return 0;
278 }
279
280 const long maxPowerOfTwo = 0x4000000000000000;
281 if (number > maxPowerOfTwo)
282 {
283 throw new ArgumentOutOfRangeException("number");
284 }
285
286 number--;
287 number |= number >> 1;
288 number |= number >> 2;
289 number |= number >> 4;
290 number |= number >> 8;
291 number |= number >> 16;
292 number |= number >> 32;
293 return number + 1;
294 }
295
296 /// <summary>
297 /// Returns the greatest common divisor (<c>gcd</c>) of two integers using Euclid's algorithm.
298 /// </summary>
299 /// <param name="a">First Integer: a.</param>
300 /// <param name="b">Second Integer: b.</param>
301 /// <returns>Greatest common divisor <c>gcd</c>(a,b)</returns>
302 public static long GreatestCommonDivisor(long a, long b)
303 {
304 while (b != 0)
305 {
306 var remainder = a%b;
307 a = b;
308 b = remainder;
309 }
310
311 return Math.Abs(a);
312 }
313
314 /// <summary>
315 /// Returns the greatest common divisor (<c>gcd</c>) of a set of integers using Euclid's
316 /// algorithm.
317 /// </summary>
318 /// <param name="integers">List of Integers.</param>
319 /// <returns>Greatest common divisor <c>gcd</c>(list of integers)</returns>
320 public static long GreatestCommonDivisor(IList<long> integers)
321 {
322 if (null == integers)
323 {
324 throw new ArgumentNullException("integers");
325 }
326
327 if (integers.Count == 0)
328 {
329 return 0;
330 }
331
332 var gcd = Math.Abs(integers[0]);
333
334 for (var i = 1; (i < integers.Count) && (gcd > 1); i++)
335 {
336 gcd = GreatestCommonDivisor(gcd, integers[i]);
337 }
338
339 return gcd;
340 }
341
342 /// <summary>
343 /// Returns the greatest common divisor (<c>gcd</c>) of a set of integers using Euclid's algorithm.
344 /// </summary>
345 /// <param name="integers">List of Integers.</param>
346 /// <returns>Greatest common divisor <c>gcd</c>(list of integers)</returns>
347 public static long GreatestCommonDivisor(params long[] integers)
348 {
349 return GreatestCommonDivisor((IList<long>)integers);
350 }
351
352 /// <summary>
353 /// Computes the extended greatest common divisor, such that a*x + b*y = <c>gcd</c>(a,b).
354 /// </summary>
355 /// <param name="a">First Integer: a.</param>
356 /// <param name="b">Second Integer: b.</param>
357 /// <param name="x">Resulting x, such that a*x + b*y = <c>gcd</c>(a,b).</param>
358 /// <param name="y">Resulting y, such that a*x + b*y = <c>gcd</c>(a,b)</param>
359 /// <returns>Greatest common divisor <c>gcd</c>(a,b)</returns>
360 /// <example>
361 /// <code>
362 /// long x,y,d;
363 /// d = Fn.GreatestCommonDivisor(45,18,out x, out y);
364 /// -> d == 9 && x == 1 && y == -2
365 /// </code>
366 /// The <c>gcd</c> of 45 and 18 is 9: 18 = 2*9, 45 = 5*9. 9 = 1*45 -2*18, therefore x=1 and y=-2.
367 /// </example>
368 public static long ExtendedGreatestCommonDivisor(long a, long b, out long x, out long y)
369 {
370 long mp = 1, np = 0, m = 0, n = 1;
371
372 while (b != 0)
373 {
374 long rem;
375 #if PORTABLE
376 rem = a % b;
377 var quot = a / b;
378 #else
379 long quot = Math.DivRem(a, b, out rem);
380 #endif
381 a = b;
382 b = rem;
383
384 var tmp = m;
385 m = mp - (quot*m);
386 mp = tmp;
387
388 tmp = n;
389 n = np - (quot*n);
390 np = tmp;
391 }
392
393 if (a >= 0)
394 {
395 x = mp;
396 y = np;
397 return a;
398 }
399
400 x = -mp;
401 y = -np;
402 return -a;
403 }
404
405 /// <summary>
406 /// Returns the least common multiple (<c>lcm</c>) of two integers using Euclid's algorithm.
407 /// </summary>
408 /// <param name="a">First Integer: a.</param>
409 /// <param name="b">Second Integer: b.</param>
410 /// <returns>Least common multiple <c>lcm</c>(a,b)</returns>
411 public static long LeastCommonMultiple(long a, long b)
412 {
413 if ((a == 0) || (b == 0))
414 {
415 return 0;
416 }
417
418 return Math.Abs((a/GreatestCommonDivisor(a, b))*b);
419 }
420
421 /// <summary>
422 /// Returns the least common multiple (<c>lcm</c>) of a set of integers using Euclid's algorithm.
423 /// </summary>
424 /// <param name="integers">List of Integers.</param>
425 /// <returns>Least common multiple <c>lcm</c>(list of integers)</returns>
426 public static long LeastCommonMultiple(IList<long> integers)
427 {
428 if (null == integers)
429 {
430 throw new ArgumentNullException("integers");
431 }
432
433 if (integers.Count == 0)
434 {
435 return 1;
436 }
437
438 var lcm = Math.Abs(integers[0]);
439
440 for (var i = 1; i < integers.Count; i++)
441 {
442 lcm = LeastCommonMultiple(lcm, integers[i]);
443 }
444
445 return lcm;
446 }
447
448 /// <summary>
449 /// Returns the least common multiple (<c>lcm</c>) of a set of integers using Euclid's algorithm.
450 /// </summary>
451 /// <param name="integers">List of Integers.</param>
452 /// <returns>Least common multiple <c>lcm</c>(list of integers)</returns>
453 public static long LeastCommonMultiple(params long[] integers)
454 {
455 return LeastCommonMultiple((IList<long>)integers);
456 }
457
458 #if !NOSYSNUMERICS
459 /// <summary>
460 /// Returns the greatest common divisor (<c>gcd</c>) of two big integers.
461 /// </summary>
462 /// <param name="a">First Integer: a.</param>
463 /// <param name="b">Second Integer: b.</param>
464 /// <returns>Greatest common divisor <c>gcd</c>(a,b)</returns>
465 public static BigInteger GreatestCommonDivisor(BigInteger a, BigInteger b)
466 {
467 return BigInteger.GreatestCommonDivisor(a, b);
468 }
469
470 /// <summary>
471 /// Returns the greatest common divisor (<c>gcd</c>) of a set of big integers.
472 /// </summary>
473 /// <param name="integers">List of Integers.</param>
474 /// <returns>Greatest common divisor <c>gcd</c>(list of integers)</returns>
475 public static BigInteger GreatestCommonDivisor(IList<BigInteger> integers)
476 {
477 if (null == integers)
478 {
479 throw new ArgumentNullException("integers");
480 }
481
482 if (integers.Count == 0)
483 {
484 return 0;
485 }
486
487 var gcd = BigInteger.Abs(integers[0]);
488
489 for (int i = 1; (i < integers.Count) && (gcd > BigInteger.One); i++)
490 {
491 gcd = GreatestCommonDivisor(gcd, integers[i]);
492 }
493
494 return gcd;
495 }
496
497 /// <summary>
498 /// Returns the greatest common divisor (<c>gcd</c>) of a set of big integers.
499 /// </summary>
500 /// <param name="integers">List of Integers.</param>
501 /// <returns>Greatest common divisor <c>gcd</c>(list of integers)</returns>
502 public static BigInteger GreatestCommonDivisor(params BigInteger[] integers)
503 {
504 return GreatestCommonDivisor((IList<BigInteger>)integers);
505 }
506
507 /// <summary>
508 /// Computes the extended greatest common divisor, such that a*x + b*y = <c>gcd</c>(a,b).
509 /// </summary>
510 /// <param name="a">First Integer: a.</param>
511 /// <param name="b">Second Integer: b.</param>
512 /// <param name="x">Resulting x, such that a*x + b*y = <c>gcd</c>(a,b).</param>
513 /// <param name="y">Resulting y, such that a*x + b*y = <c>gcd</c>(a,b)</param>
514 /// <returns>Greatest common divisor <c>gcd</c>(a,b)</returns>
515 /// <example>
516 /// <code>
517 /// long x,y,d;
518 /// d = Fn.GreatestCommonDivisor(45,18,out x, out y);
519 /// -> d == 9 && x == 1 && y == -2
520 /// </code>
521 /// The <c>gcd</c> of 45 and 18 is 9: 18 = 2*9, 45 = 5*9. 9 = 1*45 -2*18, therefore x=1 and y=-2.
522 /// </example>
523 public static BigInteger ExtendedGreatestCommonDivisor(BigInteger a, BigInteger b, out BigInteger x, out BigInteger y)
524 {
525 BigInteger mp = BigInteger.One, np = BigInteger.Zero, m = BigInteger.Zero, n = BigInteger.One;
526
527 while (!b.IsZero)
528 {
529 BigInteger rem;
530 BigInteger quot = BigInteger.DivRem(a, b, out rem);
531 a = b;
532 b = rem;
533
534 BigInteger tmp = m;
535 m = mp - (quot*m);
536 mp = tmp;
537
538 tmp = n;
539 n = np - (quot*n);
540 np = tmp;
541 }
542
543 if (a >= BigInteger.Zero)
544 {
545 x = mp;
546 y = np;
547 return a;
548 }
549
550 x = -mp;
551 y = -np;
552 return -a;
553 }
554
555 /// <summary>
556 /// Returns the least common multiple (<c>lcm</c>) of two big integers.
557 /// </summary>
558 /// <param name="a">First Integer: a.</param>
559 /// <param name="b">Second Integer: b.</param>
560 /// <returns>Least common multiple <c>lcm</c>(a,b)</returns>
561 public static BigInteger LeastCommonMultiple(BigInteger a, BigInteger b)
562 {
563 if (a.IsZero || b.IsZero)
564 {
565 return BigInteger.Zero;
566 }
567
568 return BigInteger.Abs((a/BigInteger.GreatestCommonDivisor(a, b))*b);
569 }
570
571 /// <summary>
572 /// Returns the least common multiple (<c>lcm</c>) of a set of big integers.
573 /// </summary>
574 /// <param name="integers">List of Integers.</param>
575 /// <returns>Least common multiple <c>lcm</c>(list of integers)</returns>
576 public static BigInteger LeastCommonMultiple(IList<BigInteger> integers)
577 {
578 if (null == integers)
579 {
580 throw new ArgumentNullException("integers");
581 }
582
583 if (integers.Count == 0)
584 {
585 return 1;
586 }
587
588 var lcm = BigInteger.Abs(integers[0]);
589
590 for (int i = 1; i < integers.Count; i++)
591 {
592 lcm = LeastCommonMultiple(lcm, integers[i]);
593 }
594
595 return lcm;
596 }
597
598 /// <summary>
599 /// Returns the least common multiple (<c>lcm</c>) of a set of big integers.
600 /// </summary>
601 /// <param name="integers">List of Integers.</param>
602 /// <returns>Least common multiple <c>lcm</c>(list of integers)</returns>
603 public static BigInteger LeastCommonMultiple(params BigInteger[] integers)
604 {
605 return LeastCommonMultiple((IList<BigInteger>)integers);
606 }
607 #endif
608 }
2.Euclid类的使用例子
上面已经看到源码,也提到了,Euclid作为静态类,其中的很多静态方法都可以直接作为扩展方法使用。这里看看几个简单的例子:
1 // 1. Find out whether the provided number is an even number
2 Console.WriteLine(@"1.判断提供的数字是否是偶数");
3 Console.WriteLine(@"{0} 是偶数 = {1}. {2} 是偶数 = {3}", 1, Euclid.IsEven(1), 2, 2.IsEven());
4 Console.WriteLine();
5
6 // 2. Find out whether the provided number is an odd number
7 Console.WriteLine(@"2.判断提供的数字是否是奇数");
8 Console.WriteLine(@"{0} 是奇数 = {1}. {2} 是奇数 = {3}", 1, 1.IsOdd(), 2, Euclid.IsOdd(2));
9 Console.WriteLine();
10
11 // 3. Find out whether the provided number is a perfect power of two
12 Console.WriteLine(@"2.判断提供的数字是否是2的幂");
13 Console.WriteLine(@"{0} 是2的幂 = {1}. {2} 是2的幂 = {3}", 5, 5.IsPowerOfTwo(), 16, Euclid.IsPowerOfTwo(16));
14 Console.WriteLine();
15
16 // 4. Find the closest perfect power of two that is larger or equal to 97
17 Console.WriteLine(@"4.返回大于等于97的最小2的幂整数");
18 Console.WriteLine(97.CeilingToPowerOfTwo());
19 Console.WriteLine();
20
21 // 5. Raise 2 to the 16
22 Console.WriteLine(@"5. 2的16次幂");
23 Console.WriteLine(16.PowerOfTwo());
24 Console.WriteLine();
25
26 // 6. Find out whether the number is a perfect square
27 Console.WriteLine(@"6. 判断提供的数字是否是平方数");
28 Console.WriteLine(@"{0} 是平方数 = {1}. {2} 是平方数 = {3}", 37, 37.IsPerfectSquare(), 81, Euclid.IsPerfectSquare(81));
29 Console.WriteLine();
30
31 // 7. Compute the greatest common divisor of 32 and 36
32 Console.WriteLine(@"7. 返回32和36的最大公约数");
33 Console.WriteLine(Euclid.GreatestCommonDivisor(32, 36));
34 Console.WriteLine();
35
36 // 8. Compute the greatest common divisor of 492, -984, 123, 246
37 Console.WriteLine(@"8. 返回的最大公约数:492、-984、123、246");
38 Console.WriteLine(Euclid.GreatestCommonDivisor(492, -984, 123, 246));
39 Console.WriteLine();
40
41 // 9. Compute the least common multiple of 16 and 12
42 Console.WriteLine(@"10. 计算的最小公倍数:16和12");
43 Console.WriteLine(Euclid.LeastCommonMultiple(16, 12));
44 Console.WriteLine();
结果如下:
1.判断提供的数字是否是偶数
1 是偶数 = False. 2 是偶数 = True
2.判断提供的数字是否是奇数
1 是奇数 = True. 2 是奇数 = False
2.判断提供的数字是否是2的幂
5 是2的幂 = False. 16 是2的幂 = True
4.返回大于等于97的最小2的幂整数
128
5. 2的16次幂
65536
6. 判断提供的数字是否是平方数
37 是平方数 = False. 81 是平方数 = True
7. 返回32和36的最大公约数
4
8. 返回的最大公约数:492、-984、123、246
123
10. 计算的最小公倍数:16和12
48
3.资源
源码下载:http://www.cnblogs.com/asxinyu/p/4264638.html
如果本文资源或者显示有问题,请参考 本文原文地址:http://www.cnblogs.com/asxinyu/p/4301097.html