Advertisement
HasteBin0

C++ Fast Square Root Function

Jun 15th, 2019 (edited)
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.21 KB | None | 0 0
  1. #include <exception>
  2. #include <new>
  3.  
  4. #include <iostream>
  5. #include <fstream>
  6. #include <cstdint>
  7.  
  8. #include <cinttypes>
  9. #include <cstdlib>
  10. #include <cstring>
  11. #include <cmath>
  12.  
  13. #include <chrono>
  14. #include <thread>
  15. #include <mutex>
  16.  
  17. using namespace std;
  18.  
  19. #include "ltoa.h"
  20.  
  21. class Indicator {
  22.     private:
  23.         mutable mutex editor;
  24.         bool running, killed, started, clearit, clearondeath;
  25.         thread* threader;
  26.         long complete, total;
  27.         unsigned speed;
  28.         char* buf;
  29.         uint8_t prev_length;
  30.  
  31.         const char* motion = "|[/-\\]+[/-\\]|[/+\\]+[/+\\]";
  32.         uint8_t place/* 0-23 */;
  33.  
  34.         void clear_buf() {
  35.             for (uint8_t i = 0; i < 71; i++)
  36.                 buf[i] = '\0';
  37.         }
  38.  
  39.         void clear_out() {
  40.             for (uint8_t i = 0; i < prev_length; i++) putchar(' ');
  41.             putchar('\r');
  42.             fflush(stdout);
  43.             prev_length = 0;
  44.             clearit = false;
  45.         }
  46.  
  47.         #define mlock lock_guard<mutex> abcd(this->editor)
  48.  
  49.         void run() {
  50.             chrono::milliseconds speedv;
  51.             long percentage;
  52.             uint8_t string_place;
  53.             char *buf2 = buf + 2, *bufs;
  54.             //
  55.             while (true) {
  56.                 {
  57.                     mlock;
  58.                     if (clearit) clear_out();
  59.                     /** 2 {spin}" " + 20 percent number + 3 "% (" + 20 complete + 3 " / " + 20 total + 3 ").\0*/
  60.                     if (running) {
  61.                         clear_buf();
  62.                         //
  63.                         if (place >= 24) place = 0;
  64.                         buf[0] = motion[place++];
  65.                         buf[1] = ' ';
  66.                         //
  67.                         percentage = ((double) complete * 100.0d) / total;
  68.                         ltoa(percentage, buf2, 10);
  69.                         string_place = 2 + (uint8_t) strlen(buf2);
  70.                         //
  71.                         buf[string_place++] = '%';
  72.                         buf[string_place++] = ' ';
  73.                         buf[string_place++] = '(';
  74.                         //
  75.                         bufs = buf + string_place;
  76.                         ltoa(complete, bufs, 10);
  77.                         string_place += (uint8_t) strlen(bufs);
  78.                         //
  79.                         buf[string_place++] = ' ';
  80.                         buf[string_place++] = '/';
  81.                         buf[string_place++] = ' ';
  82.                         //
  83.                         bufs = buf + string_place;
  84.                         ltoa(total, bufs, 10);
  85.                         string_place += (uint8_t) strlen(bufs);
  86.                         //
  87.                         buf[string_place++] = ')';
  88.                         buf[string_place++] = '.';
  89.                         buf[string_place] = '\0'; // length
  90.                         //
  91.                         printf("%s", buf);
  92.                         if (prev_length > string_place) {
  93.                             string_place = prev_length - string_place;
  94.                             for (uint8_t i = 0; i < string_place; i++)
  95.                                 putchar(' ');
  96.                         }
  97.                         putchar('\r');
  98.                         fflush(stdout);
  99.                         prev_length = (uint8_t) strlen(buf);
  100.                     }
  101.                     if (killed) break;
  102.                     speedv = chrono::milliseconds(speed);
  103.                 }
  104.                 this_thread::sleep_for(speedv);
  105.             }
  106.             mlock;
  107.             if (clearondeath) clear_out();
  108.         }
  109.  
  110.     public:
  111.         Indicator():
  112.             running(false),
  113.             killed(false),
  114.             started(false),
  115.             clearit(false),
  116.             clearondeath(true),
  117.             complete(0l),
  118.             total(1l),
  119.             speed(500u),
  120.             prev_length(0),
  121.             place(0) {
  122.             threader = nullptr;
  123.             buf = nullptr;
  124.             //
  125.             buf = new (nothrow) char[71] /* 2 {spin}" " + 20 percent number + 3 "% (" + 20 complete + 3 " / " + 20 total + 3 ").\0*/;
  126.             threader = new (nothrow) thread(&Indicator::run, this);
  127.             if (buf) clear_buf();
  128.         }
  129.         ~Indicator() {
  130.             if (threader) {
  131.                 stop();
  132.                 {
  133.                     mlock;
  134.                     killed = true;
  135.                 }
  136.                 threader->join();
  137.                 delete threader;
  138.             }
  139.             delete[] buf;
  140.         }
  141.  
  142.         bool check_construction() const { return threader && buf; }
  143.  
  144.         bool hide() {
  145.             mlock;
  146.             bool r = clearit;
  147.             clear_out();
  148.             return r;
  149.         }
  150.  
  151.         void start() { mlock; running = true; started = true; }
  152.         void stop() { mlock; running = false; started = false; clearit = true; }
  153.         void resume() { mlock; running = true; }
  154.         void pause()  { mlock; running = false; }
  155.  
  156.         bool is_paused() { mlock; return !running; }
  157.         bool is_started() { mlock; return started; }
  158.  
  159.         long get_complete() const { mlock; return complete; }
  160.         long get_total() const { mlock; return total; }
  161.         unsigned get_speed() const { mlock; return speed; }
  162.         bool get_cod() const { mlock; return clearondeath; }
  163.         void set_complete(long x) { mlock; if (x >= 0) complete = x; }
  164.         void make_completion(long x = 1l) { mlock; if (x > 0) complete += x; }
  165.         void set_total(long x) { mlock; if (x > 0) total = x; }
  166.         void set_speed(unsigned x) { mlock; if (x > 0) speed = x; }
  167.         void set_cod(bool cod) { mlock; clearondeath = cod; }
  168.  
  169.         #undef mlock
  170.  
  171.         static Indicator* new_indicator() {
  172.             Indicator* tmp = new (nothrow) Indicator();
  173.             if (tmp && tmp->check_construction()) return tmp;
  174.             delete tmp;
  175.             return nullptr;
  176.         }
  177. };
  178.  
  179. uint8_t bitsof(long x) {
  180.     uint8_t bits = 0;
  181.     while (x) {
  182.         bits++;
  183.         x >>= 1;
  184.     }
  185.     return bits;
  186. }
  187.  
  188. long fsqrt(long x) {
  189.     long rvalue = 0;
  190.     long nthbit = 1 << (bitsof(x) / 2);
  191.     long tmp, tmpd;
  192.     while (nthbit) {
  193.         tmpd = rvalue + nthbit;
  194.         tmp = x / tmpd;
  195.         if (tmpd > tmp) {
  196.             nthbit >>= 1;
  197.             continue;
  198.         }
  199.         rvalue = tmpd;
  200.     }
  201.     return rvalue;
  202. }
  203.  
  204. int main() {
  205.     long input;
  206.     do {
  207.         input = 0;
  208.         printf("Input a long int. above 0: ");
  209.         fflush(stdout);
  210.         scanf("%ld", &input);
  211.         fflush(stdin);
  212.     } while(input <= 0);
  213.     Indicator* spinner = Indicator::new_indicator();
  214.     ofstream log("log.txt");
  215.     if (spinner) {
  216.         if (log.is_open()) {
  217.             long* squares = new (nothrow) long[input];
  218.             if (squares) {
  219.                 for (long i = 1; i <= input; i++)
  220.                     squares[i - 1] = i * i;
  221.                 bool error;
  222.                 long errors = 0, rmin, rmax, sqrtv;
  223.                 const long up = input - 1;
  224.                 const long last_square = squares[up];
  225.                 spinner->set_total(last_square);
  226.                 spinner->set_speed(2000);
  227.                 spinner->set_cod(false);
  228.                 spinner->start();
  229.                 for (long i = 0; i < up;) {
  230.                     rmin = squares[i++];
  231.                     rmax = squares[i];
  232.                     for (long j = rmin; j < rmax; j++) {
  233.                         sqrtv = fsqrt(j);
  234.                         error = sqrtv != i;
  235.                         if (error) errors++;
  236.                         log << "\\|(" << j << ") = " << sqrtv << " (" << rmin << ")?\n";
  237.                         spinner->make_completion();
  238.                     }
  239.                     spinner->set_speed(300u + (1500.0d * i) / last_square);
  240.                 }
  241.                 spinner->stop();
  242.                 spinner->hide();
  243.                 if (errors) cerr << "Errors: " << errors << endl;
  244.                 else cout << "No errors!" << endl;
  245.                 delete[] squares;
  246.             } else cerr << "Memory (squares) error" << endl;
  247.             log.close();
  248.         } else cerr << "File error" << endl;
  249.         delete spinner;
  250.     } else cerr << "The spinner can't spin" << endl;
  251.     return 0;
  252. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement