Qt和C ++在没有科学记数法的情况下从MySQL显示大的DECIMAL数

时间:2011-03-30 16:50:00

标签: c++ qt

我在MySQL中有很大的价值。它作为DECIMAL(22,2)正确存储在MySQL中。我已确认该值已正确存储。如果我通过命令控制台运行查询,我会以所需的非科学形式返回正确的值(值和格式为:99996543210987654321.99)。

问题是当我使用Qt / C ++运行查询时,我看不出如何用非科学符号显示数字。我得到(9.99965432109877e + 19)而不是(99996543210987654321.99)。我想要后者。

在C ++ / Qt中这就是我从Qt查询中提取值的方法 (1)首先,我用Qt打开与MySQL的数据库连接 (2)然后,我进行查询以查找特定记录。到目前为止一切顺利。
(3)然后,我使用下面发布的确切代码从查询找到的返回记录中提取特定字段值 *注意。 QSqlQuery :: value返回一个Qvariant http://doc.qt.io/qt-5/qvariant.html#QVariant-30

if( query3.next() )
{
   QVariant number = query3.value(query3.record().indexOf("account_balance"));
   qout << number.toString() << endl;
}

我也尝试过(结果相同)。

if( query3.next() )
{    
 qout<<query3.value(query3.record().indexOf("account_balance")).toString()<<endl;
}

添加,“qout”只是一个QTextStream。我认为这个问题不是qout,因为代码低于输出99996543210987654321.99而没有科学记法。

qout << "99996543210987654321.99" << endl;

如何在不使用c ++ / qt舍入且没有科学记数法的情况下返回值99996543210987654321.99?







修改
在Pete的建议下尝试了

char string_account_balance[32] = "";
sprintf( string_account_balance, "%.2f", query3.value(query3.record().indexOf("account_balance")).toString() );

出错和崩溃。错误:
(1)通过'...'传递非POD类型'class QByteArray'的对象;呼叫将中止运行时间 (2)格式'%。2f'期望类型'double',但参数3的类型为'int'。

4 个答案:

答案 0 :(得分:2)

在调查Qt与MySQL结合使用十进制类型时,我找到了这个主题。

我猜想,这个问题的原因很简单:当Qt从DECIMAL字段读取数据时,它会将其转换为double。 所以,我看了Qt的MySQL驱动程序源,位于QtSDK / QtSources / 4.7.4 / src / sql / drivers / mysql / qsql_mysql.cpp 我在qDecodeMYSQLType函数中找到了以下行:

    case FIELD_TYPE_FLOAT :
    case FIELD_TYPE_DOUBLE :
    case FIELD_TYPE_DECIMAL :
#if defined(FIELD_TYPE_NEWDECIMAL)
    case FIELD_TYPE_NEWDECIMAL:
#endif
        type = QVariant::Double;
        break;

所以,我是对的,它以同样的方式处理DECIMAL,如DOUBLE。

问题的解决方案很简单。只需将此部分代码更改为

即可
    case FIELD_TYPE_FLOAT :
    case FIELD_TYPE_DOUBLE :
        type = QVariant::Double;
        break;
    case FIELD_TYPE_DECIMAL :
#if defined(FIELD_TYPE_NEWDECIMAL)
    case FIELD_TYPE_NEWDECIMAL:
#endif
        type = QVariant::String;
        break;

并重建MySQL插件。

我的应用现在正确读取DECIMAL类型。

答案 1 :(得分:1)

QSqlQuery :: value()返回一个QVariant,并且没有QVariant :: toLongDouble或类似的东西(除了toString(),它不起作用)。所以你必须在MySQL中进行转换 - 带有CHANGE选项的ALTER TABLE将DECIMAL更改为VARCHAR或类似的东西,查询结果,然后将其更改回来。否则,看起来你运气不好,尤其是鉴于MSalters发布的链接。

答案 2 :(得分:1)

@ user440297 - 我试过(想到我试过)几个小时前将其添加为评论。我猜不是。

当我在C(虽然不是C ++)程序中遇到这个问题时,%.nf格式规范可以节省时间。我通常会这样说:

// instead of:   
//  QVariant number = query3.value(query3.record().indexOf("account_balance"));<br>
// use, approximately:

  char string_account_balance[32] = "";
  sprintf( string_account_balance, %.2f%, query3.value( query3.record().indexOf( "account_balance" ));

那应该给你所需的所有整数位,小数点和两位小数。

不要更改小数(22,2)MySQL字段。如果它是varchar,你将不得不处理所有的算术......哦,伙计,想想它太可怕了。在任何情况下,它只是输出格式问题,而不是内部存储问题或Qt问题。

我总是远离%f格式,因为我认为引入了浮点格式问题;不是这样。相反,它会使浮点格式问题蒸发。

- 皮特

答案 3 :(得分:0)

Qt可能会将该数字设为科学记数法,因为您的数字长度为22位十进制数。双打可以存储53位尾数,最多可以转换为16位十进制数(见http://en.wikipedia.org/wiki/Double_precision_floating-point_format)。

话虽如此,也许你可以尝试一个长双,或其他类型,可以存储所有22位小数。