Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 64位数学运算,无任何数据或精度损失_C_Algorithm_Math_Operators_Arithmetic Expressions - Fatal编程技术网

C 64位数学运算,无任何数据或精度损失

C 64位数学运算,无任何数据或精度损失,c,algorithm,math,operators,arithmetic-expressions,C,Algorithm,Math,Operators,Arithmetic Expressions,我相信128位数据没有任何可移植的标准数据类型。因此,我的问题是如何高效地使用现有的标准数据类型执行64位操作而不丢失数据 例如:我有以下两个uint64_t类型变量: uint64_t x=-1; uint64_t y=-1 现在,如何存储/检索/打印数学运算的结果,例如x+y、x-y、x*y和x/y 对于上述变量,x+y的值为-1,这实际上是一个带进位1的0xFFFFFFFFFFFFFFFFFULL void add (uint64_t a, uint64_t b, uint64_t res

我相信128位数据没有任何可移植的标准数据类型。因此,我的问题是如何高效地使用现有的标准数据类型执行64位操作而不丢失数据

例如:我有以下两个uint64_t类型变量:

uint64_t x=-1; uint64_t y=-1

现在,如何存储/检索/打印数学运算的结果,例如
x+y、x-y、x*y和x/y

对于上述变量,x+y的值为-1,这实际上是一个带进位1的0xFFFFFFFFFFFFFFFFFULL

void add (uint64_t a, uint64_t b, uint64_t result_high, uint64_t result_low)
{
    result_low = result_high = 0;
    result_low  = a + b;
    result_high += (result_low < a);
}
void add(uint64测试a、uint64测试b、uint64测试结果高、uint64测试结果低)
{
结果低=结果高=0;
结果低=a+b;
结果高+=(结果低
如何执行其他操作,如
add
,从而提供正确的最终输出

如果有人能分享处理溢出/下溢等问题的通用算法,我将不胜感激,这些问题可能会在使用此类操作时出现


任何经过标准测试的算法都可能有所帮助。

有很多
biginger
库可以处理大数字

  • 如果您希望避免库集成,并且您的需求非常小,那么下面是我的基本
    biginger
    代码片段,我通常使用它来解决基本需求的问题。您可以根据需要创建新方法或重载运算符此代码段经过广泛测试,没有bug。

    来源
    class-BigInt{
    公众:
    //默认构造函数
    BigInt(){}
    //~BigInt(){}//避免重载默认析构函数。按成员进行销毁是可以的
    BigInt(字符串b){
    (*this)=b;//字符串的构造函数
    }
    //一些有用的方法
    size\u t size()常量{//返回位数
    返回a.length();
    }
    BigInt inverseSign(){//更改符号
    符号*=-1;
    返回(*本条);
    }
    BigInt normalize(int newSign){//删除前导0,修复符号
    对于(int i=a.size()-1;i>0&&a[i]='0';i--)
    a、 擦除(a.begin()+i);
    符号=(a.size()==1&&a[0]==0')?1:newSign;
    返回(*本条);
    }
    //赋值运算符
    void运算符=(字符串b){//为BigInt指定一个字符串
    a=b[0]='-'?b.substr(1):b;
    相反(a.开始(),a.结束());
    这->规范化(b[0]='-'?-1:1);
    }
    //条件运算符
    布尔运算符<(BigInt const&b)const{//小于运算符
    如果(sign!=b.sign)返回signb.a.size();
    对于(int i=a.size()-1;i>=0;i--)如果(a[i]!=b.a[i])
    返回符号==1?a[i]b.a[i];
    返回false;
    }
    布尔运算符==(常量BigInt&b)常量{//相等运算符
    返回a==b.a&&sign==b.sign;
    }
    //数学运算符
    BigInt运算符+(BigInt b){//加法运算符重载
    if(sign!=b.sign)返回(*this)-b.inverseSign();
    BigInt c;
    对于(int i=0,进位=0;i=0;i--){
    c、 a.插入(c.a.begin(),'0');
    c=c+a.substr(i,1);
    而(!(c//有很多
    biginger
    库可以处理大数字

  • 如果您希望避免库集成,并且您的需求非常小,那么下面是我的基本
    biginger
    代码段,我通常使用它来解决基本需求的问题。您可以根据需要创建新方法或重载运算符。此代码段经过广泛测试,没有bug。

    来源
    class-BigInt{
    公众:
    //默认构造函数
    BigInt(){}
    //~BigInt(){}//避免重载默认析构函数。按成员进行销毁是可以的
    BigInt(字符串b){
    (*this)=b;//字符串的构造函数
    }
    //一些有用的方法
    size\u t size()常量{//返回位数
    返回a.length();
    }
    BigInt inverseSign(){//更改符号
    符号*=-1;
    返回(*本条);
    }
    BigInt normalize(int newSign){//删除前导0,修复符号
    对于(int i=a.size()-1;i>0&&a[i]='0';i--)
    a、 擦除(a.begin()+i);
    符号=(a.size()==1&&a[0]==0')?1:newSign;
    返回(*本条);
    }
    //赋值运算符
    void运算符=(字符串b){//为BigInt指定一个字符串
    a=b[0]='-'?b.substr(1):b;
    相反(a.开始(),a.结束());
    这->规范化(b[0]='-'?-1:1);
    }
    //条件运算符
    布尔运算符<(BigInt const&b)const{//小于运算符
    如果(sign!=b.sign)返回signb.a.size();
    对于(int i=a.size()-1;i>=0;i--)如果(a[i]!=b.a[i])
    返回符号==1?a[i]b.a[i];
    返回false;
    }
    布尔运算符==(常量BigInt&b)常量{//相等运算符
    返回a==b.a&&sign==b.sign;
    }
    //数学运算符
    BigInt运算符+(BigInt b){//加法运算符重载
    if(sign!=b.sign)返回(*this)-b.inverseSign();
    BigInt c;
    对于(int i=0,进位=0;i=0;i--){
    c、 a.插入(c.a.begin(),'0');
    c=c+a.substr(i,1);
    而(!(c//如果没有,您可以模拟
    uint128\t

    typedef struct uint128_t { uint64_t lo, hi } uint128_t;
    ...
    
    uint128_t add (uint64_t a, uint64_t b) {
        uint128_t r; r.lo = a + b; r.hi = + (r.lo < a); return r; }
    
    uint128_t sub (uint64_t a, uint64_t b) {
        uint128_t r; r.lo = a - b; r.hi = - (r.lo > a); return r; }
    
    typedef结构uint128\u t{uint64\u t lo,hi}uint128\t;
    ...
    U
    
    BigInt a, b, c;
    a = BigInt("1233423523546745312464532");
    b = BigInt("45624565434216345i657652454352");
    c = a + b;
    // c = a * b;
    // c = b / a;
    // c = b - a;
    // c = b % a;
    cout << c << endl;
    
    // dynamic memory allocation
    BigInt *obj = new BigInt("123");
    delete obj;
    
    typedef struct uint128_t { uint64_t lo, hi } uint128_t;
    ...
    
    uint128_t add (uint64_t a, uint64_t b) {
        uint128_t r; r.lo = a + b; r.hi = + (r.lo < a); return r; }
    
    uint128_t sub (uint64_t a, uint64_t b) {
        uint128_t r; r.lo = a - b; r.hi = - (r.lo > a); return r; }
    
    __int128 add(__int128 a, __int128 b){
        return a + b;
    }