AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题

问题[floating-point](dba)

Martin Hope
FiddlingAway
Asked: 2022-05-07 11:15:20 +0800 CST

选择一个浮点值会产生不正确的结果

  • 1

考虑以下。

CREATE TABLE IF NOT EXISTS `docs` (
  `id` int(6) unsigned NOT NULL,
  `qty` float NOT NULL,
  `price` float NOT NULL,
  `rebate` float not null,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `docs` VALUES
  (1,1,43616.7,0);

SELECT SUM(qty * (price - price * rebate/100)) AS endval
FROM docs

此查询没有按预期返回 43616.7,而是返回 43616.69921875(在某些机器上为 43616.671875)。演示小提琴可以在这里找到。

为什么会这样?我希望它能够像这样工作(为实际输入像这样基本的东西道歉):

1 * (43616.7 - 43616.7 * 0 / 100) = 1 * (43616.7 - 0) = 43616.7

我意识到我可以通过使用decimal (10,2)我的专栏来克服这个问题,我只是想知道是什么导致了这种意外行为。

mysql floating-point
  • 1 个回答
  • 29 Views
Martin Hope
Heinzi
Asked: 2019-03-30 06:27:07 +0800 CST

浮点数的非确定性总和

  • 11

让我说一个明显的拳头:我完全理解浮点类型不能准确地表示十进制值。这不是那个!然而,浮点计算应该是确定性的。

既然这已经不碍事了,让我向您展示我今天观察到的奇怪案例。我有一个浮点值列表,我想总结一下:

CREATE TABLE #someFloats (val float);
INSERT INTO #someFloats (val) VALUES (1), (1), (1.2), (1.2), (1.2), (3), (5);

SELECT STR(SUM(#someFloats.val), 30, 15) FROM #someFloats;

DROP TABLE #someFloats;

-- yields:
--   13.600000000000001

到目前为止,一切都很好 - 这里没有惊喜。我们都知道1.2不能用二进制表示精确地表示,所以“不精确”的结果是意料之中的。

现在,当我左加入另一个表时,会发生以下奇怪的事情:

CREATE TABLE #A (a int);
INSERT INTO #A (a) VALUES (1), (2);

CREATE TABLE #someFloats (val float);
INSERT INTO #someFloats (val) VALUES (1), (1), (1.2), (1.2), (1.2), (3), (5);

SELECT #A.a, STR(SUM(#someFloats.val), 30, 15)
  FROM #someFloats LEFT JOIN #A ON 1 = 1
 GROUP BY #A.a;

DROP TABLE #someFloats;
DROP TABLE #A;

-- yields
--   1   13.600000000000001
--   2   13.599999999999998

(sql fiddle,你也可以在那里看到执行计划)

我对相同的值有相同的总和,但浮点错误不同。如果我向 table 添加更多行,我们可以看到该值在这两个值之间交替。我只能用;重现这个问题。在这里按预期工作。#ALEFT JOININNER JOIN

这很不方便,因为这意味着 a DISTINCT, GROUP BYorPIVOT将它们视为不同的值(这实际上是我们发现这个问题的方式)。

显而易见的解决方案是对值进行舍入,但我很好奇:这种行为是否有合乎逻辑的解释?

sql-server floating-point
  • 1 个回答
  • 1366 Views
Martin Hope
Jonathan Parent Lévesque
Asked: 2016-04-27 08:14:41 +0800 CST

MySQL bug - 十进制比较

  • 1

我目前正在为存储过程编写单元测试,该存储过程根据客户居住的国家/省计算税额和税率。

不知何故,MySQL 认为“ 14.975 ”不同于“ 14.975 ”。

在此处输入图像描述

如果我尝试taxRate < 14.975or taxRate = 14.975,它不会进入条件;但是taxRate <> 14.975确实taxRate > 14.975如此。

我觉得我错过了一些明显的东西,但我就是想不通。

我的测试代码:

  DECLARE totalTax DECIMAL(20,6) DEFAULT 0;
  DECLARE taxRate DECIMAL(10,3) DEFAULT 0;

  SET @roundMode = 0;
  SET @roundPrecision = 2;

  /* caculate TPS only*/

  CALL calculateTotalTaxOnAmount (200, 4, NULL, totalTax, taxRate);

  IF (totalTax <> 10) THEN

    SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT = 'INVALID_TAX_AMOUNT_CANADA';
  ELSEIF (taxRate <> 5) THEN

    SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT = 'INVALID_TAX_RATE_CANADA';
  END IF;

  /* caculate TPS and TVQ */

  CALL calculateTotalTaxOnAmount (100, 4, 87, totalTax, taxRate);

  IF (totalTax <> 14.98) THEN

    SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT = 'INVALID_TAX_AMOUNT_CANADA_QUEBEC';
  ELSEIF (taxRate <> 14.975) THEN

    SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT = 'INVALID_TAX_RATE_CANADA_QUEBEC';
  END IF;

我的功能:

CREATE PROCEDURE calculateTotalTaxOnAmount (
    IN amount DECIMAL(20,6),
    IN countryID INT(10),
    IN stateID INT(10),
    OUT totalTax DECIMAL(20,6),
    OUT totalTaxRate DECIMAL(10,3) 
)
BEGIN
    DECLARE break BOOLEAN DEFAULT FALSE;
    DECLARE taxBehavior INT(10);
    DECLARE taxRate DECIMAL(10,3);

    DECLARE TaxCursor CURSOR FOR
        SELECT (t.`rate` / 100),
            tr.`behavior`
        FROM `ps_tax_rule` tr 
        JOIN `ps_tax` t
            ON tr.`id_tax` = t.`id_tax`
        WHERE tr.`id_country` = countryID 
        AND tr.`id_state` IN (0, stateID) 
        AND t.`active` = 1
        ORDER BY tr.`id_state`;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET break = TRUE;

    SET totalTax = 0;
    SET totalTaxRate = 0;

    OPEN TaxCursor;

    tax_loop: LOOP
        FETCH TaxCursor INTO 
            taxRate,
            taxBehavior;

        IF (break) THEN

            LEAVE tax_loop;
        END IF;

        IF (taxBehavior = 2) THEN /* cumulative tax */

            SET totalTax = totalTax + (amount + totalTax) * taxRate;

        ELSE /* standalone tax */

            SET totalTax = totalTax + (amount * taxRate);
        END IF;
    END LOOP tax_loop;

    CLOSE TaxCursor;

    IF (totalTax <> 0) THEN

        SET totalTaxRate = totalTax * 100 / amount;

        SET totalTax = roundMoney(totalTax);
    END IF;
END //

注意:如果要在本地测试,请替换roundMoney(totalTax)为round(totalTax, 2)

mysql floating-point
  • 1 个回答
  • 2634 Views
Martin Hope
WAF
Asked: 2015-07-31 07:43:08 +0800 CST

具有非整数的模运算符 - 意外结果

  • 1

MySQL 5.5.32,甲骨文 11g

mod()对于涉及非整数模数的查询,MySQL 会返回奇怪的结果。为什么是这样?

我有一个这样定义的列:

+--------+--------------+------+-----+---------+-------+
| Field  | Type         | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| col    | double(15,6) | YES  |     | NULL    |       |
+--------+--------------+------+-----+---------+-------+

我从该列中选择了一个已知值用于测试 - 5850。如果我查询表,测试该列的整数,我得到这些结果:

mysql> SELECT thing_id,name FROM table WHERE col=5850 AND mod(col,1) != 0;
Empty set (1.07 sec)

这是意料之中的。但这不是:

mysql> SELECT thing_id,name FROM table WHERE col=5850 AND mod(col,.1) != 0;
+-----------+-----------+
| thing_id  | name      |
+-----------+-----------+
|   4444444 | some      |
|   4444445 | names     |
...
|  55555555 | go        |
|  55555556 | here      |
+-----------+-----------+
416 rows in set (1.07 sec)

替换的结果相同col MOD .1,col % .1因此它与计算而不是语义有关。

将此与 Oracle 的行为(如果重要,则使用 SQL Developer)进行比较,其中的类型col是NUMBER:

SELECT thing_id,name FROM table WHERE col=5850 AND mod(col,.1) != 0;
thing_id    name
[NO RECORDS]

MySQL 列的精度似乎造成了这种差异,但我不明白如何。从概念上讲,不应该integer_value % .1 = 0吗?

datatypes floating-point
  • 1 个回答
  • 732 Views
Martin Hope
kev
Asked: 2014-09-01 22:05:31 +0800 CST

四舍五入的问题?

  • 5

尝试这个:

create table test (f float);
insert into test values (330.0);
commit;

select (8 + 330.0/60)::int; --14
select (8 + f/60)::int from test; --14
select (9 + 330.0/60)::int; --15
select (9 + f/60)::int from test; --14

有人可以解释为什么最后一个查询返回 14 而不是 15?

PostgreSQL 9.3.9 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, 64-bit
12.04.5 LTS (GNU/Linux 3.2.0-63-virtual x86_64)
postgresql floating-point
  • 1 个回答
  • 1923 Views
Martin Hope
JAM
Asked: 2013-04-07 12:09:52 +0800 CST

如何强制执行完整整数(无浮点)?

  • 1

为什么以下允许

INSERT INTO c VALUES (123.2,'abcdefghijklmnopqrstuvwxyzabcdef', 'abcdefghijklmnop');

当表包含

CustomerID      NUMBER(3,0) -- That's the 123.2 entry

换句话说,浮点数后为 0 的总共 3 位数字?

如果number不是可行的方法,您将如何仅强制执行完整整数(无浮点)

oracle floating-point
  • 3 个回答
  • 2034 Views
Martin Hope
Bryan Agee
Asked: 2011-12-15 15:28:54 +0800 CST

MySQL 从 float (10,2) 到 fixed(10,2) 的转换

  • 4

我有一个数据库,其中包含存储为浮点数的财务数据。自然地,这可能会在随机时间出现一个真正的问题(例如,当存在无法用浮点算法足够接近地近似的精确值时)。

我的问题是:

  • 当您选择字段时,使用会 ALTER TABLE table MODIFY field fixed(10,2)保留 MySQL 当前显示的固定值吗?
  • 该值是否有可能是其他的东西?
mysql floating-point
  • 3 个回答
  • 19063 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve