4

文档并没有真正解释他们的行为Float32以及Float64不鼓励他们的原因。

我问这个问题是因为我在将这些与控制台 cli 请求或 Rest 请求一起使用时看到了奇怪的行为。无论精度如何,发送到 clickhouse 的浮点值都会在最后一位略微修改。

示例:1258.021545成为1258.0215453.

每次我插入这些值时,最后一个数字都会改变。我不认为问题来自于太高的精度值,因为这些值来自 Java 双精度值。

4

2 回答 2

1

浮点数问题

通常,浮点数的计算可能会产生舍入误差。

爪哇

请考虑学习Java 编程语言中(double浮点型)和(浮点)之间的区别。BigDecimal

例如,有一个相关的问题:java - Double vs. BigDecimal?- 堆栈溢出

点击屋

Float32、Float64 | ClickHouse 文档

使用浮点数

  • 浮点数的计算可能会产生舍入误差。

    SELECT 1 - 0.9
    
    ┌───────minus(1, 0.9)─┐
    │ 0.09999999999999998 │
    └─────────────────────┘
    
  • 计算的结果取决于计算方法(计算机系统的处理器类型和架构)。

  • 浮点计算可能会产生诸如无穷大 (Inf) 和“非数字” (NaN) 之类的数字。在处理计算结果时应考虑到这一点。

  • 从文本中解析浮点数时,结果可能不是最接近的机器可表示的数字。

一些可能的解决方案

使用整数(推荐)

Float32、Float64 | ClickHouse 文档

我们建议您尽可能以整数形式存储数据。例如,将固定精度数字转换为整数值,例如货币金额或页面加载时间(以毫秒为单位)。

使用十进制数

十进制 | ClickHouse 文档

十进制(P,S),十进制32(S),十进制64(S),十进制128(S),十进制256(S)

在加法、减法和乘法运算期间保持精度的有符号定点数。对于除法,最低有效数字被丢弃(不四舍五入)。

参数

  • P——精度。有效范围:[ 1 : 76 ]。确定数字可以有多少个十进制数字(包括小数)。
  • S - 规模。有效范围:[ 0 : P ]。确定分数可以有多少个十进制数字。

<…>

十进制值范围

  • Decimal32(S) - ( -1 * 10^(9 - S), 1 * 10^(9 - S) )
  • Decimal64(S) - ( -1 * 10^(18 - S), 1 * 10^(18 - S) )
  • Decimal128(S) - ( -1 * 10^(38 - S), 1 * 10^(38 - S) )
  • Decimal256(S) - ( -1 * 10^(76 - S), 1 * 10^(76 - S) )

例如,Decimal32(4) 可以包含从 -99999.9999 到 99999.9999 的数字,步长为 0.0001。

于 2021-07-10T17:58:53.883 回答
1

ClickHouse 文档反对的唯一原因Float舍入错误。它与 ClickHouse 本身无关,而是实数表示的算法。

  • 如果您不介意时不时出现一些舍入错误,请继续使用浮点数。
  • 但是如果你存储代表金钱的数字,花车是一个禁区。在这种情况下,将两个不同字段中小数点左右的部分存储为整数。
于 2017-12-31T10:20:26.587 回答