Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // http://codegolf.stackexchange.com/questions/35182/integer-square-root-of-integer
- // http://stackoverflow.com/questions/21657491/an-efficient-algorithm-to-calculate-the-integer-square-root-isqrt-of-arbitrari
- // http://www.codecodex.com/wiki/Calculate_an_integer_square_root
- #include <stdio.h>
- #include <stdint.h> // uint64_t
- #include <time.h> // clock()
- #include <string.h> // strcpy()
- // g++ --version
- // Apple LLVM version 5.1 (clang-503.0.40)
- //#define FASTEST
- #define ITERATIVE
- //#define RECURSIVE
- //#define FASTER
- //#define SLOWEST
- #if defined(FASTEST) // -O3: 0.0 secs, 95 chars, by edc65
- typedef uint64_t Z;Z q(Z x){Z n=1,a=x,m=0;for(;a-m&&a-n;)n=a,m=x/n,a=m/2+n/2+(m&n&1);return a;}
- #define isqrt q
- #else
- #if defined(ITERATIVE) // -O3: 0.0 secs, by Asuka Kenji - Siu Ching Pong
- typedef uint64_t Z;
- uint32_t isqrt_iterative(uint64_t const n)
- {
- Z xk = n;
- if (n == 0) return 0;
- //if (n == 18446744073709551615ULL) return 4294967295U;
- if( n == -1 ) return -1; // optimization
- do
- {
- Z const xk1 = (xk + n / xk) / 2;
- if (xk1 >= xk)
- return xk;
- else
- xk = xk1;
- } while (1);
- }
- #define isqrt isqrt_iterative
- #else
- #if defined(RECURSIVE) // -O3: 0.0 secs, by Asuka Kenji - Siu Ching Pong
- uint32_t isqrt_impl(
- uint64_t const n,
- uint64_t const xk)
- {
- uint64_t const xk1 = (xk + n / xk) / 2;
- return (xk1 >= xk) ? xk : isqrt_impl(n, xk1);
- }
- uint32_t isqrt_recursive(uint64_t const n)
- {
- if (n == 0) return 0;
- if (n == 18446744073709551615ULL) return 4294967295U;
- return isqrt_impl(n, n);
- }
- #define isqrt isqrt_recursive
- #else
- #if defined(FASTER) // -O3: 4.0 secs, 70 chars
- typedef uint64_t Z;Z z(Z x){Z n=0,s=0;for(;s<x;s+=2*n+1)n++;return n;}
- #define isqrt z
- #else
- #if defined(SLOWEST) // -O3 177.3 secs, 58 chars, undefined behavior by Todd Lehman
- typedef uint64_t Z;Z r(Z n,Z r){for(;n/++r/r;);return--r;}
- #define isqrt(x) r(x,0)
- // C++ Non-wrapper version:
- // typedef uint64_t Z;Z isqrt(Z n,Z r=0){for(;n/++r/r;);return--r;}
- #else
- #error "Didn't define isqrt() to test!"
- #endif // SLOWEST
- #endif // FASTER
- #endif // RECURSIVE
- #endif // ITERATIVE
- #endif // FASTEST
- char* i2a( uint64_t x, int base = 10, bool comma = true )
- {
- const int SIZE = 64; // largest is binary + null
- static char t[SIZE ] ; // output buffer
- const int BASE = 16; // largest base
- const char s[BASE+1] = "0123456789ABCDEF";
- /* */ char*p = t + SIZE - 1;
- /* */ int digits = 0;
- /* */ int r ; // remainder
- if( base > BASE ) base = BASE;
- if( base < 2 ) base = 2;
- *p-- = 0;
- while( x >= base )
- {
- digits++;
- r = x % base;
- x -= r;
- x /= base;
- *p = s[ r ];
- p--;
- if( comma && base == 16 && digits && ((digits & 7) == 0 )) *p-- = '_';
- if( comma && base == 10 && digits && ((digits % 3) == 0 )) *p-- = ',';
- }
- r = x % base;
- *p = s[ r ];
- if( base == 16 ) *--p = 'x';
- if( base == 2 ) *--p = 'z';
- if( base == 16 || base == 2 || base == 8 ) *--p = '0';
- return p;
- }
- inline
- void entry( const int i, const uint64_t& n, uint64_t& s )
- {
- // If your compiler -O2 is buggy *cough clang cough*
- // ... don't put isqrt() outside the function
- s = isqrt(n);
- printf( "#%d isqrt( ", i );
- printf( "%s = ", i2a( n,16,0) );
- printf( "%s ) ", i2a( n,10,0) );
- printf( "= %s ", i2a( s ) );
- printf( "\n" );
- }
- int main(int nArg, char* aArg[])
- {
- time_t start = clock();
- uint64_t n = 0;
- uint64_t s = 0;
- for( int i = 0; i <= sizeof(uint64_t)*8; i++ )
- {
- entry( i, n, s );
- n <<= 1;
- if( !n ) n++; // handle zero case
- }
- n = -1; // 0xFFFFffffFFFFffffULL;
- entry( 65, n, s );
- time_t end = clock();
- double dif = (end - start);
- double sec = dif / CLOCKS_PER_SEC;
- printf( "Time: %5.3f secs\n", sec );
- uint64_t actual = s;
- uint64_t expect = 4294967295ULL; // 2^32-1;
- bool pass = (actual == expect);
- char act[64];
- char exp[64];
- strcpy( act, i2a( actual ) );
- strcpy( exp, i2a( expect ) );
- printf( "Verify #65 %s =?= %s ? %s\n", act, exp, pass ? "pass." : "FAIL!" );
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement