In need of a fast and reliable textual number formatting function I tried many ways.
From own hand and sourced online or mixed. I made up some candidates to evaluate.
Number.toFixed(accuracy) or parseFloat(value).toFixed(accuracy)
Both fail at some points. A) doesn't round ..5 always up, B) solves this only for some.
numberToString() use sprintf.js and needs post formatting too.
It returns a comma in my case and a leading zero.
- FAST! It is called tirelessly to trial number formatting for 'Tile2Hatch'.
- formatting a parseFloat() as short as possible.
- rounding tie breaking half away from zero.
- without leading- and trailing zeros. (optional with any)
- with a dot as decimal separator. (optional with custom)
For this I also evaluated RUnit.doubleToStringDec()
A promising build-in function and compiled still very fast although the use of sprintf (not .js I presume).
At first glance only the default for the use of a leading zero differs.
It took me a while to figure out that the custom decimal point should be a character code, a number.
Looking into: https://qcad.org/doc/qcad/3.0/developer ... 124e3f2c3f
RDEFAULT_DOT is defined as a '.' (dot) not as value 46.
What did the trick was:
Code: Select all
REcmaUnit.cpp ...
// argument isStandardType
char
a4 =
(char)
context->argument( 4 ).
toNumber();
But ...
In the end, I can't get the 'NO leadingZero' to work. Using a LZ is perstistent.
Code: Select all
var testcase = 0.0125;
var accuracy = 6;
var decPnt = "p";
var reply0 = RUnit.doubleToStringDec(testcase, accuracy); // 0.0125 defaults LZ=true TZ=false
var reply1 = RUnit.doubleToStringDec(testcase, accuracy, true); // 0.0125 default TZ=false
var reply2 = RUnit.doubleToStringDec(testcase, accuracy, false); // 0.0125 default TZ=false FAILS LZ=false
var reply3 = RUnit.doubleToStringDec(testcase, accuracy, true, true); // 0.012500
var reply4 = RUnit.doubleToStringDec(testcase, accuracy, true, false); // 0.0125
var reply5 = RUnit.doubleToStringDec(testcase, accuracy, false, true); // 0.012500 FAILS LZ=false
var reply6 = RUnit.doubleToStringDec(testcase, accuracy, false, false); // 0.0125 FAILS LZ=false
var reply7 = RUnit.doubleToStringDec(testcase, accuracy, true, true, decPnt); // 0p012500
var reply8 = RUnit.doubleToStringDec(testcase, accuracy, true, false, decPnt); // 0p0125
// Next all FAIL LZ=false
var reply9 = RUnit.doubleToStringDec(testcase, accuracy, false, true, decPnt);
var replyA = RUnit.doubleToStringDec(testcase, accuracy, false, false, decPnt);
var replyB = RUnit.doubleToStringDec(testcase, accuracy, false, false, ",".charCodeAt(0));
var replyC = RUnit.doubleToStringDec(testcase, accuracy, false, false, 44);
Beyond scripts it get fuzzy:
Code: Select all
RUnit.h ...
static QString doubleToString(double value, double prec,
bool showLeadingZeroes=true, bool showTrailingZeroes=false,
char decimalSeparator=RDEFAULT_DOT);
static QString doubleToString(double value, int prec,
bool showLeadingZeroes=true, bool showTrailingZeroes=false,
char decimalSeparator=RDEFAULT_DOT);
// workaround: make the second version also accessible by scripts:
static QString doubleToStringDec(double value, int prec,
bool showLeadingZeroes=true, bool showTrailingZeroes=false,
char decimalSeparator=RDEFAULT_DOT) {
return doubleToString(value, prec, showLeadingZeroes, showTrailingZeroes, decimalSeparator);
}
Also see: https://qcad.org/doc/qcad/3.0/developer ... e195df67c6
The two headers look exactly the same apart from the nature of 'prec'.
This isn't true looking at RUnit.cpp:
Code: Select all
QString RUnit::doubleToString(double value, double prec,
bool showLeadingZeroes, bool showTrailingZeroes,
char decimalSeparator) { ... }
QString RUnit::doubleToString(double value, int prec,
bool /*showLeadingZeroes*/, bool showTrailingZeroes,
char decimalSeparator) { ... }
And if I can follow it correctly then doubleToString 1/2 calls doubleToStringDec what is calling doubleToString 2/2 ...
Further:
Do I see limitations in what can be handled:
Code: Select all
doubleToString 1/2 ...
if (prec>1.0e-12) {
exaStr = doubleToStringDec(prec, 10);
doubleToString 2/2 ...
adds +/- fuzz = 1.0e-13 to sprintf
A double with 15.95 significant digits can look like 0.00000123451234512345(6).
With 10,12 or 13 decimal digits it looks like 0.0000012345(12(3)) and has at most 5-8 significant digits.
Troubled.
Can you explain all this more in detail?
Regards,
CVH