64位溢出数学转换
64-bit overflow math conversion
我正在尝试执行一个转换:
uint64_t factor = 2345345345; // Actually calculated at runtime, but roughly this magnitude
uint64_t Convert(uint64_t num)
{
return num * 1000ULL / factor;
}
对于最大的num
值,在除以factor
之前进行乘法运算。将顺序更改为num / factor * 1000UL
会丢失一些不可接受的精度。
我想重写Convert()
来处理所有可能的num
值:
uint64_t Convert(uint64_t num)
{
if(num > MAX_UINT64/1000ULL) // pseudo code
{
// Not sure what to put here
}
else
{
return num * 1000ULL / factor;
}
}
我们考虑过使用128位数学,但如果可能的话,我们希望避免使用它。
实现Convert()
的最有效方法是什么,以便它能够理想地处理尽可能大的num
并仍然产生正确的结果?
有点老派数学,可以使用%
计算剩余:
uint64_t Convert(uint64_t num)
{
uint64_t m = 1000;
uint64_t a = num / factor;
uint64_t t = num % factor;
uint64_t h = m * t / factor;
return a * m + h;
}
示例:
uint64_t Convert2(uint64_t num)
{
return num * 1000ULL / factor;
}
uint64_t Convert3(uint64_t num)
{
return num / factor * 1000ULL;
}
int main()
{
cout << Convert(std::numeric_limits<uint64_t>::max()) << endl;
cout << Convert2(std::numeric_limits<uint64_t>::max()) << endl;
cout << Convert3(std::numeric_limits<uint64_t>::max()) << endl;
}
输出:
7865257077400 <--- // The correct one //
7865257077 <--- // Value wrapped before multiplication //
7865257077000 <--- // Low accuracy, loses remaining //
分解您的部门:
r = 1000*(n/factor) + ((n%factor)*1000)/Factor
如果余数溢出(因子很大),您仍然可能遇到问题,但如果因子小于MAX_UINT64/1000
,则可以。
相关文章:
- 获取隐式转换溢出从无符号到已签名的警告
- 将公共递归转换为尾递归,因为大型输入的堆栈溢出
- 将字符数组转换为结构时出现问题. 结构的字符数组变量溢出
- 从双精度转换为整数的显式类型是否始终检查整数溢出?
- 将字符串转换为整数类型T,检查是否存在溢出
- 将整型转换为浮点型时检测溢出
- 隐式转换双重到无符号长溢出 c++
- 如何检查溢出将字符*[]转换为无符号短短
- 如何在预处理器 (#if) 中强制转换静态 const 以避免溢出
- 当我尝试将char*转换为C 中的双重溢出时,如何检查双重溢出
- 从指针进行特征3类型的强制转换/复制(溢出uint8_t)
- 将uint32_t转换为int32_t,既没有溢出的风险,也没有过度复杂的风险
- 从毫米到公里的转换(以较小的单位溢出,例如米)
- 64位溢出数学转换
- 在涉及溢出错误的情况下,从int转换为char
- 缩小从double到float的转换:保证溢出行为
- 不同的编译器用来处理数字转换中的溢出的常见策略是什么?
- 隐式常量转换中的溢出[-Woverflow]
- 长类型Max等于int Max error + math.h pow()编译警告:隐式常量转换溢出
- CPP:防止溢出的类型转换