在C中将float64转换为uint64时有精度损失吗?假设只有数据的整数部分是有意义的
我有一个来自TCP协议的计数器字段,用于跟踪发送的样本。它被定义为float64。我需要将此协议转换为另一个协议,其中计数器定义为uint64 我能否安全地将float64值存储在uint64中,而不会丢失数据整数部分的任何精度?假设分数部分可以忽略 编辑:对不起,如果我没有描述清楚。没有代码。我只是在看两个不同的协议文档,看看一个是否可以翻译成另一个 请将float64视为double,文档编写得不好,而且非常旧在C中将float64转换为uint64时有精度损失吗?假设只有数据的整数部分是有意义的,c,binary,primitive-types,C,Binary,Primitive Types,我有一个来自TCP协议的计数器字段,用于跟踪发送的样本。它被定义为float64。我需要将此协议转换为另一个协议,其中计数器定义为uint64 我能否安全地将float64值存储在uint64中,而不会丢失数据整数部分的任何精度?假设分数部分可以忽略 编辑:对不起,如果我没有描述清楚。没有代码。我只是在看两个不同的协议文档,看看一个是否可以翻译成另一个 请将float64视为double,文档编写得不好,而且非常旧 非常感谢。我假设您询问的是64位浮点值,如中所述的IEEE Binary64 将
非常感谢。我假设您询问的是64位浮点值,如中所述的IEEE Binary64 将表示为64位IEEE浮点值的
double
转换为uint64_t
不会丢失该值的整数部分的任何精度,只要该值本身为非负且小于264。但是,如果该值大于253,则表示为double
不允许完全精确,因此导致该值的任何计算都可能是不准确的
请注意,反之为假,IEEE浮点的精度低于64位uint64\u t
,因此接近但不同的大值将转换为相同的双
值
请注意,实现为64位双精度的计数器本质上受到浮点类型精度的限制。将大于253的值增加1可能根本没有效果。使用浮点类型实现数据包计数器似乎是一个非常糟糕的主意。直接使用uint64\t
计数器似乎更安全。你只需要担心264的环绕度,这是一个你可以在不太可能的情况下检查的条件,在这种情况下,你实际上会期望数到那么远
如果无法更改格式,请验证浮点值是否在转换范围内,如果不在以下范围内,请存储适当的值:
#include <stdint.h>
...
double v = get_64bit_value();
uint64_t result;
if (v < 0) {
result = 0;
} else
if (v >= (double)UINT64_MAX) {
result = UINT64_MAX;
} else {
result = (uint64_t)v;
}
#包括
...
双v=获取64位的值();
uint64_t结果;
if(v<0){
结果=0;
}否则
如果(v>=(双)UINT64_最大值){
结果=UINT64_最大值;
}否则{
结果=(uint64_t)v;
}
我假设您询问的是64位浮点值,如中所述的IEEE Binary64
将表示为64位IEEE浮点值的double
转换为uint64_t
不会丢失该值的整数部分的任何精度,只要该值本身为非负且小于264。但是,如果该值大于253,则表示为double
不允许完全精确,因此导致该值的任何计算都可能是不准确的
请注意,反之为假,IEEE浮点的精度低于64位uint64\u t
,因此接近但不同的大值将转换为相同的双
值
请注意,实现为64位双精度的计数器本质上受到浮点类型精度的限制。将大于253的值增加1可能根本没有效果。使用浮点类型实现数据包计数器似乎是一个非常糟糕的主意。直接使用uint64\t
计数器似乎更安全。你只需要担心264的环绕度,这是一个你可以在不太可能的情况下检查的条件,在这种情况下,你实际上会期望数到那么远
如果无法更改格式,请验证浮点值是否在转换范围内,如果不在以下范围内,请存储适当的值:
#include <stdint.h>
...
double v = get_64bit_value();
uint64_t result;
if (v < 0) {
result = 0;
} else
if (v >= (double)UINT64_MAX) {
result = UINT64_MAX;
} else {
result = (uint64_t)v;
}
#包括
...
双v=获取64位的值();
uint64_t结果;
if(v<0){
结果=0;
}否则
如果(v>=(双)UINT64_最大值){
结果=UINT64_最大值;
}否则{
结果=(uint64_t)v;
}
是,精度丢失。负数不能正确转换为uint64(因为此类型是无符号的),以及大于2^64-1的数字。在所有其他情况下,转换都是精确的(前提是您将float64值视为精确的,并且舍入操作正确)。是的,精度会丢失。负数不能正确转换为uint64(因为此类型是无符号的),以及大于2^64-1的数字。在所有其他情况下,转换都是精确的(前提是您将float64值视为精确的,并且舍入操作正确)。没有float64
输入C。请更精确。显示你的代码。什么样的疯子使用浮点类型作为计数器?它来自国防工业的一家老公司。C中没有float64
类型。请更精确一些。显示您的代码。什么样的疯子使用浮点类型作为计数器?它来自国防工业的一家老公司。您的意思是2^53吗?从技术上讲,如果该值大于2^53且小于2^64,则浮点类型中的精度已经丢失。转换不会导致损失。如果(v>(双精度)UINT64\u MAX)
-测试可能不充分。请注意,UINT64_MAX
设置了所有位,因此它的每个右移位都是奇数。因此,转换为double
将在默认的四舍五入模式下四舍五入到最接近的偶数模式。你看到了吗?我明白了。在我们的应用程序中,要计数的项目数不会超过2^53。谢谢大家!@EOF:我猜将UINT64\u MAX
转换为double
将产生0x1p64
,因此比较肯定是=
。谢谢。您的意思是2^53吗?从技术上讲,如果该值大于2^53且小于2^64,则浮点类型中的精度已经丢失。转换不会导致损失。如果(v>(双精度)UINT64\u MAX)
-测试可能不充分。N