浮点的替代方法,用于存储简单的小数值
An Alternative to Floating-Point for Storing Simple Fractional Values
首先,我试图解决的问题是为始终在范围内均匀分布的值提出更好的表示:
0.0 <= x < 1.0
这样做的动机是尝试减少用于存储此数据的字节数(应用程序内存和 I/O 带宽受到严重限制)。目前使用的是 32 位浮点表示,16 位浮点表示被证明不够准确。
我最初的想法是尝试将数据存储在 16 位整数中,并简单地使用该方案:
x/(2^16 - 1) [x is an unsigned short]
为了保持算法基本相同并保留使用相同的浮点硬件操作(至少一开始),理想情况下,我希望继续将此分数表示转换为浮点表示,执行操作,然后转换回分数表示以进行存储。
显然,在这两种完全不同的、不精确的表示之间来回会损失精度,但对于我们的应用程序,我怀疑这可能是一个可以接受的权衡。
我已经做了一些研究,看看目前的情况可能会给我们一个很好的起点。开创性的"每个计算机科学家都应该知道的关于浮点算术"的文章(http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)让我看了其他一些,"超越浮点"(home.ccil.org/~cowan/temp/p319-clenshaw.pdf)就是这样一个例子。
谁能指出人们在其他地方使用的其他可能满足这些要求的表示示例?
我担心表示准确性的任何潜在收益(我们目前使用这个特定范围浪费了大部分浮点格式)将被从分数表示到浮点表示两次并再次舍入的要求完全抵消。在这种情况下,可能需要直接使用这种分数表示进行算术,以便从这种方法中获得任何好处。关于这一点的任何建议会有所帮助吗?
不要使用 2^16-1
.使用2^16
.是的,您的精度会略低并浪费您的0xFFFF
,但您将保证在转换为浮点数时精度不会损失。(相反,当从浮点转换时,您将失去 8 位尾数精度。
精度之间的往返转换可能会导致某些运算出现问题,尤其是渐进式求和数字时。如果可能的话,将定点值视为"脏",不要将它们用于进一步的浮点计算;更喜欢从输入重新计算,而不是使用定点形式的中间结果。
或者,使用 24 位。使用此表示形式,只要您的值不下溢(即,只要它们高于 2^-24
),您就不会在任一方向上丢失精度。
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
请查看本页的"打包数据值"部分:
https://www.unidata.ucar.edu/software/netcdf/docs/BestPractices.html#Packed%20Data%20Values
- 将字符串存储在c++中的稳定内存中
- 在c++中用vector填充一个简单的动态数组
- std::原子加载和存储都需要吗
- (C++)分析树以计算返回错误值的简单算术表达式
- C++:将控制台输出存储在宏中更好吗
- 我的简单if-else语句是如何无法访问的代码
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 引发未经处理的异常:简单 C++ 程序中的读取访问冲突,动态增加数组长度以存储数字
- 简单的 CPP 地图存储和访问无法按预期工作
- 将unique_ptr存储在堆上的最简单方法是什么
- 尝试在C 程序中设置简单的键盘输入.使用变量存储True或false
- 浮点的替代方法,用于存储简单的小数值
- 将对象引用存储在一个简单的容器中
- 无锁简单隔离存储算法
- 简单的银行账户程序无法正确存储余额
- 简单的程序:存储数据从一个文件到一个结构数组
- 存储抽象成员,保持接口简单
- C++11 在map<key,value>中存储值(整数和字符串)的多种数据类型的最简单方法?
- 存储可通过键或序号 C++ 访问的数据的简单有效方法