7

我有一种情况需要 afloat以单个char. 这个 'minifloat' 需要表示的范围是 0 到 10e-7,所以我们总是可以假设数字为 +ve,指数为 -ve 以节省空间。

我考虑过的表示是 3 位指数和 5 位尾数(隐含 1 位),指数以 10 为底,即x = man * 10^exp.

要将浮点数转换为我的 minifloat,我计划使用frexp,并使用一些数学将基数 2 转换为基数 10。

这是一个明智的做法吗?还是有更好的方法来实现这一目标?

4

4 回答 4

9

您是否真的需要该值是浮点数(即随着值的缩放具有大致恒定的精度)?你打算如何处理这些值?

一个更简单(也更有效)的想法是将 8 位解释为隐含比例为 1e-7 的无符号定点数。IE:

float toFloat(uint8_t x) {
    return x / 255.0e7;
}

uint8_t fromFloat(float x) {
    if (x < 0) return 0;
    if (x > 1e-7) return 255;
    return 255.0e7 * x; // this truncates; add 0.5 to round instead
}
于 2012-08-13T13:29:02.330 回答
4

如果它符合您的目的,那么使用存储或传输格式等格式是合理的,即在小空间中记录数据。您应该验证这种格式的舍入误差对于您的需求来说不是太大,范围是否合适等等。

这不是一个好的计算格式,因为它在普通硬件上会很慢。

我不明白你会做什么基础转换。如果您在 a 中有一个 IEEE-754 浮点数float,那么转换为 8 位格式或从您的 8 位格式转换的工作是在转换为较窄格式时舍入有效数字(小数)和调整指数偏差,加上处理特殊情况(反规范、溢出、NaN)。这将只涉及二进制算术,而不是十进制。

顺便说一句,请注意浮点数的小数部分的正确术语是“小数”或“有效数”(IEEE-754 标准中使用的术语)。“尾数”是对数的小数部分。

于 2012-08-13T13:25:09.893 回答
4

另一种方法是使用 256 个浮点(或双精度)的静态数组,您将根据自己的标准进行选择。

然后转换 unsigned char -> float/double 是微不足道的......

转换 float/double-> unsigned char 有点复杂(在静态数组中找到最近的浮点数);与简单的二进制搜索算法进行大约 8 次比较,但根据您在静态数组中选择值的方式,您可能会发现更好。

当然,操作将使用本机浮点/双精度执行。

于 2012-08-13T14:49:26.290 回答
1

5 个尾数位为您提供从 1.00 到 9.00 的 32 种不同情况,最小步长为 0.25

1.00 1.25 1.50 1.75 2.00 .... 8.75 9.00

3 个指数可以给你 8 种不同的情况 10^0(即 1) 10^-2 10^-3 10^-4 ....最后 10^-7

你的分数部分的误差是 0.25。如果您的计算可以补偿此错误,那么您可以使用它。

于 2012-08-13T13:33:43.677 回答