Fix LaTeX length export of big numbers (bug 9416)

LaTeX lengths must not use scientific notation, since the + sign has a
different meaning (glue lengths). This is the export part of bug 9416, the GUI
part is still not fixed.
This commit is contained in:
Georg Baum 2015-05-14 12:10:42 +02:00
parent 1586f79499
commit 59e4d16ab9
5 changed files with 138 additions and 7 deletions

View File

@ -22,6 +22,7 @@
#include "frontends/FontMetrics.h"
#include "support/docstream.h"
#include "support/lstrings.h"
#include <sstream>
#include <iomanip>
@ -81,29 +82,31 @@ docstring const Length::asDocstring() const
string const Length::asLatexString() const
{
ostringstream os;
// Do not allow scientific notation (e.g. 1.2e+03), since this is not valid
// LaTeX (bug 9416)
switch (unit_) {
case PTW:
os << val_ / 100.0 << "\\textwidth";
os << support::formatFPNumber(val_ / 100.0) << "\\textwidth";
break;
case PCW:
os << val_ / 100.0 << "\\columnwidth";
os << support::formatFPNumber(val_ / 100.0) << "\\columnwidth";
break;
case PPW:
os << val_ / 100.0 << "\\paperwidth";
os << support::formatFPNumber(val_ / 100.0) << "\\paperwidth";
break;
case PLW:
os << val_ / 100.0 << "\\linewidth";
os << support::formatFPNumber(val_ / 100.0) << "\\linewidth";
break;
case PTH:
os << val_ / 100.0 << "\\textheight";
os << support::formatFPNumber(val_ / 100.0) << "\\textheight";
break;
case PPH:
os << val_ / 100.0 << "\\paperheight";
os << support::formatFPNumber(val_ / 100.0) << "\\paperheight";
break;
case UNIT_NONE:
break;
default:
os << val_ << unit_name[unit_];
os << support::formatFPNumber(val_) << unit_name[unit_];
break;
}
return os.str();

View File

@ -22,9 +22,12 @@
#include <QString>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <typeinfo>
using namespace std;
@ -1385,6 +1388,25 @@ int findToken(char const * const str[], string const & search_token)
}
std::string formatFPNumber(double x)
{
// Need manual tweaking, QString::number(x, 'f', 16) does not work either
ostringstream os;
os << std::fixed;
// Prevent outputs of 23.4200000000000017 but output small numbers
// with at least 6 significant digits.
double const logarithm = log10(x);
os << std::setprecision(max(6 - static_cast<int>(round(logarithm)), 0)) << x;
string result = os.str();
if (result.find('.') != string::npos) {
result = rtrim(result, "0");
if (result[result.length()-1] == '.')
result = rtrim(result, ".");
}
return result;
}
template<>
docstring bformat(docstring const & fmt, int arg1)
{

View File

@ -302,6 +302,15 @@ docstring const getStringFromVector(std::vector<docstring> const & vec,
/// found, else -1. The last item in \p str must be "".
int findToken(char const * const str[], std::string const & search_token);
/// Format a floating point number with at least 6 siginificant digits, but
/// without scientific notation.
/// Scientific notation would be invalid in some contexts, such as lengths for
/// LaTeX. Simply using std::ostream with std::fixed would produce results
/// like "1000000.000000", and precision control would not be that easy either.
std::string formatFPNumber(double);
template <class Arg1>
docstring bformat(docstring const & fmt, Arg1);

View File

@ -25,8 +25,59 @@ void test_uppercase()
cout << uppercase('a') << endl;
}
void test_formatFPNumber()
{
cout << formatFPNumber(0) << endl;
cout << formatFPNumber(1) << endl;
cout << formatFPNumber(23.42) << endl;
cout << formatFPNumber(1.3754937356458394574047e-20) << endl;
cout << formatFPNumber(1.3754937356458394574047e-19) << endl;
cout << formatFPNumber(1.3754937356458394574047e-18) << endl;
cout << formatFPNumber(1.3754937356458394574047e-17) << endl;
cout << formatFPNumber(1.3754937356458394574047e-16) << endl;
cout << formatFPNumber(1.3754937356458394574047e-15) << endl;
cout << formatFPNumber(1.3754937356458394574047e-14) << endl;
cout << formatFPNumber(1.3754937356458394574047e-13) << endl;
cout << formatFPNumber(1.3754937356458394574047e-12) << endl;
cout << formatFPNumber(1.3754937356458394574047e-11) << endl;
cout << formatFPNumber(1.3754937356458394574047e-10) << endl;
cout << formatFPNumber(1.3754937356458394574047e-9) << endl;
cout << formatFPNumber(1.3754937356458394574047e-8) << endl;
cout << formatFPNumber(1.3754937356458394574047e-7) << endl;
cout << formatFPNumber(1.3754937356458394574047e-6) << endl;
cout << formatFPNumber(1.3754937356458394574047e-5) << endl;
cout << formatFPNumber(1.3754937356458394574047e-4) << endl;
cout << formatFPNumber(1.3754937356458394574047e-3) << endl;
cout << formatFPNumber(1.3754937356458394574047e-2) << endl;
cout << formatFPNumber(1.3754937356458394574047e-1) << endl;
cout << formatFPNumber(1.3754937356458394574047) << endl;
cout << formatFPNumber(1.3754937356458394574047e1) << endl;
cout << formatFPNumber(1.3754937356458394574047e2) << endl;
cout << formatFPNumber(1.3754937356458394574047e3) << endl;
cout << formatFPNumber(1.3754937356458394574047e4) << endl;
cout << formatFPNumber(1.3754937356458394574047e5) << endl;
cout << formatFPNumber(1.3754937356458394574047e6) << endl;
cout << formatFPNumber(1.3754937356458394574047e7) << endl;
cout << formatFPNumber(1.3754937356458394574047e8) << endl;
cout << formatFPNumber(1.3754937356458394574047e9) << endl;
cout << formatFPNumber(1.3754937356458394574047e10) << endl;
cout << formatFPNumber(1.3754937356458394574047e11) << endl;
cout << formatFPNumber(1.3754937356458394574047e12) << endl;
cout << formatFPNumber(1.3754937356458394574047e13) << endl;
cout << formatFPNumber(1.3754937356458394574047e14) << endl;
cout << formatFPNumber(1.3754937356458394574047e15) << endl;
cout << formatFPNumber(1.3754937356458394574047e16) << endl;
cout << formatFPNumber(1.3754937356458394574047e17) << endl;
cout << formatFPNumber(1.3754937356458394574047e18) << endl;
cout << formatFPNumber(1.3754937356458394574047e19) << endl;
cout << formatFPNumber(1.3754937356458394574047e20) << endl;
cout << formatFPNumber(1e-42) << endl;
cout << formatFPNumber(1e42) << endl;
}
int main()
{
test_lowercase();
test_uppercase();
test_formatFPNumber();
}

View File

@ -5,3 +5,49 @@ alle
A
ALLE
A
0
1
23.42
0.00000000000000000001375494
0.0000000000000000001375494
0.000000000000000001375494
0.00000000000000001375494
0.0000000000000001375494
0.000000000000001375494
0.00000000000001375494
0.0000000000001375494
0.000000000001375494
0.00000000001375494
0.0000000001375494
0.000000001375494
0.00000001375494
0.0000001375494
0.000001375494
0.00001375494
0.0001375494
0.001375494
0.01375494
0.1375494
1.375494
13.75494
137.5494
1375.494
13754.94
137549.4
1375494
13754937
137549374
1375493736
13754937356
137549373565
1375493735646
13754937356458
137549373564584
1375493735645840
13754937356458394
137549373564583952
1375493735645839360
13754937356458393600
137549373564583952384
0.000000000000000000000000000000000000000001
1000000000000000044885712678075916785549312