将浮点数保存为整数而不会丢失浮点精度

时间:2015-04-25 15:08:22

标签: c++

我想将一个名为f的浮点变量的值保存在名为i的数组的第三个元素中,其方式是不擦除浮点部分(即我不想要保存1而不是1.5)。之后,以我们在输出中看到1.5的方式完成最后一行(不要使用cout<<1.5;cout<<f;或类似的技巧!)

float f=1.5;
int i[3];
i[2] = ... ;
cout<<... ; 

有人有任何想法吗?

3 个答案:

答案 0 :(得分:4)

如果在编译环境中具有相同的大小,则使用union类型 - 惩罚:

static_assert(sizeof(int) == sizeof(float));

int castFloatToInt(float f) {
    union { float f; int i; } u;
    u.f = f;
    return u.i;
}

float castIntToFloat(int i) {
    union { float f; int i; } u;
    u.i = i;
    return u.f;
}

// ...

float f=1.5;
int i[3];
i[2] = castFloatToInt(f);
cout << castIntToFloat(i); 

使用union是防止别名问题的方法,否则编译器可能会因优化而生成错误的结果。

这是一种直接操作浮点数的常用技术。虽然通常会使用uint32_t代替。

答案 1 :(得分:2)

一般来说,您不能在float中存储int而不会丢失精确度 您可以将您的数字乘以一个因子,然后将其存储在该除数之后再次得到一些小数位 请注意,这不适用于所有数字,您必须仔细选择您的因素。

float f = 1.5f;
const float factor = 10.0f;
int i[3];
i[2] = static_cast<int>(f * factor);
std::cout << static_cast<float>(i[2]) / factor;

答案 2 :(得分:1)

如果我们可以假设int是32位,那么你可以用类型惩罚来做到这一点:

float f = 1.5;
int i[3];
i[2] = *(int *)&f;
cout << *(float *)&i[2];

但这是进入未定义的行为区域(打破别名规则),因为它通过指向不同(不兼容)类型的指针访问类型。

LIVE DEMO