【问题标题】:SolR float (TrieFloatField) storage limitsSolR float (TrieFloatField) 存储限制
【发布时间】:2016-12-07 13:34:17
【问题描述】:

我试图了解浮点数是如何存储在 SolR 中的。 我在 PHP(32 位)中的浮点值和 SolR 中存储的浮点值之间存在差异。

我在“SolR 包含的字段类型”文档中进行了搜索:

https://cwiki.apache.org/confluence/display/solr/Field+Types+Included+with+Solr

并为 TrieFloatField 找到:

浮点字段(32 位 IEEE 浮点)。精度步=“0” 实现高效的数字排序并最小化索引大小; precisionStep="8"(默认)启用高效的范围查询。

但我不知道如何估计存储值。 这是我所做的一些测试。 我尝试在浮点字段中插入的值和结果:

ok: 2097151.1
ko: 2097152.1 -> 2097152
ko: 20971521 -> 20971520
ok: 16777216
ko: 16777217 -> 16777216
ko: 4294967296 -> 4294967300
ok: 4294967300
ko: 4294967301 -> 4294967300

我不明白使用了哪个约束,它不是四舍五入的。 也许它是一个二元约束,因为它看起来像是被四舍五入以适应 2 的幂。

https://en.wikipedia.org/wiki/Power_of_two#The_first_96_powers_of_two

2^21 = 2,097,152
2^24 = 16,777,216
2^32 = 4,294,967,296 

如您所见,这些值与 SolR 存储的值接近。

有人知道 SolR 商店是如何浮动的吗? 以及如何用 PHP 评估它?

谢谢。

【问题讨论】:

    标签: php solr binary floating-point


    【解决方案1】:

    正如您所提到的,它是一个 32 位浮点数。一个 32 位的浮点数不能准确地表示 0 到 2^32 之间的所有值,所以会出现不准确和无法用这些位表示的数字。

    您可以使用IEEE754 Floating Point Conversion 之类的转换器来测试您包含的值,它们都会转换为您从 Solr 返回的值。

    浮点数并不精确,也不是魔术 - 仍然只有 2^32 个不同的值可用,因此当您尝试存储不完全映射到 32 位 FP 的可能值的值时可以代表,你会得到不准确的。

    引入双精度以具有更高的准确性(64 位与 32 位),您可以在 Solr 中通过使用 TrieDoubleField 来使用双精度。

    根据您的需要,另一种选择是改用长字段,并在存储值时乘以 10 或 100,并在输出时将该值除以。这将允许您在点后用两位数字精确表示十进制数。

    【讨论】:

    • 非常感谢,我会尝试在 PHP 中转置这个 JavaScript 示例。
    • 嗬,我没看到你的链接实际上是使用 .py 文件...所以我不得不自己搜索。
    【解决方案2】:

    显然,比较浮点数最安全的方法是使用 pack()。 将数据打包成二进制字符串以安全地比较两个浮点数。

    http://php.net/manual/en/language.types.float.php#119860

    因此,作为使用的替代方法

    $float1 === $float2
    

    可以使用

    pack('f', $float1) === pack ('f', $float2)
    

    有一个很大的脚注,人们应该真正记住,这是降低你比较的准确性。 AFAIK 是安全比较两个浮点数的唯一方法(除了 epsilon 方法)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      相关资源
      最近更新 更多