首先,我试图解决的问题是提出一个更好的代表值,这些值将始终保持在范围内均匀分布:
0.0 <= x < 1.0
这样做的动机是尝试减少用于存储此数据的字节数(应用程序占用大量内存并限制I / O带宽)。目前使用的是32位浮点表示,16位浮点表示不够准确。
我最初的想法是尝试将数据存储在16位整数中,并简单地使用该方案:
x/(2^16 - 1) [x is an unsigned short]
为了保持算法大致相同并保持使用相同的浮点硬件操作(至少在开始时),理想情况下我希望继续将此小数表示转换为浮点表示,执行操作(s ),然后转换回分数表示存储。
显然,在这两种完全不同的,不精确的表示之间会有来回的精确度,但对于我们的应用,我怀疑这可能是一种可接受的权衡。我做了一些研究,看看目前的情况可能会给我们一个很好的起点。开创性的&#34;每个计算机科学家应该知道的关于浮点算术的内容&#34;文章(http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)让我看了几个其他人,#34; Beyond Floating Point&#34; (home.ccil.org/~cowan/temp/p319-clenshaw.pdf)就是这样一个例子。
有人能指出人们在其他地方使用过的可能满足这些要求的其他表示形式吗?
我担心表示的准确性有任何潜在的好处(我们目前通过使用这个特定范围浪费了大部分浮点格式)将完全超出要求舍入两次从分数表示到浮点再返回。在这种情况下,可能需要直接使用此分数表示来进行算术运算以从该方法中获得任何好处。关于这一点的任何建议都会有所帮助吗?
答案 0 :(得分:4)
请勿使用2^16-1
。使用2^16
。是的,你的精度会略微降低并浪费你的0xFFFF
,但是你可以保证在转换到浮点时没有精度损失。 (相反,当从浮点转换时,你将失去8位的mantissal精度。)
精度之间的往返转换可能会导致某些操作出现问题,尤其是逐步求和数字。如果可能的话,将定点值视为“脏”,不要将它们用于进一步的浮点计算;更喜欢从输入重新计算到使用定点形式的中间结果。
或者,使用24位。使用此表示形式,只要您的值不下溢(即,只要它们高于2^-24
),您就不会在任何方向上失去任何精度。
答案 1 :(得分:1)
1 / x不会在你的范围内分布不均匀吗? 1/2 1/3 1/4 ..你不想代表1/2以上的数字吗?
为了节省空间,这种事情在Netcdf中完成了很多编码数据。
const double scale = 1.0/65536;
unsigned short x;
x中的任何数字都是x * scale
请参阅NetCDF中的示例,了解使用比例和偏移的更一般方法:http://www.unidata.ucar.edu/software/thredds/current/netcdf-java/tutorial/NetcdfDataset.html
答案 2 :(得分:0)