我试图理解浮点数是如何存储在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评估它?
感谢。
答案 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方法)。