Guest User

Untitled

a guest
Apr 22nd, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.85 KB | None | 0 0
  1. #include <iostream>
  2. #include <random>
  3. #include <functional>
  4. #include <chrono>
  5. #include <limits>
  6. #include <cmath>
  7.  
  8. unsigned sqrtull(unsigned long long x) {
  9. if (x == 0) return 0;
  10. unsigned ans = 0;
  11. for (int i = ((std::numeric_limits<long long>::digits - __builtin_clzll(x)) & ~1);
  12. i >= 0; i -= 2) {
  13. ans <<= 1;
  14. if ((ans | 1) * (unsigned long long)(ans | 1) <= (x >> i)) ans |= 1;
  15. }
  16. return ans;
  17. }
  18.  
  19. unsigned sqrtu_exact(unsigned x) {
  20. if (x == 0) return 0;
  21. unsigned ret = 0;
  22. for (int i = ((std::numeric_limits<int>::digits - __builtin_clz(x)) & ~1);
  23. i >= 0; i -= 2) {
  24. ret <<= 1;
  25. if ((ret | 1) * (ret | 1) <= (x >> i)) ret |= 1;
  26. }
  27. return ret;
  28. }
  29.  
  30. unsigned sqrtu_usual(unsigned x) {
  31. unsigned ret = (unsigned)sqrt(x);
  32. return ret;
  33. }
  34.  
  35. unsigned D[1000'0000];
  36. unsigned D1[1000'0000];
  37. unsigned D2[1000'0000];
  38.  
  39. int main() {
  40. using namespace std;
  41.  
  42. // 32, 64
  43. cout << numeric_limits<unsigned>::digits << ", "
  44. << numeric_limits<unsigned long long>::digits << endl;
  45. for (int i = 10; i >= 0; --i) cout << i << ": " << sqrtu_exact(i) << endl;
  46.  
  47. mt19937 rnd;
  48. for (int i = 0; i < 1000'0000; ++i) D[i] = rnd();
  49. {
  50. const auto start = chrono::system_clock::now();
  51. for (int i = 0; i < 1000'0000; ++i) D1[i] = sqrtu_exact(D[i]);
  52. const auto end = chrono::system_clock::now();
  53. const chrono::duration<double> sec = end - start;
  54. cout << "Exact: " << sec.count() << "s\n";
  55. }
  56. {
  57. const auto start = chrono::system_clock::now();
  58. for (int i = 0; i < 1000'0000; ++i) D2[i] = sqrtu_usual(D[i]);
  59. const auto end = chrono::system_clock::now();
  60. const chrono::duration<double> sec = end - start;
  61. cout << "Usual: " << sec.count() << "s\n";
  62. }
  63.  
  64. for (int i = 0; i < 1000'0000; ++i) {
  65. if (D1[i] != D2[i]) {
  66. cout << "Wrong: " << D[i] << ' ' << D1[i] << ' ' << D2[i] << endl;
  67. return 0;
  68. }
  69. }
  70.  
  71. cout << "Correct!" << endl;
  72. return 0;
  73. }
  74.  
  75. /*
  76. Exact: 0.354943s
  77. Usual: 0.0570476s
  78. Correct!
  79. */
Add Comment
Please, Sign In to add comment