求平方根下取整,对于gcc type __uint128_t。

~45.5ns/op on i7-7700k@4.35G,即typical <200cyc/op。

Together with u128gen&timing&validation.

#include <cmath>
#include <cstdio>
#include <random>
#include <chrono>
typedef __uint128_t u128;
typedef unsigned long long u64;
const int count=10000000;
u64 sqrt_approx(u64 x){
u64 approx=sqrt(double(x));
return (approx+x/approx)>>1;
}
u64 sqrt(u64 x){
u64 approx=sqrt(double(x));
u64 apt=(approx+x/approx)>>1;
approx=apt*apt;
if(approx>x)return apt-1;
if(x-approx>=2*apt-1)return apt+1;
return apt;
}
u128 sqrt(u128 r){
if(!(r>>64))return sqrt(u64(r));
int cnt=(((64-__builtin_clzll(u64(r>>64)))+1)|1)^1;
u128 approx=u128(sqrt_approx(u64(r>>cnt)))<<(cnt/2);
approx=(approx+r/approx)>>1;
u128 apt=u128(u64(approx))*u128(u64(approx));
// if(r-apt>=2*approx-1)return approx+1;
return approx-((r-apt)>>127);
}
u128 rand_arr[count],root_arr[count]; typedef void(*func)(); void Time(const char*str,func fn,int multi=count){
using hrc=std::chrono::high_resolution_clock;
hrc::time_point start=hrc::now();
fn();
hrc::time_point stop=hrc::now();
hrc::duration dur=stop-start;
printf("%s Finished in %llu us . \n",str,std::chrono::duration_cast<std::chrono::microseconds>(dur).count());
if(multi)
printf("Average %.3lfns per op.\n",double(std::chrono::duration_cast<std::chrono::nanoseconds>(dur).count())/multi);
} void Root(){
for(int i=0;i<count;++i)
root_arr[i]=sqrt(rand_arr[i]);
} std::mt19937_64 rng; void Gen(){
for(int i=0;i<count;++i)
rand_arr[i]=(u128(rng())<<64)|rng();
} int Validate(){
for(int i=0;i<count;++i){
u128 ax=root_arr[i];
u128 bx=(ax+1)*(ax+1);
ax=ax*ax;
if(ax>rand_arr[i])
return i+1;
if(bx<=rand_arr[i])
return i+1;
}return 0;
} char pp[300];
#define spp(...) (sprintf(pp,##__VA_ARGS__),pp)
#define hexo(x) (spp("0x%llx%016llx",u64(x>>64),u64(x))) int main(){
printf("Count=%d\n",count);
Time("Generation",Gen);
Time("Square root",Root);
int val=Validate();
printf("Validation %s\n",val?spp("Fail at %d",val):"Passed");
if(val){
--val;
printf("Rand %s\n",hexo(rand_arr[val]));
printf("Root %s\n",hexo(root_arr[val]));
}
return 0;
}

sqrti128的更多相关文章

随机推荐

  1. Windows Server 2012下手动配置IIS的文件夹访问权限

    当新建一个website的时候,一般情况下IIS对相应的物理文件夹的访问权限是不够的. 针对匿名认证(anonymous authentication)需要: 打开文件夹properties-> ...

  2. python基础之反射、面向对象进阶

    isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象,如果是返回True 1 class F ...

  3. 用ServiceStack操作使用redis的问题

    最近在学习Redis,查阅网上很多资料后使用SericeStack连接redis.在nuget中下载ServiceStack.Redis,主要使用到四个dll 但是运行之后会出现一堆奇怪问题:没有实现 ...

  4. coia阻止事件上浮

    1.阻止事件上浮 选择默认地址li 时 选中整个div使其为默认地址 此时点击编辑按钮也会触发选中默认事件 为事件添加event.stopPropagation();阻止事件上浮 2.js给页面inp ...

  5. 牛客网暑期ACM多校训练营(第七场):J-Sudoku Subrectangles

    链接:J-Sudoku Subrectangles 题意:给出 n * m 的字母矩阵,公52种字母.求出不含重复元素的子矩阵的个数. 题解: L[i][j]:s[i][j] ~ s[i][ j - ...

  6. mysql数据库----Pymysql

    本节重点: pymysql下载和使用 sql注入 增.删.改:conn.commit() 查:fetchone.fetchmany.fetchall 一.pymysql的下载和使用 之前我们都是通过M ...

  7. 03-Mysql数据库----安装与管理

    本节掌握内容: mysql的安装.启动 mysql破解密码 统一字符编码 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下公司.MySQL 最流行的 ...

  8. 更换ubuntu软件源的方法

    第一步:查看本系统Codename 输入lsb_release -a查看本系统Codename,我的codename是bionic,如图: 第二步:搜索与codename对应的镜像地址 我搜索到的是: ...

  9. Visual Studio 2010安装包

    点击下载

  10. deeplearning.ai课程学习(4)

    第四周:深层神经网络(Deep Neural Networks) 1.深层神经网络(Deep L-layer neural network) 在打算使用深层神经网络之前,先去尝试逻辑回归,尝试一层然后 ...