我正在尝试执行转换:
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
并仍然产生正确的结果?
答案 0 :(得分:3)
有点古老的学校数学,您可以使用%
来计算余数:
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 //
答案 1 :(得分:1)
将您的部门分解:
r = 1000*(n/factor) + ((n%factor)*1000)/Factor
如果余数溢出(因子很大),你仍然会遇到问题,但如果因子小于MAX_UINT64/1000
你就可以了。