Format QString with fixed number of digits - qt

When using sprintf() when I want to format a number with a fixed number of digits, I have to use format strings like "%.3f" or "%2d". Now the Qt-manual says, I have to use QStrings::arg()-function instead of sprintf():
QString("%1").arg(QString::number(1.3));
So how do I specify the number of digits to be shown in resulting string? Thanks :-)

QString::arg
You can specify the formatting with QString::arg like:
%.3f: QString("%1").arg(1.3, 0, 'f', 3): where the second argument is the field-width (minimum width of the resulting string, 0 here), the third is the format of the number, (in this case f means use no scientific notation), and the fourth is the precision (3 number of decimal places).
%2d: QString("%1").arg(42, 2).
Note: When using QString::arg you must be careful on using the adequate data type. For example, if you want to format the number 50 with one zero decimal, you must use QString("%1").arg(50.0, 0, 'f', 1). If you use QString("%1").arg(50, 0, 'f', 1) instead (note 50 is an integer), code won't compile due to a conflict of arguments.
This is the preferred way to do it in Qt, specially if the formatting string has to be localized. One of the main reasons is that the placeholders for values have an index (%1, %2...), allowing them to be in any order in the string and keeping their semantics (you may need to change order in some languages).. When using sprintf-like functions the order of the arguments matters.
QString::asprintf
Nevertheless, and though not recommended in new Qt code, you can use the sprintf-like QString::asprintf (do not use QString::sprintf which is deprecated). For example, QString::asprintf("%.3f", 1.3).

Related

How to parse accounting number format in SQLite field?

I am a somewhat newbie to SQLite (and KMyMoney). KMyMoney (an open source personal finance manager) allows one-click exporting data into an SQLite database.
On browsing the SQLite database output, the dollar amount data is stored in a table called kmmSplits as several text fields in a strange format based on “value” and “valueFormatted” (see screen shot below). The “value” field is apparently written as a division equation (in a text format) which apparently yields the “valueFormatted” field (again in text format). The “valueFormatted is the correct number amount but the problem is that parenthesis are used to indicate a negative number instead of a simple minus in front of the value. This is apparently an accounting number format, but I don’t know how to parse this into a float value for running calculated SQL queries, etc. The positive values (without parenthesis) are no problem to convert to FLOATS.
I’ve tried using the CAST to FLOAT function but this does not do the division math, nor does it convert parenthesis into negative values (see screen shot).
The basic question is: how to parse a text value containing parenthesis in the “valueFormatted field (accounting money format) into a common number format OR, alternatively, how to convert a division equation in the “value” field to an actual calculation.
Use a CASE expression to check if valueFormatted is a numeric value inside parentheses and if it is multiply -1 with the substring starting from the 2nd char (the closing parenthesis will be discarded by SQLite during this implicit type casting):
SELECT *,
CASE
WHEN valueFormatted LIKE '(%)' THEN (-1) * SUBSTR(valueFormatted, 2)
ELSE valueFormatted
END AS value
FROM kmmSQLite;
Or, replace '(' with ''-'' and add 0 to covert the result to a number:
SELECT *,
REPLACE(valueFormatted, '(', '-') + 0 AS value
FROM kmmSQLite;

Combine IsNumeric and Right()

Trying to return field [doc] that have no letters. Results are all over the place.
SELECT Right([doc],4) AS ex1, IsNumeric([ex1]) AS ex2
FROM stat_converted;
The query returns two fields as it should but not evaluating correctly. Results with all numbers and others that are all letters are coming back as True(-1).
I also tried building a temp table and then applying IsNumeric to that with same results.
I also built a small test DB and the logic works so I am really confused.
IsNumeric will match things like "2E+1" (2 times ten to the power of 1, i.e. 20) as that is a number in scientific format. "0D88" is also a number according to IsNumeric because it is the double-precision (hence the "D") version of "0E88".
You could use LIKE '####' to match exactly four digits (0-9).
If you had more complex match requirements, say a variable quantity of digits, you would be interested in Expressing basic Access query criteria as regular expressions.

Stopping a large number of zeros being printed (not scientific notation)

What I'm trying to achieve is to have all printed numbers display at maximum 7 digits. Here are examples of what I want printed:
0.000000 (versus the actual number which is 0.000000000029481.....)
0.299180 (versus the actual number which is 0.299180291884922.....)
I've had success with the latter types of numbers by using options(scipen=99999) and options(digits=6). However, the former example will always print a huge number of zeros followed by five non-zero digits. How do I stop this from occurring and achieve my desired result? I also do not want scientific notation.
I want this to apply to ALL printed numbers in EVERY context. For example if I have some matrix, call it A, and I print this matrix, I want every element to just be 6-7 digits. I want this to be automatic for every print in every context; just like using options(digits=6) and options(scipen=99999) makes it automatic for every context.
You can define a new print method for the type you wish to print. For example, if all your numbers are doubles, you can create
print.double=function(x){sprintf("%.6f", x)}
Now, when you print a double (or a vector of doubles), the function print.double() will be called instead of print.default().
You may have to create similar functions print.integer(), print.complex(), etc., depending on the types you need to print.
To return to the default print method, simply delete the function print.double().
Are all your numbers < 1? You could try a simple sprintf( "%.6f", x ). Otherwise you could try wrapping things to sprintf based on the number of digits; check ?sprintf for other details.

YAML ignore decimal values like `X.0`

On loading a yaml file with values such as 25.0, the .0 is ignored and what I get is 25. Is it possible to force yaml to consider the value as it is without manipulating the data? I have tried enclosing the values in single/double quotes, but that does not work.
[Edit]: I am using the yaml parser package for R programming language. The data type returned is double. If I set the value to 25.2, I get back the same value. How can I force YAML/R to read the the information in YAML as it is.
Your problem is that the parser recognises that these are floating point numbers and in R there is no difference between 25.0 and 25. Try this for example:
identical(25.0, 25)
25.0 and 25 are just two different representations of the same floating point number. If you want to retain the form in which the data is supplied you will have to read them in as strings (which you can later convert to numeric if you need to perform calculations). You can do this with a handler:
yaml.load("25.0", handlers=list("float#fix"=function(x) as.character(x)))
Maybe this will help: http://tolstoy.newcastle.edu.au/R/help/06/05/28016.html
Its suggested to change the settings for digits and possibly round the numbers too to avoid too many decimal places.
options(digits=2)
format(rounf(x, 2), nsmall = 2)

Decimal places problem with SQLite

I have a SQLite3 table with a column having format DECIMAL(7,2), but whenever I select rows with values not having a non-zero 2nd decimal place (eg. 3.00 or 3.10), the result always has trailing zero(s) missing (eg. 3 or 3.1). Is there any way that I can apply a formatting function in the SELECT statement so that I get the required 2dp? I have tried ROUND(), but this has no effect. Otherwise I have to keep converting the resulting column values into the required format for display (using Python in my case) every time I do a SELECT statement, which is a real pain.
I don't even mind if the result is string instead of numeric, as long as it has the right number of decimal places.
Any help would be appreciated.
Alan
SQLite internally uses IEEE binary floating point arithmetic, which truly does not lend itself well to maintaining a particular number of decimals. To get that type of decimal handling would require one of:
Fixed point math, or
IEEE decimal floating point (rather uncommon), or
Handling everything as strings.
Formatting the values (converting from floating point to string) after extraction is the simplest way to implement things. You could even hide that inside some sort of wrapper so that the rest of the code doesn't have to deal with the consequences. But if you're going to do arithmetic on the value afterwards then you're better off not formatting and instead working with the value as returned by the query, because the format and reconvert back to binary floating point (which Python uses, just like the vast majority of other modern languages) loses lots of information in the reduced precision.

Resources