【问题标题】:Smart bit encoding of floating point values (float, double)浮点值的智能位编码(float、double)
【发布时间】:2016-09-07 12:53:02
【问题描述】:

假设我有一个浮点值数组,它目前是我在磁盘加载和包大小限制方面的瓶颈。给定以下 3 个输入,我如何对这些值进行编码以减少数据大小:

  • 绝对误差:我可以删除任何尾数位,只要最终值与实际值相差这个数量(这是设计使然,它是基于屏幕错误的数据可视化)李>
  • 最小浮点值:数组中的最小值
  • 最大浮点值:数组中的最大值

注意:如果float值太小,它只会被转换为0(因为使用绝对误差,整个尾数被删除,对于太大的数字,尾数就被留下原封不动)。

浮点值出现的顺序很重要(它不仅仅是点云)。所以无论是哪种编码,解码后的顺序都应该保留。

现在我无法成功保存尽可能多的位:

我可以使用 Min/Max 值在指数字段中保存 3 到 5 位,但我无法利用绝对误差,也无法利用 Min/Max 值中的额外位。 如果 Max 值不太大,我也可以从 1 到 3 个尾数位减少,但在这里我再次没有最佳地使用 3 个输入。

我不是在寻找压缩,只是为了更好的编码(包已经是 7 压缩包)。另请注意,我指的是常规 float 和 double 值,您可以在 C# 和 C++ 中找到。

重要通知: 当 IEEE 浮点数中的指数足够大时,绝对误差会变得大于我用作输入的值(项目符号列表中的第一个点)。这不是问题,因为无论如何数据以浮点开始和结束。相反,重要的是在尾数中丢弃无用的位。

我已经尝试过定点数,它们可以工作,但只能达到一定程度。(请参阅对 tera 答案的评论)。

【问题讨论】:

  • 为什么不考虑为手头的数据量身定制的自定义压缩,或者可能结合与 ZIP 等通用压缩。也许看看:Martin Burtscher 和 Paruj Ratanaworabhan,“FPC:双精度浮点数据的高速压缩器”,*IEEE Trans.比较,卷。 58,第 1 期,2009 年 1 月,第 18-31 页。

标签: encoding floating-point


【解决方案1】:

在我看来,您好像在寻找 fixed-point representation。减去最小值,除以绝对误差限制的两倍,然后四舍五入到最接近的整数。

【讨论】:

  • 如果我将 4096 空间分成 2^24 部分,我得到的错误是 0,00024,这已经低于我目前的好并节省了 8 位。然而,对于某些“边缘”情况,例如空间 2^14 分为 2^28 部分,我使用上述原始结果节省了更多位,并且我有更高的精度。固定精度有效,但仅在某些情况下有效。期待更好的解决方案(隐含地,对于某些数字,IEEE 浮点数不能授予小于要求的绝对误差,对不起,我不得不提一下,)
  • 那是因为即使是一个完整的单精度数字也没有精确地将空间分成 2^28 部分的精度。在这种情况下,您可以枚举单精度浮点值可以映射到的定点表示的所有值。然而,可能值得看看您的计算是否真正达到了您所追求的准确性。
  • 定点的问题是不能在不牺牲低位的情况下表示大数字,从而在需要的地方失去很多精度。但是,您给了我将指数存储在单独数组中的想法,这可能会有所帮助。我会告诉你的:)
  • “定点的问题是不能在不牺牲低位的情况下表示大数” - 这实际上是浮点数(具有固定尾数大小)的属性,而不是定点数。
  • 我的说法仍然正确 XD。如果我牺牲所有小数位,1 万亿将需要 39/40 位的定点。但如果我想保留小数位,它需要更多。如果我已经有 4 个小数位并且我想最多使用 24 位,你会发现我可以在定点中拥有的最大数字不是那么大。我知道我们都知道浮点和定点的工作原理 XD 只是猜测我们没有正确地相互沟通。
【解决方案2】:

如果您专门为大型网格存储顶点位置数据,您还可以使用其他一些肮脏的技巧。哪种技巧效果最好取决于您将遇到的顶点云的类型。

我见过的关卡数据的一个简单技巧(医生讨厌他!)是通过顶点的符号和指数来划分顶点。例如,您将有一个专门用于 +x、-y、+z 顶点的 bin,其指数分别为 138、140 和 131。然后存储运行的符号和指数(27 位)、运行中的顶点数以及每个的尾数三元组(69 位)。这里的压缩率并不惊人,但它是一种易于实现的方法。

同样,您可以存储附近顶点的运行,并使用 Golomb-Rice 编码来指定每对之间的增量。这更复杂,需要仔细调整和聚类,但可能会产生极好的压缩比。

【讨论】:

    【解决方案3】:

    如果您关心绝对误差,而不是相对误差,则不应使用浮点数。浮点在限制绝对误差方面很糟糕;在高幅度时,它无法达到所需的界限,而在低幅度时,它会浪费你不关心的精度。

    您说在定点中“不牺牲低位就无法表示大数”,但这与定点与浮点无关。如果您有 n 位,并且需要 ε 的最大绝对误差,您将永远无法表示大于 ε*2^(n+1) 的幅度范围。但是如果你使用浮点数,n 会更小,因为你在指数而不是尾数上花费位。在不违反您的错误界限的情况下,这永远不会扩大您的幅度范围。

    如果您有一个绝对范围和一个绝对误差界限,并且关注表示而不是计算,那么客观上定点是您能做的最好的。如果您认为在这种特定情况下浮点比定点具有优势。

    哦,请注意,所有这些都适用,即使您已经在中间浮点存储中失去了计算精度。如果您完全违反了错误界限,那么显然需要修复的是计算。否则,您得到的值最好存储为定点而不是浮点。

    【讨论】:

    • 完全偏离主题,你的最后一段正是我在最后两段中用不同的词写的。虽然我无法完全解释域应用程序,但我认为发布必要条件就足够了。问题是浮点根本不起作用,因为幅度范围太大,什么会产生更大的误差?最小尾数位大于绝对误差的浮点数,还是刚刚超出可能值的定点范围的定点值? ;) 我发誓更大的错误是固定点。我不得不接受妥协。
    • 顺便说一句,它是 3D 数据的可视化,所以:如果数据是在原点附近建模的,我必须使用足够小的误差来保持在误差像素内。如果数据足够远,那没关系,因为即使浮点分辨率大于单个像素误差,3D 模型已经“正确”(只是因为 3D 建模者在该位置放置了一个顶点,这意味着该位置是好的艺术家,无论是否高于或没有一个像素的位置错误)。取而代之的是,对于靠近原点的数据,单个像素的错误变得非常明显。我只是丢掉无用的部分。
    • @DarioOO 听起来,那么,您实际上想要绑定相对误差,而不是绝对误差?
    猜你喜欢
    • 1970-01-01
    • 2015-03-23
    • 1970-01-01
    • 1970-01-01
    • 2010-11-16
    • 1970-01-01
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多