__int128的实现

#include<bitset>
#include<algorithm>
#include<iostream>
#include<string>
#include<deque>
#include<cstdio>
using namespace std;  

class int128;  

void shift(int128 & in,deque<bool> & de);  

template<size_t N>
bool operator<(bitset<N> const& b1,bitset<N> const& b2)
{
    int i=N;
    while( i-- && b1[i]==b2[i] ) { }  

    return ((-1 == i) ? false : (b1[i]<b2[i]));
}  

class int128
{
    bitset<128> number;
public:
    explicit int128(string str):number(str){}
    int128(bitset<128>const& b):number(b){}
    int128(int a = 0 , int b = 0 , int c = 0 , int d = 0)
    {
        bitset<32> b1(a),b2(b),b3(c),b4(d);
        int i, k = 128;
        for(i = 32 ; i ; number[--k] = b1[--i]) { }
        for(i = 32 ; i ; number[--k] = b2[--i]) { }
        for(i = 32 ; i ; number[--k] = b3[--i]) { }
        for(i = 32 ; i ; number[--k] = b4[--i]) { }
    }
    bool operator[](size_t i)const
    {
        return number[i];
    }
    bitset<128>::reference operator[](size_t i)
    {
        return number[i];
    }
    friend bool operator<(int128 const& i1,int128 const& i2)
    {
        return i1.number < i2.number;
    }  

    friend int128 operator+(int128 const& i1,int128 const& i2)
    {
        if(i1 == 0)
            return i2;
        if(i2 == 0)
            return i1;
        int128 result;
        bitset<2> sum;  

        for(int i = 0 ; i < 128 ; ++i)
        {
            sum=i1[i]+i2[i]+sum.to_ulong();
            result[i]=sum[0];
            sum>>=1;
        }
        return result;
    }  

    friend int128 operator-(int128 const& i1,int128 const& i2)
    {
        if(i2==0)
            return i1;  

        int128 result=i1;  

        for(int i = 0 ; i < 128 ; ++i)
        {
            if(i2[i] == 0)   {}
            else
            {
                if(result[i] == 1)
                    result[i] = 0;
                else
                {
                    int k = i;
                    while(k < 128 && result[k] == 0)
                    {
                        result[k] = 1;
                        ++k;
                    }
                    if(k != 128)
                        result[k] = 0;
                }
            }
        }  

        return result;
    }
    friend int128 operator*(int128 const& i1,int128 const& i2)
    {
        if(i1==0 || i2==0)
            return int128();
        if(i1==1)
            return i2;
        if(i2==1)
            return i1;  

        int128 acc=int128();  

        for(int i=0;i<128;++i)
        {
            if(i2[i]==1)
            {
                acc=acc+(i1<<i);
            }
        }  

        return acc;
    }
    friend int128 operator/(int128 const& i1,int128 const& i2)
    {
        if(i1 < i2)
            return int128();
        deque<bool> de;
        bool flag = 0;
        for(int i = 127 ; i >= 0 ; --i)
        {
            if(flag == 0 && i1[i] == 0)   {}
            else
            {
                flag = 1;
                de.push_back(i1[i]);
            }
        }  

        int128 div = int128();
        int128 result = int128();  

        while(!de.empty())
        {
            shift(div,de);
            if(div < i2)
            {
                result = result<<1;
            }
            else
            {
                result = (result<<1) + int128(0,0,0,1);
                div = div - i2;
            }
        }  

        return result;
    }
    friend int128 operator%(int128 const& i1,int128 const& i2)
    {
        if(i1 < i2)
            return i1;
        deque<bool> de;
        bool flag = 0;
        for(int i = 127 ; i >= 0 ; --i)
        {
            if(flag == 0 && i1[i] == 0)   {}
            else
            {
                flag = 1;
                de.push_back(i1[i]);
            }
        }  

        int128 div = int128();
        int128 result = int128();  

        while(!de.empty())
        {
            shift(div,de);
            if(div < i2)
            {
                result = result<<1;
            }
            else
            {
                result = (result<<1) + int128(0,0,0,1);
                div = div - i2;
            }
        }  

        return div;
    }
    friend bool operator==(int128 const& i,int const k)
    {
        bitset<32> bb(k);
        for(int g = 0 ; g < 32 ; ++g)
        {
            if(i[g] != bb[g])
                return 0;
        }
        return 1;
    }
    void operator=(bitset<128>const& b)
    {
        number = b;
    }
    friend ostream& operator<<(ostream& o,int128 const& i)
    {
        o<<i.number;
        return o;
    }
    int128 operator<<(size_t step)const
    {
        return int128(number<<step);
    }
    unsigned long to_ulong()const
    {
        return *((unsigned long*)&number);
    }  

public:
    bool ToDecimalStr(std::string &str)
    {
        str.clear();
        char buf[128] = {0};
        int128 Radix(0, 0, 0, 10);
        for(int128 num = number; !(num == 0); num = num/Radix)
        {
            if( sprintf(buf, "%d", ((int)(num%Radix).to_ulong())) < 0 )
            {
                return false;
            }
            str = buf + str;
        }
        return true;
    }  

    static void Print(int128 & data, bool bEndl = true)
    {
        string str;
        if( data.ToDecimalStr(str) )
        {
            printf("%s%s", str.c_str(), (bEndl?"\n":""));
        }
    }
};  

static int128 const one = int128(0,0,0,1);  

template<size_t N>
void add_one(bitset<N>& b)
{
    int i = 0;
    while(i < N && b[i] == 1)
    {
        b[i] = 0;
        ++i;
    }
    if(i == N)
        return;
    b[i] = 1;
}  

void add_one(int128& k)
{
    int i = 0;
    while(i < 128 && k[i] == 1)
    {
        k[i] = 0;
        ++i;
    }
    if(i == 128)
        return;
    k[i] = 1;
}  

void shift(int128 & in,deque<bool> & de)
{
    if(de.front()==1)
    {
        de.pop_front();
        in=(in<<1)+one;
    }
    else
    {
        de.pop_front();
        in=in<<1;
    }
}  

bool IsPrime(int128 const& number)
{
    for(int128 i = int128(0,0,0,2) ; i < number ; add_one(i))
    {
        if(number%i == 0)
            return 0;
    }
    return 1;
}

  这个是某dalao写的int128类,可能不是那么好用,暂存,回家搞一点事情。

原文地址:https://www.cnblogs.com/TheRoadToAu/p/8414622.html

时间: 2024-11-17 22:43:34

__int128的实现的相关文章

关于__int128

定义 __int128 n,r,g,b,T; __int128 ans; __int128 f[1025][1025]; 取最大值函数 __int128 getmax(__int128 a,__int128 b){ if (a>b) return(a);else return(b); } 输出 void print(__int128 x){ if (x==0) return; if (x) print(x/10); putchar(x%10+'0'); } 其余与整形类似,对于略大于LL范围值计

__int128 输入输出模板

#include <bits/stdc++.h> using namespace std; void scan(__int128 &x)//输入 { x = 0; int f = 1; char ch; if((ch = getchar()) == '-') f = -f; else x = x*10 + ch-'0'; while((ch = getchar()) >= '0' && ch <= '9') x = x*10 + ch-'0'; x *= f

__int128

__int128 __uint128 __int128_t __uint128_t 大小:16字节 2^128(sizeof()) 2^128 39位 340282366920938463463374607431768211456 Codeblocks 无法使用,Dev C++ 可以使用,有时候比赛能用 Problem:A+B http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1 1 #include <cstdio> 2 #

__int128使用

输入输出模板: __int128无法使用cin和cout进行输入输出,所以只能自己写一个输入输出的模板: #include <bits/stdc++.h> using namespace std; void scan(__int128 &x)//输入 { x = 0; int f = 1; char ch; if((ch = getchar()) == '-') f = -f; else x = x*10 + ch-'0'; while((ch = getchar()) >= '

__int128输出

ostream& operator<<(ostream& os, __int128 t) { if (t==0) return os << "0"; if (t<0) { os<<"-"; t=-t; } int a[50],ai=0; memset(a,0,sizeof a); while (t!=0){ a[ai++]=t%10; t/=10; } for (int i=1;i<=ai;i++) o

Clang之语法抽象语法树AST

语法分析器的任务是确定某个单词流是否能够与源语言的语法适配,即设定一个称之为上下文无关语言(context-free language)的语言集合,语法分析器建立一颗与(词法分析出的)输入单词流对应的正确语法树.语法分析树的建立过程主要有两种方法:自顶向下语法分析法和自底向上分析法.AST作为语法分析树(parse tree)的一种简写方式,它独立于具体编程语言(C++.Java.C等),而且与语法分析树的建立过程无关(自顶向下和自底向上逻辑等价),是联系编译器前端.后端的重要接口.Clang的

iOS安装包瘦身的那些事儿

在我们提交安装包到App Store的时候,如果安装包过大,有可能会收到类似如下内容的一封邮件: 收到这封邮件的时候,意味着安装包在App Store上下载的时候,有的设备下载的安装包大小会超过100M.对于超过100M的安装包,只能在WIFI环境下下载,不能直接通过4G网络进行下载. 在这里,我们提交App Store的安装包大小为67.6MB,在App Store上显示的下载大小和实际下载下来的大小,我们通过下表做一个对比: iPhone型号 系统 AppStore 显示大小 下载到设备大小

Clang+llvm windows运行环境配置

下了官网Pre-built Binaries:Clang for Windows( llvm.org/releases/3.5.0/LLVM-3.5.0-win32.exe )03 Sep 2014 3.5.0 The LLVM Compiler Infrastructure(llvm.org) download LLVM(llvm.org/releases/) 由于刚刚安装了 TDM GCC 4.9.2 tdm64-gcc-4.9.2-3.exe 2014 December 12th(tdm-

XJOI 郎思轲模拟题

今天比赛的是郎思轲出的模拟题,比较偏数学. 全国青少年奥林匹克联赛 CCF-NOIP 2017模拟试题 提高组(复赛)day1 竞赛时间:210分钟 命题:郎思轲 题目一览: 题目名称 不定长数组 台球游戏 对称的多项式 题目类型 传统型 传统型 传统型 目录 vector billiards poly 可执行文件名 vector billiards poly 输入文件名 vector.in billiards.in poly.in 输出文件名 vector.out billiards.out