拆分64位值以适应双精度参数类型
spliting 64 bit value to fit in argument type of double
我有一个函数,我不能改变语法,说这是一些库函数,我正在调用:
void schedule(double _val);
void caller() {
uint64_t value = 0xFFFFFFFFFFFFFFF;
schedule(value);
}
作为函数调度接受double作为实参类型,在实参值大于52位的情况下(考虑到double将尾数存储为52位值),在这种情况下我将失去精度。
我要做的是,如果该值大于双精度体所能容纳的最大值,我需要循环获取剩余的值,以便最终求和得到正确的值。
void caller() {
uint64_t value = 0xFFFFFFFFFFFFFFF;
for(count = 0; count < X ; count++) {
schedule(Y);
}
}
我需要从变量"值"中提取X和Y。如何才能做到这一点?我的目标是不要因为类型转换而失去精度。
如果您的问题只是在caller
而不是schedule
中失去精度,则不需要循环:
void caller() {
uint64_t value = 0xFFFFFFFFFFFFFFF;
uint64_t modulus = (uint64_t) 1 << 53;
schedule(value - value % modulus);
schedule(value % modulus)
}
在value - value % modulus
中,只有高11位是有效的,因为低53位已经被清除。因此,当转换为double
时,没有错误,并且将准确的值传递给schedule
。同样地,value % modulus
只有53位,并且完全转换为双精度。
(IEEE-754 64位二进制浮点对象的有效位数编码为52位,但由于隐式前导位,实际有效位数为53位)
注意:上面的操作可能会导致调用schedule
时带一个参数为0,我们还没有确定是否允许。如果这是一个问题,那么应该跳过这样的调用。
如果N
是double
可以精确表示的最大积分值,那么显然可以使用
Y = N
和
X = amount / Y
(假设整除)。一旦你完成了对X
的迭代,你仍然需要调度剩余的
R = amount % Y
请记住,所有的整型计算都必须在uint64_t
类型的域中执行,也就是说,你必须为常量(UL
或ULL
)添加适当的后缀,或者使用类型强制转换到uint64_t
,或者使用uint64_t
类型的中间变量。
当然,如果你的程序并不关心schedule
被调用了多少次,只要总数是正确的,那么你可以为N
使用任何值,只要它能被精确地表示。例如,您可以简单地设置N = 10000
。
另一方面,如果你想最小化schedule
调用的次数,那么值得注意的是,由于"隐式1"规则,可以用52位尾数精确表示的最大整数是(1 << 53) - 1
。
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 正在将csv文件读取为双精度矢量
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 如何在C++中的同一函数中使用字符串和双精度
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- 为什么在传递长整型时调用具有两个双精度类型的参数的重载函数?
- 将不同类型的模板参数包提取到双精度向量中会产生警告
- C++双精度作为模板参数的解决方法
- 一元'*'的类型参数无效(有双精度)
- 错误:类型"类特征::张量<双精度,3>"参数提供给"删除",预期指针
- 使用整数模板参数创建编译时双精度
- 如何替换具有双精度类型的模板参数
- 如何使C++函数使用双精度参数或无参数执行
- 具有双精度参数的数组
- 试图将数组作为参数传递,得到双精度[4]到双精度转换错误
- 如何为通过地址传递参数的Windows API调用编写测试双精度
- 以双精度数除以双精度数来获得循环中的余数和char参数不起作用
- 拆分64位值以适应双精度参数类型
- 包含两个双精度的类是 std::complex 参数的有效替代品<double>吗?