半精确多倍似乎会产生错误的结果
half precision muliplication seems to produce wrong result
首先,IEEE754半精度浮点数使用16位。它使用 1 位符号、5 位指数和 10 位尾数。实际值可以计算为符号 * 2^(指数-15( * (1+Mantisa/1024(。
我正在尝试使用半精度运行图像检测程序。原始程序使用单精度 (=float(。我在 http://half.sourceforge.net/中使用半精度类。使用类一半,我至少可以运行相同的程序。(通过使用 half 而不是 float 并使用 g++ 而不是 gcc 进行编译,并且在许多类型转换之后......
我发现了一个乘法似乎错误的问题。
这是查看问题的示例代码(要打印半精度数字,我应该将其转换为浮点以查看值。 并且在半整数和整数的操作中不会发生自动铸造,所以我放了一些铸件..(
#include <stdio.h>
#include "half.h"
using half_float::half;
typedef half Dtype;
main()
{
#if 0 // method 0 : this makes sx 600, which is wrong.
int c = 325;
Dtype w_scale = (Dtype)1.847656;
Dtype sx = Dtype(c*w_scale);
printf("sx = %fn", (float)sx); // <== shows 600.000 which is wrong.
#else // method 1, which also produces wrong result..
int c = 325;
Dtype w_scale = (Dtype)1.847656;
Dtype sx = (Dtype)((Dtype)c*w_scale);
printf("sx = %fn", (float)sx);
printf("w_scale specified as 1.847656 was 0x%xn", *(unsigned short *)&w_scale);
#endif
}
结果如下所示:
w_scale = 0x3f63
sx = 600
sx = 0x60b0
但 sx 应该是 325 * 1.847656 = 600.4882。可能出了什么问题?
补充:当我第一次发布这个问题时,我没想到这个值正好是 600.4882,而是接近它。后来我发现半精度,其限制是只表示 3~4 个有效数字,乘法的最接近值刚刚证明只有 600.00。虽然大家都知道浮点有这种局限性,但有些人会像我一样犯一个错误,忽略了半精度只能有3~4个有效数字的事实。所以我认为这个问题值得未来的提问者去看。(在stackoverflow中,我认为有些人只是将每个问题都视为同一个旧问题,而实际上情况略有不同。有几个类似的问题并没有什么坏处。
我想出了原因。半精度的有效精度约为log10(2^10(~3或4位。我希望将sx
打印为 600.488 或接近的内容,但这不能用半精度表示。 这部分是在图像预处理过程中完成的,无需 16 位精度(我们的暂定硬件(,所以我可以在这个阶段只使用浮点运算。
补充 :这种异常是在图像尺寸计算过程中出现的,在这种情况下,我们没有任何理由使用 16 位浮点数。仅图像数据(像素或特征图数据(应使用 16 位浮点数。写了这篇文章,这是一个一般规则。
- 如何修复循环中的错误产生的错误结果?
- 添加可变参数函数的错误结果
- 使用特征 3 线性系统求解器的错误结果
- 按位包含 OR 的错误结果
- 如果我将索引变量更改为零,并且合并函数中的k = 0,则获得合并排序的错误结果
- STD :: FPCLASSIFY的错误结果使用Valgrind进行长时间的双重双重结果
- 视觉工作室的错误结果
- 将C#struct传递给C 不受管理的DLL返回错误结果
- 最长的常见子字错误结果
- 华氏度到摄氏度的错误结果
- UE4中简单坐标变换的错误结果
- 记忆错误结果的说明[编译器行为]
- 如何解决错误PRJ0002:错误结果 -1073741515从"cl.exe"返回?
- 错误 PRJ0002:错误结果 -1073741515 从"C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\cl.
- glGetUniformLocation OpenGL ES 2.0(在ipad 3 iOS 7.0.3上返回错误结果)
- 在模板函数中调用std::for_each时出现错误结果
- 使用copy和back_inserter将矢量附加到其自身时出现错误结果
- CUDA 线程在全局内存中的私有位置写入时出现错误结果
- 来自 c++ 代码的错误结果
- 使用浮点值和铸造的算术运算的错误结果 - 差异很大,我想这不是准确值的情况(429497)?