MariaDB 5.5.60 上的奇怪零行为(双重)[重复]

Posted

技术标签:

【中文标题】MariaDB 5.5.60 上的奇怪零行为(双重)[重复]【英文标题】:Weird zeros behaviour (double) on MariaDB 5.5.60 [duplicate] 【发布时间】:2019-01-29 09:00:32 【问题描述】:

亲爱的朋友们!

我遇到了一个在 linux 上运行的 MariaDB 5.5.60 的奇怪问题。

出于某种原因,我正在对差异列进行简单的操作,如您所见,是一个double。

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(12) NOT NULL AUTO_INCREMENT,
  `email` varchar(256) DEFAULT NULL,
  `username` varchar(256) NOT NULL,
  `password` varchar(256) NOT NULL,
  `won` int(11) NOT NULL DEFAULT '0',
  `lose` int(11) NOT NULL DEFAULT '0',
  `difference` double NOT NULL DEFAULT '0',
  `available_balance` double NOT NULL DEFAULT '0',
  `pending_received_balance` double NOT NULL DEFAULT '0',
  `spawns` int(11) NOT NULL DEFAULT '0',
  `condicion` varchar(256) NOT NULL DEFAULT 'offline',
  `address` varchar(256) NOT NULL DEFAULT 'offline',
  `eliminado` int(12) NOT NULL DEFAULT '0',
  `creacion` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;

问题:

-917.3700000000001

当系统开始加减值时会发生这种情况。由于这些数字代表金钱,我们不能容忍任何随意的差异。

可能导致此问题的查询之一如下:

    UPDATE users SET
    difference                  = difference - '$xfer->value_final',
    available_balance           = '$user->available_balance',
    pending_received_balance    = '$user->pending_received_balance',
    condicion                   = '$user->condicion'
    WHERE id                    = '$user->id'

如您所见,值正在更新以减去 $xfer->value_final,在本例中为 101.93

这甚至有点难以复制,因为我必须至少下 10 次相同的订单,才能获得长零尾值。

一旦该值发生一次,那么它当然会在每次下一次操作时保持全零,或者直到固定为止。

这些值来自 BTC 区块链,但我 100% 确信它们总是有 2 位小数,因为我总是将它们存储在另一个表中。

¿有人知道为什么会发生这种情况吗? ¿ 这是一个错误吗? ¿ 还是我错过了什么?

¿我该如何解决这个问题?

提前致谢; 克里斯

【问题讨论】:

使用 DECIMAL 而不是 DOUBLE 如果您知道您将始终精确到两位小数。 特别是永远不要使用浮点值来赚钱。 @Amadan,感谢您的快速回复,但是,根据手册,十进制应该具有更高的精度......我正在处理昏迷后的 2 个位置......这应该即使使用浮点数也能正常工作......我会尝试十进制,但我什至不确定我错过了它。 阅读链接的问题,这应该可以回答您从不使用花车赚钱的原因。 DECIMAL 完全符合您指定的精度,绝不会像 0.2 + 0.1 = 0.30000000000000004 这样搞恶作剧。 十进制将 5718.94 向上舍入到 5719.00... 您是如何声明该列的?像difference DECIMAL(10, 2) NOT NULL DEFAULT 0 这样的东西不应该那样做。 (适当增加 10 到您的极限。) 【参考方案1】:

感谢@Amadan!

我们的解决方法如下:

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(12) NOT NULL AUTO_INCREMENT,
  `email` varchar(256) DEFAULT NULL,
  `username` varchar(256) NOT NULL,
  `password` varchar(256) NOT NULL,
  `won` int(11) NOT NULL DEFAULT '0',
  `lose` int(11) NOT NULL DEFAULT '0',
  `difference` decimal(10,2) NOT NULL DEFAULT '0.00',
  `available_balance` decimal(10,2) NOT NULL DEFAULT '0.00',
  `pending_received_balance` decimal(10,2) NOT NULL DEFAULT '0.00',
  `spawns` int(11) NOT NULL DEFAULT '0',
  `condicion` varchar(256) NOT NULL DEFAULT 'offline',
  `address` varchar(256) NOT NULL DEFAULT 'offline',
  `eliminado` int(12) NOT NULL DEFAULT '0',
  `creacion` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;

所有双精度都已替换为 十进制 10,2

【讨论】:

以上是关于MariaDB 5.5.60 上的奇怪零行为(双重)[重复]的主要内容,如果未能解决你的问题,请参考以下文章

双重比较的C ++非常奇怪的行为[关闭]

centos 7.5 安装mysql

CentOS 7.4 如何安装 MariaDB 10.3.9 Stable 数据库

centos7安装mysql-5.5.60

CentOS 7 安装MySql 5.5.60

具有零值双精度的奇怪 if 语句行为