fork download
  1. #include <iostream>
  2. #include <map>
  3. using namespace std;
  4. using int64 = long long;
  5.  
  6. int64 gcd(int64 a, int64 b) {
  7. while (b != 0) {
  8. int64 r = a % b;
  9. a = b;
  10. b = r;
  11. }
  12. return a;
  13. }
  14.  
  15. bool isPowerOfTwo(int64 n) {
  16. return n > 0 && ((n & (n - 1)) == 0);
  17. }
  18.  
  19. int main() {
  20. int64 num, den;
  21. cout << "Podaj licznik i mianownik: ";
  22. cin >> num >> den;
  23.  
  24. if (den <= 0) {
  25. cout << "Blad: mianownik musi byc dodatni\n";
  26. return 1;
  27. }
  28.  
  29. // skracanie ulamka
  30. int64 g = gcd(llabs(num), den);
  31. num /= g;
  32. den /= g;
  33.  
  34. // ma NIE byc potega dwojki
  35. if (isPowerOfTwo(den)) {
  36. cout << "Mianownik NIE moze byc potega dwojki!\n";
  37. return 1;
  38. }
  39.  
  40. cout << "Rozwiniecie binarne: 0.";
  41.  
  42. // mapujemy reszta -> pozycja w wyniku
  43. map<int64, int> seen;
  44. string result = "";
  45.  
  46. int64 remainder = num % den;
  47. int pos = 0;
  48. int startPeriod = -1;
  49.  
  50. while (remainder != 0) {
  51. if (seen.count(remainder)) {
  52. // znaleziono okres
  53. startPeriod = seen[remainder];
  54. break;
  55. }
  56.  
  57. seen[remainder] = pos++;
  58. remainder *= 2;
  59.  
  60. if (remainder >= den) {
  61. result += '1';
  62. remainder -= den;
  63. } else {
  64. result += '0';
  65. }
  66. }
  67.  
  68. // wypisanie
  69. if (startPeriod == -1) {
  70. // przypadek rzadki: mimo wszystko skończone
  71. cout << result << endl;
  72. } else {
  73. for (int i = 0; i < result.size(); i++) {
  74. if (i == startPeriod) cout << "(";
  75. cout << result[i];
  76. }
  77. cout << ")" << endl;
  78. }
  79.  
  80. return 0;
  81. }
  82.  
  83.  
Success #stdin #stdout 0.01s 5328KB
stdin
3 5
stdout
Podaj licznik i mianownik: Rozwiniecie binarne: 0.(1001)