SolR float(TrieFloatField)存储限制

时间:2016-12-07 13:34:18

标签: php solr binary floating-point

我试图理解浮点数是如何存储在SolR中的。 我在PHP(32位)中的浮点值和SolR中存储的值之间有一个增量。

我在文档中搜索过,#34; SolR"中包含的字段类型:

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

找到了TrieFloatField:

  

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

但我不知道如何估算储值。 以下是我做过的一些测试。 我尝试在float字段中插入的值和结果:

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评估它?

感谢。

2 个答案:

答案 0 :(得分:0)

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

您可以使用IEEE754 Floating Point Conversion之类的转换器来测试您所包含的值,并将它们全部转换为您从Solr获取的值。

浮点数并不准确,并且不是魔术 - 还有2 ^ 32个不同的值可用,所以当您尝试存储不会映射的值时确切地说,32位FP可能代表的可能值,你会得到不准确的。

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

根据您的需要,另一个选项是使用长字段,并在存储值时将乘以10或100,并在出路时除以值。这将允许您准确地表示点后两位数的十进制数。

答案 1 :(得分:0)

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

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

所以,作为使用

的替代方案
$float1 === $float2

可以使用

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

有一个很大的脚注,人们应该记住,减少你的比较准确性。 AFAIK是安全地比较两个花车的唯一方法(除了epsilon方法)。