简体   繁体   English

为什么不鼓励在 ClickHouse 表中使用浮点表示?

[英]Why floating point representation are discouraged in ClickHouse tables?

The documentation is not really explaining the behavior of the Float32 and Float64 and why they are discouraged.文档并没有真正解释Float32Float64的行为以及为什么不鼓励它们。

I'm asking this question because I'm seeing strange behavior when using theses with console cli requests or Rest requests.我问这个问题是因为在将论文与控制台 cli 请求或 Rest 请求一起使用时,我看到了奇怪的行为。 Float values that are sent to clickhouse are slightly modified at the last digit, whatever the precision is.无论精度如何,发送到 clickhouse 的浮点值都会在最后一位稍作修改。

Example: 1258.021545 became 1258.0215453 .示例: 1258.021545变成1258.0215453

Each time I insert these values, the last digit is changed.每次我插入这些值时,最后一位数字都会改变。 I don't think the problem comes from a too high precision value because these values come from Java doubles.我不认为问题来自太高的精度值,因为这些值来自 Java doubles。

The only reason why ClickHouse documentation dicourages Float is arounding error . ClickHouse 文档不鼓励Float的唯一原因是舍入错误 It's has nothing to do with the ClickHouse itself, but rather an algorithm for real number representations .它与 ClickHouse 本身无关,而是一种用于实数表示的算法。

  • If you don't mind some rounding errors every now and then, go ahead and use floats.如果您不介意不时出现一些舍入错误,请继续使用浮点数。
  • But shall you store numbers representing money, floats are a no-go zone.但是你应该存储代表金钱的数字,浮动是一个禁区。 In this case store parts left and right to the decimal point in two different fields as integers.在这种情况下,将两个不同字段中小数点左右的部分存储为整数。

Floating-point numbers problem浮点数问题

Generally, computations with floating-point numbers might produce a rounding error.通常,使用浮点数进行计算可能会产生舍入误差。

Java爪哇

Please, consider learning the difference between double (a floating binary point type) and BigDecimal (a floating decimal point type) in the Java programming language.请考虑学习 Java 编程语言中double (一种浮点二进制小数点类型)和BigDecimal (一种浮点小数点类型)之间的区别。

For example, there is a related question: java - Double vs. BigDecimal?例如,有一个相关的问题: java - Double vs. BigDecimal? - Stack Overflow . - 堆栈溢出

ClickHouse点击之家

FromFloat32, Float64 |来自Float32, Float64 | ClickHouse Documentation : ClickHouse 文档

Using Floating-point Numbers使用浮点数

  • Computations with floating-point numbers might produce a rounding error.使用浮点数进行计算可能会产生舍入误差。

     SELECT 1 - 0.9 ┌───────minus(1, 0.9)─┐ │ 0.09999999999999998 │ └─────────────────────┘
  • The result of the calculation depends on the calculation method (the processor type and architecture of the computer system).计算结果取决于计算方法(计算机系统的处理器类型和架构)。

  • Floating-point calculations might result in numbers such as infinity (Inf) and “not-a-number” (NaN).浮点计算可能会产生无穷大 (Inf) 和“非数字”(NaN) 等数字。 This should be taken into account when processing the results of calculations.在处理计算结果时应考虑到这一点。

  • When parsing floating-point numbers from text, the result might not be the nearest machine-representable number.从文本中解析浮点数时,结果可能不是最接近的机器可表示数。

Some possible solutions一些可能的解决方案

Use integer numbers (recommended)使用整数(推荐)

FromFloat32, Float64 |来自Float32, Float64 | ClickHouse Documentation : ClickHouse 文档

We recommend that you store data in integer form whenever possible.我们建议您尽可能以整数形式存储数据。 For example, convert fixed precision numbers to integer values, such as monetary amounts or page load times in milliseconds.例如,将固定精度数字转换为整数值,例如货币金额或以毫秒为单位的页面加载时间。

Use decimal numbers使用十进制数

From Decimal |十进制 | ClickHouse Documentation : ClickHouse 文档

Decimal(P, S), Decimal32(S), Decimal64(S), Decimal128(S), Decimal256(S) Decimal(P, S), Decimal32(S), Decimal64(S), Decimal128(S), Decimal256(S)

Signed fixed-point numbers that keep precision during add, subtract and multiply operations.在加、减和乘运算期间保持精度的有符号定点数。 For division least significant digits are discarded (not rounded).对于除法,最低有效数字被丢弃(不四舍五入)。

Parameters参数

  • P - precision. P——精度。 Valid range: [ 1 : 76 ].有效范围:[ 1 : 76 ]。 Determines how many decimal digits number can have (including fraction).确定数字可以有多少个十进制数字(包括分数)。
  • S - scale. S - 规模。 Valid range: [ 0 : P ].有效范围:[ 0 : P ]。 Determines how many decimal digits fraction can have.确定分数可以有多少个十进制数字。

<…> <…>

Decimal Value Ranges十进制值范围

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

For example, Decimal32(4) can contain numbers from -99999.9999 to 99999.9999 with 0.0001 step.例如,Decimal32(4) 可以包含从 -99999.9999 到 99999.9999 的数字,步长为 0.0001。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM