【问题标题】:MySQL SELECT Precision of calculation (digits after decimal point)MySQL SELECT 计算精度(小数点后的数字)
【发布时间】:2019-08-15 04:52:21
【问题描述】:

我正在尝试为来自执行某些方程式的 SELECT 的结果实现相同的精度(小数点后的位数)。

  1. 除了最后一个舍入之外,在性能方面是否有任何差异,在 CAST() 或 ROUND() 之间实现所需精度的良好使用实践?有没有更好的选择?

为简单起见,下面所有示例中的值都是硬编码的,它们可能来自也可能不来自表的列

我正在使用 MySQL 8。

如果你运行示例E1

-- E1
SELECT (41/99);
-- 0.4141

您将得到小数点后 4 位数字。

  1. 是否有任何 MySQL 设置可以直接带来更高的精度,所以我不需要使用:

    -- E2 选择回合((41/99),20); -- 0.41414141400000000000

    -- 或

    SELECT CAST((41/99) AS DECIMAL(21,20)); -- 0.41414141400000000000

  2. 如果用于计算的数据是 int,如何从 E2 获得更多小数点精度?

如果你提供带小数点的数据,你会得到更高的精度:

-- E3
SELECT ROUND((41.0/99.0), 20);
-- 0.41414141414141414100

SELECT CAST((41.0/99.0) AS DECIMAL(21,20));
-- 0.41414141414141414100

避免浮点数据类型对我来说很重要,因为它们近似小数。如果数据来自表列,则该列将是十进制数据类型。但是用于计算的数据也可能是硬编码的。

【问题讨论】:

  • " 是否有任何 MySQL 设置可以直接带来更高的精度,所以我不需要使用:" 不需要使用隐式数据类型在表中或隐式转换中的选择就像 SQL 标准定义的那样以获得更高的精度。如果我从来没有遇到过 MySQL 中的这种更高精度的设置。
  • 我也相信SELECT (41/99) 按照 SQL 标准应该是 0 但 MySQL 和 MariaDB 允许这样做,在 PostgreSQL 等数据库中,SQL Server 会给出 0 所以 SELECT (41/99); 不是便携。
  • @Raymond Nijland 问题不是关于浮点数,而是关于实现小数的固定精度,因此它不是重复的。
  • seams 有一个 MySQL 设置,我刚发现它是第一个 div_precision_increment

标签: mysql select precision decimal-point


【解决方案1】:

MySQL 使用 64 位 IEEE-754 浮点(又名DOUBLE)进行内部计算,除非您通过强制转换常量使其使用整数或十进制算法。 (Javascript 也是。)

在显示数字时,尽可能准确地以十进制显示它们。对于DOUBLE,需要转换为十进制。如果您不想要默认的渲染精度,而是想自己控制它,您可以使用ROUND()TRUNCATE() 函数。这就是你控制它的方式。

使用这些函数并没有太大的性能损失。许多使用纯 SQL(而不是使用 Java、PHP 或其他语言的应用程序检索 SQL)的程序员总是使用其中一个函数来保持对呈现的控制。

如果您在计算中依赖 DECIMAL 数据类型的准确性,请仔细测试:MySQL 确实希望在 DOUBLE 中执行它们。或者,更好的是,使用强类型语言来精确控制算术。

【讨论】:

  • 你吓到我了:“如果你在计算中依赖 DECIMAL 数据类型的准确性,请仔细测试:MySQL 真的想在 DOUBLE 中做这些”。但是,如果我在 SELECT 中的任何地方都使用 CAST 和 AS DECIMAL,我在 INSERT 之前对数据和任何地方进行操作,我会被覆盖并且不会发生意外?
  • 恕我直言,我是想吓唬你。请非常小心使用此 SQL 中的算术应用程序。你可能没事。但是你应该测试像10000000000000 + 1 这样的用例来说服自己你没有失去精确度。如果精度是关键任务,你真的应该用强类型语言来做这些事情。
  • 顺便说一句,如果 MySQL 会使用 IEEE-754 floating point (aka DOUBLE) internal 我发现了其他东西,为什么 SELECT (0.1 + 0.3) = 0.4 会导致 1 如果 MySQL 会使用,它应该会导致 0? MySQL 接缝在可能的情况下默认为 Precision Math(又名 DECIMAL 数据类型精度)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-13
  • 2017-03-29
相关资源
最近更新 更多