12 #ifndef XPACE_DECIMAL_FLOAT_H 13 #define XPACE_DECIMAL_FLOAT_H 96 template <
typename STR>
99 typename STR::charType decimalChar =
'.')
110 template <
typename STR>
113 uint precision = ~0);
122 if (
_i64toa_s(val, reinterpret_cast<char*>(dest), size, 10))
125 *
len = strlen(reinterpret_cast<char*>(dest));
136 if (
_i64tow_s(val, reinterpret_cast<wchar_t*>(dest), size, 10))
139 *
len = wcslen(reinterpret_cast<wchar_t*>(dest));
164 from_raw_string(str, precision);
174 from_raw_string(str, precision);
186 template <
typename STR>
190 typename STR::charType decimalChar)
197 if (!itoafn(mantissa, str->data + 1, str->length - 1, &len))
199 typename STR::charType* ch(str->data);
200 for (; ch < str->data + len - decimals; ++ch)
203 str->length = len + 1;
209 if (!itoafn(mantissa, str->data, str->length + decimals, &len))
211 typename STR::charType* ch(str->data + len);
212 for (; ch < str->data + len - decimals; ++ch)
217 if (!itoafn(mantissa, str->data, str->length, &len))
235 template <
typename STR>
237 bool DecimalFloat::from_raw_string
241 typename STR::charType buf[256];
242 typename STR::charType* b(buf);
243 const typename STR::charType* d(str.data);
244 uint len(narrow_to<uint>(str.length));
246 for (
uint i(0); i <
len; ++i, ++d)
251 decimals = len - i - 1;
254 decimals = std::min(precision, len - i - 1);
255 len = std::min(len, i + precision + 1);
260 else if ((*d >=
'0') && (*d <=
'9'))
269 while ((decimals > 0) && (b > buf) && (*--b ==
'0'))
275 mantissa = (
sizeof(
typename STR::charType) == 1) ?
_atoi64(reinterpret_cast<const char*>(buf)) :
_wtoi64(reinterpret_cast<const wchar_t*>(buf));
277 if (mantissa == std::numeric_limits<int64>::max())
284 mantissa = -mantissa;
286 if ((len < str.length) && (*d >=
'5') && (*d <=
'9'))
307 DecimalFloat::operator double
311 return double(mantissa) /
pow10_64(decimals);
319 if (decimals == rhs.decimals)
321 if (mantissa == rhs.mantissa)
323 return (mantissa < rhs.mantissa) ? -1 : 1;
326 if (decimals > rhs.decimals)
329 return (mantissa == rm) ? 0 : ((mantissa < rm) ? -1 : 1);
334 return (lm == rhs.mantissa) ? 0 : ((lm < rhs.mantissa) ? -1 : 1);
338 bool DecimalFloat::operator==
342 if (decimals == rhs.decimals)
343 return mantissa == rhs.mantissa;
344 if (decimals < rhs.decimals)
345 return int64(mantissa *
pow10_64(rhs.decimals - decimals)) == rhs.mantissa;
346 return mantissa ==
int64(rhs.mantissa *
pow10_64(decimals - rhs.decimals));
350 bool DecimalFloat::operator!=
354 return !(*
this == rhs);
String toString(utf16_t decimalChar= '.') const
int64 getMantissa() const
DecimalFloat(const String8 &str, uint precision=~0)
int sprintf_s(char *, size_t, const char *,...)
A string, Unicode UTF-16 and reference-counted.
uint const Xpace_Char8 size_t len
const utf16_t * toUtf16() const
A floatimg-point number with explicit mantissa and decimals TODO: normalize.
uint64 XPACE_EXPORT pow10_64(uint p)
int64 _wtoi64(const wchar_t *)
int64 _atoi64(const char *)
errno_t _i64tow_s(int64, wchar_t *, size_t, int)
errno_t _i64toa_s(int64, char *, size_t, int)
RawString< utf8_t > String8
Xpace project main namespace
bool toRawString(STR *str, typename STR::charType decimalChar= '.') const
int compare(const DecimalFloat &rhs) const