#include #include #include #include /* old version: uintmax_t isqrt(uintmax_t n){ int i; for(i = 1; i <= n; i += 2) n -= i; return i >> 1; } */ /* this version only works for unsigned types... uintmax_t isqrt(uintmax_t n){ uintmax_t r = 0; // fixed this so it should work even if uintmax_t is an odd number of bits! // ... i've never seen an implementation where that's the case, but i realized // that the code i had here before would break if someone was perverse enough // to do that, so i fixed it. for(uintmax_t i = ~(UINTMAX_MAX >> 2) & UINTMAX_MAX / 3; i; i >>= 2) if(n >= (i | r)){ n -= i | r; r = r >> 1 | i; } else r >>= 1; return r; } */ intmax_t isqrt(intmax_t n){ if(0 > n) n = -n; for(intmax_t i = ((INTMAX_MAX >> 2) ^ INTMAX_MAX) / 3 << 1; i; i >>= 2) if(n >= (i | r)){ n -= i | r; r = r >> 1 | i; } else r >>= 1; return r; } int main(int argc, char *argv[]){ for(int i = 1; i < argc; ++i){ intmax_t n = strtoimax(argv[i],NULL,0); printf("isqrt(%jd) == %jd%s\n", n, ISQRT(n), n < 0 ? "i" : ""); } return 0; }