为什么双字段的总和要超过2个小数位

时间:2018-07-23 23:47:37

标签: elasticsearch

我正在评估elascticsearch,并生成了一堆假数据。 数量字段定义为双精度。 这是映射 “ authamount”:{“ type”:“ double”},等等...

在执行随机数的Java代码中,我指定了2个小数位,并且Elasticsearch中的数据看起来还可以。

当我按如下方式运行统计查询时:

{
    "query" : { "constant_score": { "filter": {
                "range": {
                    "txndatestring": {
                        "gte": "2017-01-01T15:44:04.068Z",
                        "lte": "2017-01-31T15:44:04.068Z"
                    }
                }
            }
        }
    },
    "aggs" : {  "auth_amount_stats" : { "stats" : { "field" : "authamount" } }
    }
}

我看到这个结果:

"aggregations": {
        "auth_amount_stats": {
            "count": 20810,
            "min": 5.03,
            "max": 1474.24,
            "avg": 734.682198942815,
            "sum": 15288736.559999982
        }}

我不明白总和如何才能有这么多小数位。

1 个答案:

答案 0 :(得分:1)

浮点十进制值通常没有确切的二进制表示形式。这是由于CPU表示浮点值的方式。通常这并不重要,可以通过在显示数字时四舍五入到小数点后的适当位数来解决。但是,当执行诸如Sum之类的算术运算时,您的小数点后两位数字与其内部浮点表示之间的微小差异会加重。

因此,在比较浮点数时必须小心。例如,由于精度损失,您的Sum不会严格等于15,288,736.56,即使那是作为十进制值的Sum。

您可以使用scaled_float来表示您的两位十进制数字:

    "authamount": {
      "type": "scaled_float",
      "scaling_factor": 100
    }

缩放的浮点数存储为long,并按double的因子进行缩放,因此效率更高。