【问题标题】:Double precision not working correctly in mysql when using double type使用双精度类型时,双精度在 mysql 中无法正常工作
【发布时间】:2016-05-26 11:22:27
【问题描述】:

我的表中有双字段。当我从双参数中减去小数部分时,它会出现奇怪的问题。

我在表格中的金额是 0.068

当我减去 0.06 时,它变成了

0.0080000000000001

我对更新的简单查询是

UPDATE 
     subscriber 
SET 
     balance = balance - _amount

其中 _amount 是一个 Double 参数

由于它是一种遗留实现,我目前无法更改列类型。所以在查询中需要一些解决方法

【问题讨论】:

  • 双精度是近似数字,即可能发生这种情况。
  • 目前我无法更改类型,否则我可以选择浮点/十进制。我可以在上述查询中做的任何事情作为一种解决方法
  • user20160 我在 sql server 中使用过 double 并且不记得这个问题。我已经要求在不更改类型的情况下提供任何 mysql 解决方法
  • 我知道的所有 dbms 产品,包括 SQL Server,都有这种行为。

标签: mysql sql database tsql


【解决方案1】:

有什么问题? double precision 是一个浮点数,它使用二进制表示来近似十进制值。

如果您想要一个精确的数字,请使用定点表示。这样的列将被声明为decimal。你可以改用alter table

alter table change column balance decimal(10, 4);  -- or whatever is appropriate

尤其不建议使用浮点数存储货币值。

【讨论】:

    【解决方案2】:

    如果您无法更改类型,您可以尝试以下方法:

    UPDATE 
         subscriber 
    SET 
         balance = ((balance * 10000) - (_amount * 10000)) / 10000
    

    所以减法不使用小数。

    【讨论】:

    • 一个问题我有 1 作为数量。当我减去 0.001234 时,它变为 0.9987659999999999 而不是 0.998766
    • @KamranShahid 是的,解决方法有局限性,但如果您使用* 1000000/ 1000000,它可能适用于您提供的那些数字。但是,如果您的小数位数超过 10-15 位,那么解决方法可能不起作用。其他选项是在减法之前将值转换为十进制(10, 5)。
    • 好的,让我试试 Casting
    • 我使用了 UPDATE 订阅者 SET balance= CAST( balance AS DECIMAL(20,3)) - CAST( _amount AS DECIMAL(20,3)) .... 谢谢艺术
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-13
    • 1970-01-01
    相关资源
    最近更新 更多