Current Version: 1.0.10
Project Name: csspp
csspp.cpp
Go to the documentation of this file.
1 // CSS Preprocessor
2 // Copyright (C) 2015-2016 Made to Order Software Corp.
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 
28 #include "csspp/csspp.h"
29 
30 #include "csspp/exceptions.h"
31 
32 #include <cmath>
33 #include <cfloat>
34 #include <iomanip>
35 #include <sstream>
36 #include <iostream>
37 
45 namespace csspp
46 {
47 
48 namespace
49 {
50 
51 int g_precision = 3;
52 
53 } // no name namespace
54 
55 char const * csspp_library_version()
56 {
57  return CSSPP_VERSION;
58 }
59 
61 {
62  return g_precision;
63 }
64 
65 void set_precision(int precision)
66 {
67  if(precision < 0 || precision > 10)
68  {
69  throw csspp_exception_overflow("precision must be between 0 and 10, " + std::to_string(precision) + " is out of bounds.");
70  }
71 
72  g_precision = precision;
73 }
74 
75 std::string decimal_number_to_string(decimal_number_t d, bool remove_leading_zero)
76 {
77  // the std::setprecision() is a total number of digits when we
78  // want a specific number of digits after the decimal point so
79  // we use the following algorithm for it:
80  std::stringstream ss;
81 
82  // use the maximum precision so we do not get any surprises
83  // see the following for the "3 + DBL_MANT_DIG - DBL_MIN_EXP":
84  // http://stackoverflow.com/questions/1701055/what-is-the-maximum-length-in-chars-needed-to-represent-any-double-value
85  ss << std::setprecision(3 + DBL_MANT_DIG - DBL_MIN_EXP);
86 
87  // make sure to round the value up first
88  if(d >= 0.0)
89  {
90  ss << d + 0.5 / pow(10.0, g_precision);
91  }
92  else
93  {
94  ss << d - 0.5 / pow(10.0, g_precision);
95  }
96 
97  std::string out(ss.str());
98 
99  // check wether the number of digits after the decimal point is too large
100  std::string::size_type end(out.find('.'));
101  if(end != std::string::npos
102  && out.length() > end + g_precision + 1)
103  {
104  // remove anything extra
105  out = out.substr(0, end + g_precision + 1);
106  }
107  if(out.find('.') != std::string::npos
108  && end != std::string::npos)
109  {
110  while(out.back() == '0')
111  {
112  out.erase(out.end() - 1);
113  }
114  if(out.back() == '.')
115  {
116  out.erase(out.end() - 1);
117  }
118  }
119 
120  // remove the leading zero when possible
121  if(remove_leading_zero)
122  {
123  if(out.length() >= 3
124  && out[0] == '0'
125  && out[1] == '.')
126  {
127  out.erase(out.begin());
128  // .33 is valid and equivalent to 0.33
129  }
130  else if(out.length() >= 4
131  && out[0] == '-'
132  && out[1] == '0'
133  && out[2] == '.')
134  {
135  out.erase(out.begin() + 1);
136  // -.33 is valid and equivalent to -0.33
137  }
138  }
139 
140  if(out == "-0")
141  {
142  // this happens with really small numbers because we lose
143  // the precision and thus end up with zero even if the number
144  // was not really zero
145  return "0";
146  }
147 
148  return out;
149 }
150 
151 } // namespace csspp
152 
153 // Local Variables:
154 // mode: cpp
155 // indent-tabs-mode: nil
156 // c-basic-offset: 4
157 // tab-width: 4
158 // End:
159 
160 // vim: ts=4 sw=4 et
std::string decimal_number_to_string(decimal_number_t d, bool remove_leading_zero)
Definition: csspp.cpp:75
int get_precision()
Definition: csspp.cpp:60
void set_precision(int precision)
Definition: csspp.cpp:65
char const * csspp_library_version()
Definition: csspp.cpp:55
double decimal_number_t
Definition: csspp.h:53
#define CSSPP_VERSION
Definition: csspp.h:47

Documentation of CSS Preprocessor.

This document is part of the Snap! Websites Project.

Copyright by Made to Order Software Corp.