Showing numbers in decimal not scientific notation
-
@tomy said in Showing numbers in decimal not scientific notation:
How can it be acceptable!? All calculator around the world do calculations on both types. Furthermore, when I write 2.3+4.6, it shows: 6.900000!
No they do calculation in the widest possible type they support (here it's double) and then display the result as appropriate. Further reading on implicit type promotions in c++ can be found here
Ow my God! Isn't there any simpler way?
This is a simple
if-else
statement with the notable exception that it compares floating point values as they should be compared.Do you say that behind that Windows' calculator there would be such a long statement just for showing numbers in decimal mode, if it were written by C++/Qt?
Yes, I'm sure of it. It's probably even much longer as windows is actually written in C.
-
I used this:
ss = qFuzzyCompare(expression(), static_cast<qint64>(expression()) ? QString::number(static_cast<qint64>(expression())) : QString::number(expression(), 'f')); result_box -> setText(ss);
ss
is a QString.
expression()
returns anint
ordouble
value.
result_box
is alineEdit
which shows the result of the calculations.I get this error:
C:\Users\ME\Documents\Qt\My_First_Calculator\my_first_calculator.cpp:81: error: no matching function for call to 'qFuzzyCompare(double, QString)'
QString::number(expression(), 'f'));
^ -
@tomy said in Showing numbers in decimal not scientific notation:
expression() returns an int or double value.
I'm pretty sure that functions returns a string, not an
int
, nor adouble
. You need to convert the string to an actual number if you want to use it as such, e.g. see here. -
expression() returns an int or double value.
I'm pretty sure that functions returns a string, not an
int
, nor adouble
.Don't be that sure. :)
I have this method in my code:double My_First_Calculator::expression()
But I think this error is of that
ss
is aQString
. -
@tomy No, don't use QTextStream you don't need something like stringstream to pass numbers to string.
QString ss; ss = result_box -> locale().toString(expression(),'f'); result_box -> setText(ss);
or more concisely,
result_box->setText(result_box->locale().toString(expression(),'f'));
-
@VRonin said in Showing numbers in decimal not scientific notation:
@tomy No, don't use QTextStream you don't need something like stringstream to pass numbers to string.
QString ss; ss = result_box -> locale().toString(expression(),'f'); result_box -> setText(ss);
I used it.
2 + 3 = 5.000000
:( :( -
what is result_box
It's a
lineEdit
.and what is inside expression()?
It returns only a
double
value. Consider something simple like:double My_First_Calculator::expression() { double d1, d2; // these d1, d2 are gotten from input E.g. d1 = 2, d2 = 3.5 if(_ch == '+') return d1+d2; // _ch is a previously defined varible else if (_ch == '-') return d1-d2; // and so on }
-
I simplified the code as follows. This, too, has exactly that problem:
test.h
#ifndef TEST_H #define TEST_H #include <QDialog> class QLineEdit; class QPushButton; class test : public QDialog { Q_OBJECT public: test(QWidget* parent = 0); private slots: void expression(); private: QLineEdit* result_box; QPushButton* equal; QPushButton* quit; }; #endif // TEST_H
test.cpp
#include <QtWidgets> #include "test.h" test::test(QWidget* parent) : QDialog(parent) { result_box = new QLineEdit; equal = new QPushButton(tr("=")); quit = new QPushButton(tr("Close")); connect(quit, SIGNAL(clicked(bool)), this, SLOT(close())); connect(equal,SIGNAL(clicked(bool)), this, SLOT(expression())); QHBoxLayout* layout = new QHBoxLayout; layout -> addWidget(result_box); layout -> addWidget(equal); layout -> addWidget(quit); setLayout(layout); } //****************** void test::expression() { QString ss; double d = 1000000; QTextStream (&ss) << d; result_box -> setText(ss); }
And
main.cpp
#include <QApplication> #include "test.h" int main(int argc, char* argv[]) { QApplication app(argc, argv); test t; t.show(); return app.exec(); }
Just run it and click on the
=
button. -
-
@tomy said in Showing numbers in decimal not scientific notation:
Don't be that sure. :)
Yes! There's a typo in the code ... :)
ss = qFuzzyCompare(expression(), static_cast<qint64>(expression()) ? //< Missing a ) QString::number(static_cast<qint64>(expression())) : QString::number(expression(), 'f')); //< Extra )
What you want is to have the
if
withqFuzzyCompare
, not with the static cast. It should rather read like this:ss = qFuzzyCompare(expression(), static_cast<qint64>(expression())) ? QString::number(static_cast<qint64>(expression())) : QString::number(expression(), 'f');
If you wish you can of course use the usual
if-else
construct, not the ternary operator, so the last snippet'd be equivalent to:if (qFuzzyCompare(expression(), static_cast<qint64>(expression())) ss = QString::number(static_cast<qint64>(expression())); else ss = QString::number(expression(), 'f');
-
What you want is to have the
if
withqFuzzyCompare
, not with the static cast. It should rather read like this:ss = qFuzzyCompare(expression(), static_cast<qint64>(expression())) ? QString::number(static_cast<qint64>(expression())) : QString::number(expression(), 'f');
If you wish you can of course use the usual
if-else
construct, not the ternary operator, so the last snippet'd be equivalent to:if (qFuzzyCompare(expression(), static_cast<qint64>(expression())) ss = QString::number(static_cast<qint64>(expression())); else ss = QString::number(expression(), 'f');
Sorry, I don't know how I tested it but it doesn't work as it's expected! :(
for example:
2 + 3 = 5
OK
10 ^ 6 = 1000000
OK
2 + 1.5 = 3.500000
!!!That is, the function
QString::number(expression(), 'f');
(with the default precision 6) shows all range of precision whether it's need or not!Maybe it's what we need:
http://doc.qt.io/qt-5/qtextstream.html#setRealNumberNotation
But how to use it? Docs doesn't offer a little example of it to show how beginners should use it. !!!!!!
(Docs are not for learners/beginners, they are for professionals — if they are professional, so they don't need Docs much => Docs are not useful) -
What you want to do in the floating point case is not at all trivial. Here you can read on that topic if you are willing to digest the math.
The simpler but inefficient approach is to save the floating point text representation and just discard all the trailing
0
characters manually.EDIT:
Here's (probably) the most concise way, but requires knowledge of regular expressions, which is yet again for you to read on to understand how or why it works:if (qFuzzyCompare(expression(), static_cast<qint64>(expression())) ss = QString::number(static_cast<qint64>(expression())); else { ss = QString::number(expression(), 'f', 17); ss.replace(QRegularExpression("\\.?0+$"), ""); }
(Docs are not for learners/beginners, they are for professionals — if they are professional, so they don't need Docs much => Docs are not useful)
You got that backwards. The point of the Qt docs is they are a documentation for Qt itself, they will give no instruction into C++, its types, the types' memory layout and other such technical topics. If you are in need of that, then you need to look elsewhere, for example http://en.cppreference.com/w/
-
The point of the Qt docs is they are a documentation for Qt itself, they will give no instruction into C++, its types, the types' memory layout and other such technical topics.
Thanks but I didn't talk about C++, but Docs.
I thought we can look at the Docs as a set of instructions useful for learners to be used to Qt, because they have been frequently suggested to new comers of Qt for reading.
Thanks also for your code. -
@tomy Qt documentation is not a set of instructions and it will never be. It is just not possible to have instructions for every use case you can imagine.
Qt documentation documents Qt API and provides some examples. For specific use cases you need to think about it, read Qt documentation, try out. This is same for all frameworks I was using so far.