C 64位数学运算,无任何数据或精度损失
我相信128位数据没有任何可移植的标准数据类型。因此,我的问题是如何高效地使用现有的标准数据类型执行64位操作而不丢失数据 例如:我有以下两个uint64_t类型变量: uint64_t x=-1; uint64_t y=-1 现在,如何存储/检索/打印数学运算的结果,例如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
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;
}