如何在C中将浮点数(float 32)转换为半浮点数(float 16),同时考虑NaN,Infinity等边缘情况。
我不需要算术,因为我只需要类型来满足支持它们的要求。所以半类型可以是uint16_t
或对应的typedef
。我只在C中找到了一些方法,或者一些没有考虑到NaN等边缘情况的方法。
我需要将一个float转换成一个half类型,它可以表示为一个简单的uint16_t
,这个uint16_t
应该只包含half的二进制表示,因为我不会对它进行算术运算。我需要这个,这样我就可以满足图书馆的要求。我不能使用现有的实现,因为它们是作为共享库构建的(也主要是C),在这种情况下我不能使用。此外,GCC/Clang __fp16
和_Float16
将无法工作,因为我将代码编译为将在隔离环境中运行的Web程序集,因此无法使用本机依赖代码(无WASI)(并且EMCC在使用_FloatXX
类型时抛出错误)。
3条答案
按热度按时间g9icjywg1#
您有多种选择:
1.使用现有的实施例,例如来自Industrial Light & Magic的那个还有一些其他的impl。
1.使用一个固有的,例如对于Intel CPU,您有_mm_cvtps_ph和_mm_cvtph_ps,它们一次最多可以转换4个值。
1.使用自己的IEEE 754浮点格式知识编写,并使用了一半。
编辑:由于您主要是想来回转换,因此在ILM代码中要查看的两个函数是:Float to half: Line 85和half to float: line 62
vjrehmav2#
16位到32位转换的代码是here。
下面是快速编写的32位到16位转换的测试代码,主要基于算法here。我现在没有时间把它适当地记录下来,它可以改进。测试不检查NaN的有效载荷位(在有效数字段中)的处理。
字符串
qvtsj1bj3#
下面我展示了一个
float
到half
转换的ISO-C99实现,它已经过详尽的测试。以下假设适用:float
Map到IEEE-754binary32
,而half
Map到IEEE-754binary16
;浮点和整数数据类型在存储时使用相同的字节序;转换到更窄的浮点类型应利用舍入模式 * 到最近或偶数 *。作为黄金参考,测试框架使用2011年引入的x86-64指令集扩展
F16C
,以支持半精度(FP 16)作为存储类型。IEEE-754 NaN处理包含一些架构特定元素,下面的float2half_rn()
函数旨在模拟x86-64行为。调整,例如切换到使用单个规范NaN编码,是微不足道的。下面的代码来自我以前在BSD许可证here下发布的代码。我使用英特尔编译器版本13.1.3.198 Build 20130607来构建此代码,并在IvyBridge CPU上运行了详尽的测试。
字符串