PhotoHelper.cs 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. using System;
  2. using System.Text;
  3. namespace MediaBrowser.Providers.Photos
  4. {
  5. public static class PhotoHelper
  6. {
  7. public static string Dec2Frac(double dbl)
  8. {
  9. char neg = ' ';
  10. double dblDecimal = dbl;
  11. if (dblDecimal == (int)dblDecimal) return dblDecimal.ToString(); //return no if it's not a decimal
  12. if (dblDecimal < 0)
  13. {
  14. dblDecimal = Math.Abs(dblDecimal);
  15. neg = '-';
  16. }
  17. var whole = (int)Math.Truncate(dblDecimal);
  18. string decpart = dblDecimal.ToString().Replace(Math.Truncate(dblDecimal) + ".", "");
  19. double rN = Convert.ToDouble(decpart);
  20. double rD = Math.Pow(10, decpart.Length);
  21. string rd = Recur(decpart);
  22. int rel = Convert.ToInt32(rd);
  23. if (rel != 0)
  24. {
  25. rN = rel;
  26. rD = (int)Math.Pow(10, rd.Length) - 1;
  27. }
  28. //just a few prime factors for testing purposes
  29. var primes = new[] { 47, 43, 37, 31, 29, 23, 19, 17, 13, 11, 7, 5, 3, 2 };
  30. foreach (int i in primes) ReduceNo(i, ref rD, ref rN);
  31. rN = rN + (whole * rD);
  32. return string.Format("{0}{1}/{2}", neg, rN, rD);
  33. }
  34. /// <summary>
  35. /// Finds out the recurring decimal in a specified number
  36. /// </summary>
  37. /// <param name="db">Number to check</param>
  38. /// <returns></returns>
  39. private static string Recur(string db)
  40. {
  41. if (db.Length < 13) return "0";
  42. var sb = new StringBuilder();
  43. for (int i = 0; i < 7; i++)
  44. {
  45. sb.Append(db[i]);
  46. int dlength = (db.Length / sb.ToString().Length);
  47. int occur = Occurence(sb.ToString(), db);
  48. if (dlength == occur || dlength == occur - sb.ToString().Length)
  49. {
  50. return sb.ToString();
  51. }
  52. }
  53. return "0";
  54. }
  55. /// <summary>
  56. /// Checks for number of occurence of specified no in a number
  57. /// </summary>
  58. /// <param name="s">The no to check occurence times</param>
  59. /// <param name="check">The number where to check this</param>
  60. /// <returns></returns>
  61. private static int Occurence(string s, string check)
  62. {
  63. int i = 0;
  64. int d = s.Length;
  65. string ds = check;
  66. for (int n = (ds.Length / d); n > 0; n--)
  67. {
  68. if (ds.Contains(s))
  69. {
  70. i++;
  71. ds = ds.Remove(ds.IndexOf(s, System.StringComparison.Ordinal), d);
  72. }
  73. }
  74. return i;
  75. }
  76. /// <summary>
  77. /// Reduces a fraction given the numerator and denominator
  78. /// </summary>
  79. /// <param name="i">Number to use in an attempt to reduce fraction</param>
  80. /// <param name="rD">the Denominator</param>
  81. /// <param name="rN">the Numerator</param>
  82. private static void ReduceNo(int i, ref double rD, ref double rN)
  83. {
  84. //keep reducing until divisibility ends
  85. while ((rD % i) < 1e-10 && (rN % i) < 1e-10)
  86. {
  87. rN = rN / i;
  88. rD = rD / i;
  89. }
  90. }
  91. }
  92. }