mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Decimal conversion of Number to zt-string (still not precise enough). Zt-string copy and length calculation helpers.
This commit is contained in:
parent
e35f54fe86
commit
813831a23b
@ -37,7 +37,7 @@ typedef signed long ssize_t;
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
#define JERRY_BITSINBYTE 8u
|
||||
#define JERRY_BITSINBYTE 8
|
||||
|
||||
/**
|
||||
* Error codes
|
||||
|
||||
@ -527,6 +527,11 @@ typedef double ecma_number_t;
|
||||
*/
|
||||
#define ECMA_NUMBER_ONE ((ecma_number_t) 1)
|
||||
|
||||
/**
|
||||
* Null character (zt-string end marker)
|
||||
*/
|
||||
#define ECMA_CHAR_NULL ((ecma_char_t) '\0')
|
||||
|
||||
/**
|
||||
* Maximum number of characters in string representation of ecma-number
|
||||
*/
|
||||
|
||||
@ -31,11 +31,16 @@
|
||||
* See also:
|
||||
* ECMA-262 v5, 9.3.1
|
||||
*
|
||||
* Warning:
|
||||
* the conversion routine may be not precise for some cases
|
||||
*
|
||||
* @return ecma-number
|
||||
*/
|
||||
ecma_number_t
|
||||
ecma_zt_string_to_number (const ecma_char_t *str_p) /**< zero-terminated string */
|
||||
{
|
||||
TODO (Check conversion precision);
|
||||
|
||||
const ecma_char_t dec_digits_range[10] = { '0', '9' };
|
||||
const ecma_char_t hex_lower_digits_range[10] = { 'a', 'f' };
|
||||
const ecma_char_t hex_upper_digits_range[10] = { 'A', 'F' };
|
||||
@ -45,11 +50,10 @@ ecma_zt_string_to_number (const ecma_char_t *str_p) /**< zero-terminated string
|
||||
const ecma_char_t plus_char = '+';
|
||||
const ecma_char_t minus_char = '-';
|
||||
const ecma_char_t dot_char = '.';
|
||||
const ecma_char_t null_char = '\0';
|
||||
|
||||
const ecma_char_t *begin_p = str_p;
|
||||
const ecma_char_t *end_p = begin_p;
|
||||
while (*end_p != null_char)
|
||||
while (*end_p != ECMA_CHAR_NULL)
|
||||
{
|
||||
end_p++;
|
||||
}
|
||||
@ -332,10 +336,9 @@ ecma_uint32_to_string (uint32_t value, /**< value to convert */
|
||||
ssize_t buffer_size) /**< size of buffer */
|
||||
{
|
||||
const ecma_char_t digits[10] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
|
||||
const ecma_char_t null_char = '\0';
|
||||
|
||||
ecma_char_t *p = (ecma_char_t*) ((uint8_t*) out_buffer_p + buffer_size) - 1;
|
||||
*p-- = null_char;
|
||||
*p-- = ECMA_CHAR_NULL;
|
||||
|
||||
size_t bytes_copied = sizeof (ecma_char_t);
|
||||
|
||||
@ -435,6 +438,10 @@ ecma_number_to_int32 (ecma_number_t value) /**< unsigned 32-bit integer value */
|
||||
* See also:
|
||||
* ECMA-262 v5, 9.8.1
|
||||
*
|
||||
* Warning:
|
||||
* the conversion is not precise for all cases
|
||||
* For example, 12345.0f converts to "12344.99931".
|
||||
*
|
||||
* @return length of zt-string
|
||||
*/
|
||||
ecma_length_t
|
||||
@ -442,18 +449,20 @@ ecma_number_to_zt_string (ecma_number_t num, /**< ecma-number */
|
||||
ecma_char_t *buffer_p, /**< buffer for zt-string */
|
||||
ssize_t buffer_size) /**< size of buffer */
|
||||
{
|
||||
FIXME (Conversion precision);
|
||||
|
||||
const ecma_char_t digits[10] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
|
||||
const ecma_char_t e_chars [2] = { 'e', 'E' };
|
||||
const ecma_char_t plus_char = '+';
|
||||
const ecma_char_t minus_char = '-';
|
||||
const ecma_char_t dot_char = '.';
|
||||
const ecma_char_t null_char = '\0';
|
||||
|
||||
if (ecma_number_is_nan (num))
|
||||
{
|
||||
// 1.
|
||||
FIXME (/* Assert that buffer's size is enough */);
|
||||
__strncpy ((char*) buffer_p, (char*) ecma_get_magic_string_zt (ECMA_MAGIC_STRING_NAN), (size_t) buffer_size);
|
||||
ecma_copy_zt_string_to_buffer (ecma_get_magic_string_zt (ECMA_MAGIC_STRING_NAN),
|
||||
buffer_p,
|
||||
buffer_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -463,7 +472,7 @@ ecma_number_to_zt_string (ecma_number_t num, /**< ecma-number */
|
||||
{
|
||||
// 2.
|
||||
*dst_p++ = digits[0];
|
||||
*dst_p++ = null_char;
|
||||
*dst_p++ = ECMA_CHAR_NULL;
|
||||
|
||||
JERRY_ASSERT ((uint8_t*)dst_p - (uint8_t*)buffer_p <= (ssize_t) buffer_size);
|
||||
}
|
||||
@ -477,129 +486,268 @@ ecma_number_to_zt_string (ecma_number_t num, /**< ecma-number */
|
||||
else if (ecma_number_is_infinity (num))
|
||||
{
|
||||
// 4.
|
||||
FIXME (/* Assert that buffer's size is enough */);
|
||||
__strncpy ((char*) buffer_p, (char*) ecma_get_magic_string_zt (ECMA_MAGIC_STRING_INFINITY), (size_t) buffer_size);
|
||||
ecma_copy_zt_string_to_buffer (ecma_get_magic_string_zt (ECMA_MAGIC_STRING_INFINITY),
|
||||
buffer_p,
|
||||
buffer_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 5.
|
||||
uint64_t fraction;
|
||||
#ifdef CONFIG_ECMA_NUMBER_FLOAT32
|
||||
#define LL_T uint32_t
|
||||
#define LL_MAX_DIGITS 10
|
||||
#elif defined (CONFIG_ECMA_NUMBER_FLOAT64)
|
||||
#define LL_T uint64_t
|
||||
#define LL_MAX_DIGITS 18
|
||||
#else /* !CONFIG_ECMA_NUMBER_FLOAT32 && !CONFIG_ECMA_NUMBER_FLOAT64 */
|
||||
# error "!CONFIG_ECMA_NUMBER_FLOAT32 && !CONFIG_ECMA_NUMBER_FLOAT64"
|
||||
#endif /* !CONFIG_ECMA_NUMBER_FLOAT32 && !CONFIG_ECMA_NUMBER_FLOAT64 */
|
||||
|
||||
uint64_t fraction_uint64;
|
||||
LL_T fraction;
|
||||
int32_t exponent;
|
||||
int32_t dot_shift;
|
||||
dot_shift = ecma_number_get_fraction_and_exponent (num, &fraction, &exponent);
|
||||
int32_t decimal_exp = 0;
|
||||
|
||||
FIXME (Decimal representation);
|
||||
dot_shift = ecma_number_get_fraction_and_exponent (num, &fraction_uint64, &exponent);
|
||||
|
||||
uint64_t s = fraction;
|
||||
int32_t n = exponent + 1;
|
||||
int32_t k = dot_shift;
|
||||
fraction = (LL_T) fraction_uint64;
|
||||
JERRY_ASSERT (fraction == fraction_uint64);
|
||||
|
||||
JERRY_ASSERT (s != 0);
|
||||
while (!(s & 1))
|
||||
if (exponent != 0)
|
||||
{
|
||||
s >>= 1;
|
||||
k--;
|
||||
ecma_number_t t = 1.0f;
|
||||
bool do_divide;
|
||||
|
||||
if (exponent < 0)
|
||||
{
|
||||
do_divide = true;
|
||||
|
||||
while (exponent <= 0)
|
||||
{
|
||||
t *= 2.0f;
|
||||
exponent++;
|
||||
|
||||
if (t >= 10.0f)
|
||||
{
|
||||
t /= 10.0f;
|
||||
decimal_exp--;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (t < 10.0f);
|
||||
}
|
||||
|
||||
while (t > 1.0f)
|
||||
{
|
||||
exponent--;
|
||||
t /= 2.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do_divide = false;
|
||||
|
||||
while (exponent >= 0)
|
||||
{
|
||||
t *= 2.0f;
|
||||
exponent--;
|
||||
|
||||
if (t >= 10.0f)
|
||||
{
|
||||
t /= 10.0f;
|
||||
decimal_exp++;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (t < 10.0f);
|
||||
}
|
||||
|
||||
while (t > 2.0f)
|
||||
{
|
||||
exponent++;
|
||||
t /= 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_divide)
|
||||
{
|
||||
fraction = (LL_T) ((ecma_number_t) fraction / t);
|
||||
}
|
||||
else
|
||||
{
|
||||
fraction = (LL_T) ((ecma_number_t) fraction * t);
|
||||
}
|
||||
}
|
||||
|
||||
LL_T s;
|
||||
int32_t n;
|
||||
int32_t k;
|
||||
|
||||
if (exponent > 0)
|
||||
{
|
||||
fraction <<= exponent;
|
||||
}
|
||||
else
|
||||
{
|
||||
fraction >>= -exponent;
|
||||
}
|
||||
|
||||
const int32_t int_part_shift = dot_shift;
|
||||
const LL_T frac_part_mask = ((((LL_T)1) << int_part_shift) - 1);
|
||||
|
||||
LL_T int_part = fraction >> int_part_shift;
|
||||
LL_T frac_part = fraction & frac_part_mask;
|
||||
|
||||
s = int_part;
|
||||
k = 1;
|
||||
n = decimal_exp + 1;
|
||||
|
||||
JERRY_ASSERT (int_part < 10);
|
||||
|
||||
while (k < LL_MAX_DIGITS
|
||||
&& frac_part != 0)
|
||||
{
|
||||
frac_part *= 10;
|
||||
|
||||
LL_T new_frac_part = frac_part & frac_part_mask;
|
||||
LL_T digit = (frac_part - new_frac_part) >> int_part_shift;
|
||||
s = s * 10 + digit;
|
||||
k++;
|
||||
frac_part = new_frac_part;
|
||||
}
|
||||
|
||||
// 6.
|
||||
if (k <= n && n <= 21)
|
||||
{
|
||||
for (int32_t i = 0; i < k; i++)
|
||||
{
|
||||
uint64_t bit_mask = 1ul << (k - i - 1);
|
||||
*dst_p++ = digits [(s & bit_mask) ? 1 : 0];
|
||||
}
|
||||
dst_p += n;
|
||||
JERRY_ASSERT ((ssize_t) sizeof (ecma_char_t) * ((dst_p - buffer_p) + 1) <= buffer_size);
|
||||
|
||||
*dst_p = ECMA_CHAR_NULL;
|
||||
|
||||
for (int32_t i = 0; i < n - k; i++)
|
||||
{
|
||||
*dst_p++ = digits [0];
|
||||
*--dst_p = digits [0];
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < k; i++)
|
||||
{
|
||||
*--dst_p = digits [s % 10];
|
||||
s /= 10;
|
||||
}
|
||||
}
|
||||
else if (0 < n && n <= 21)
|
||||
{
|
||||
// 7.
|
||||
for (int32_t i = 0; i < n; i++)
|
||||
dst_p += k + 1;
|
||||
JERRY_ASSERT ((ssize_t) sizeof (ecma_char_t) * ((dst_p - buffer_p) + 1) <= buffer_size);
|
||||
|
||||
*dst_p = ECMA_CHAR_NULL;
|
||||
|
||||
for (int32_t i = 0; i < k - n; i++)
|
||||
{
|
||||
uint64_t bit_mask = 1ul << (k - i - 1);
|
||||
*dst_p++ = digits [(s & bit_mask) ? 1 : 0];
|
||||
*--dst_p = digits [s % 10];
|
||||
s /= 10;
|
||||
}
|
||||
|
||||
*dst_p++ = dot_char;
|
||||
*--dst_p = dot_char;
|
||||
|
||||
for (int32_t i = n; i < k; i++)
|
||||
for (int32_t i = 0; i < n; i++)
|
||||
{
|
||||
uint64_t bit_mask = 1ul << (k - i - 1);
|
||||
*dst_p++ = digits [(s & bit_mask) ? 1 : 0];
|
||||
*--dst_p = digits [s % 10];
|
||||
s /= 10;
|
||||
}
|
||||
}
|
||||
else if (-6 <= n && n <= 0)
|
||||
{
|
||||
// 8.
|
||||
*dst_p++ = digits [0];
|
||||
*dst_p++ = '.';
|
||||
dst_p += k - n + 1 + 1;
|
||||
JERRY_ASSERT ((ssize_t) sizeof (ecma_char_t) * ((dst_p - buffer_p) + 1) <= buffer_size);
|
||||
|
||||
*dst_p = ECMA_CHAR_NULL;
|
||||
|
||||
for (int32_t i = 0; i < k; i++)
|
||||
{
|
||||
uint64_t bit_mask = 1ul << (k - i - 1);
|
||||
*dst_p++ = digits [(s & bit_mask) ? 1 : 0];
|
||||
*--dst_p = digits [s % 10];
|
||||
s /= 10;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < -n; i++)
|
||||
{
|
||||
*--dst_p = digits [0];
|
||||
}
|
||||
|
||||
*--dst_p = dot_char;
|
||||
*--dst_p = digits[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (k == 1)
|
||||
{
|
||||
// 9.
|
||||
*dst_p++ = digits [s ? 1 : 0];
|
||||
JERRY_ASSERT ((ssize_t) sizeof (ecma_char_t) <= buffer_size);
|
||||
|
||||
*dst_p++ = digits [s % 10];
|
||||
s /= 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 10.
|
||||
uint64_t bit_mask = 1ul << (k - 1);
|
||||
*dst_p++ = digits [(s & bit_mask) ? 1 : 0];
|
||||
*dst_p++ = dot_char;
|
||||
for (int32_t i = 1; i < k; i++)
|
||||
dst_p += k + 1;
|
||||
JERRY_ASSERT ((ssize_t) sizeof (ecma_char_t) * (dst_p - buffer_p) <= buffer_size);
|
||||
|
||||
for (int32_t i = 0; i < k - 1; i++)
|
||||
{
|
||||
bit_mask = 1ul << (k - i - 1);
|
||||
*dst_p++ = digits [(s & bit_mask) ? 1 : 0];
|
||||
*--dst_p = digits [s % 10];
|
||||
s /= 10;
|
||||
}
|
||||
|
||||
*--dst_p = dot_char;
|
||||
*--dst_p = digits[s % 10];
|
||||
s /= 10;
|
||||
|
||||
dst_p += k + 1;
|
||||
}
|
||||
|
||||
// 9., 10.
|
||||
JERRY_ASSERT ((ssize_t) sizeof (ecma_char_t) * (dst_p - buffer_p + 2) <= buffer_size);
|
||||
*dst_p++ = e_chars[0];
|
||||
*dst_p++ = (n >= 1) ? plus_char : minus_char;
|
||||
int32_t t = (n >= 1) ? (n - 1) : -(n - 1);
|
||||
|
||||
if (t == 0)
|
||||
{
|
||||
JERRY_ASSERT ((ssize_t) sizeof (ecma_char_t) * (dst_p - buffer_p + 1) <= buffer_size);
|
||||
*dst_p++ = digits [0];
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t t_bit = (1u << 31);
|
||||
int32_t t_mod = 1000000000u;
|
||||
|
||||
while ((t & (int32_t) t_bit) == 0)
|
||||
while ((t / t_mod) == 0)
|
||||
{
|
||||
t_bit >>= 1;
|
||||
t_mod /= 10;
|
||||
|
||||
JERRY_ASSERT (t_bit != 0);
|
||||
JERRY_ASSERT (t_mod != 0);
|
||||
}
|
||||
|
||||
while (t_bit != 0)
|
||||
while (t_mod != 0)
|
||||
{
|
||||
*dst_p++ = digits [(t & (int32_t) t_bit) ? 1 : 0];
|
||||
JERRY_ASSERT ((ssize_t) sizeof (ecma_char_t) * (dst_p - buffer_p + 1) <= buffer_size);
|
||||
*dst_p++ = digits [t / t_mod];
|
||||
|
||||
t_bit >>= 1;
|
||||
t -= (t / t_mod) * t_mod;
|
||||
t_mod /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
JERRY_ASSERT ((ssize_t) sizeof (ecma_char_t) * (dst_p - buffer_p + 1) <= buffer_size);
|
||||
*dst_p++ = ECMA_CHAR_NULL;
|
||||
}
|
||||
|
||||
*dst_p++ = null_char;
|
||||
|
||||
JERRY_ASSERT ((uint8_t*)dst_p - (uint8_t*)buffer_p <= (ssize_t) buffer_size);
|
||||
JERRY_ASSERT (s == 0);
|
||||
}
|
||||
}
|
||||
|
||||
ecma_length_t length = (ecma_length_t) __strlen ((char*) buffer_p);
|
||||
ecma_length_t length = ecma_zt_string_length (buffer_p);
|
||||
|
||||
return length;
|
||||
} /* ecma_number_to_zt_string */
|
||||
|
||||
@ -347,7 +347,7 @@ ecma_number_get_fraction_and_exponent (ecma_number_t num, /**< ecma-number */
|
||||
|
||||
*out_fraction_p = fraction;
|
||||
*out_exponent_p = exponent;
|
||||
return ECMA_NUMBER_FRACTION_WIDTH + 1;
|
||||
return ECMA_NUMBER_FRACTION_WIDTH;
|
||||
} /* ecma_number_get_fraction_and_exponent */
|
||||
|
||||
/**
|
||||
|
||||
@ -427,7 +427,8 @@ ecma_string_to_zt_string (const ecma_string_t *string_desc_p, /**< ecma-string d
|
||||
{
|
||||
const ecma_char_t *str_p = deserialize_string_by_id ((idx_t) string_desc_p->u.lit_index);
|
||||
JERRY_ASSERT (str_p != NULL);
|
||||
__strncpy ((char*)buffer_p, (const char*)str_p, string_desc_p->length + 1u);
|
||||
|
||||
ecma_copy_zt_string_to_buffer (str_p, buffer_p, required_buffer_size);
|
||||
JERRY_ASSERT (__strlen ((char*)buffer_p) == string_desc_p->length);
|
||||
|
||||
bytes_copied = (ssize_t) ((string_desc_p->length + 1u) * sizeof (ecma_char_t));
|
||||
@ -767,12 +768,78 @@ bool
|
||||
ecma_compare_zt_string_to_zt_string (const ecma_char_t *string1_p, /**< zero-terminated string */
|
||||
const ecma_char_t *string2_p) /**< zero-terminated string */
|
||||
{
|
||||
TODO (Implement comparison that supports UTF-16);
|
||||
const ecma_char_t *iter_1_p = string1_p;
|
||||
const ecma_char_t *iter_2_p = string2_p;
|
||||
|
||||
return (__strcmp ( (char*)string1_p, (char*)string2_p) == 0);
|
||||
while (*iter_1_p != ECMA_CHAR_NULL)
|
||||
{
|
||||
if (*iter_1_p++ != *iter_2_p++)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return (*iter_2_p == ECMA_CHAR_NULL);
|
||||
} /* ecma_compare_zt_string_to_zt_string */
|
||||
|
||||
/**
|
||||
* Copy zero-terminated string to buffer
|
||||
*
|
||||
* Warning:
|
||||
* the routine requires that buffer size is enough
|
||||
*
|
||||
* @return number of bytes copied
|
||||
*/
|
||||
ssize_t
|
||||
ecma_copy_zt_string_to_buffer (const ecma_char_t *string_p, /**< zero-terminated string */
|
||||
ecma_char_t *buffer_p, /**< destination buffer */
|
||||
ssize_t buffer_size) /**< size of buffer */
|
||||
{
|
||||
const ecma_char_t *str_iter_p = string_p;
|
||||
ecma_char_t *buf_iter_p = buffer_p;
|
||||
ssize_t bytes_copied = 0;
|
||||
|
||||
do
|
||||
{
|
||||
bytes_copied += (ssize_t) sizeof (ecma_char_t);
|
||||
JERRY_ASSERT (bytes_copied <= buffer_size);
|
||||
|
||||
*buf_iter_p++ = *str_iter_p++;
|
||||
}
|
||||
while (*str_iter_p != ECMA_CHAR_NULL);
|
||||
|
||||
bytes_copied += (ssize_t) sizeof (ecma_char_t);
|
||||
JERRY_ASSERT (bytes_copied <= buffer_size);
|
||||
|
||||
*buf_iter_p = ECMA_CHAR_NULL;
|
||||
|
||||
return bytes_copied;
|
||||
} /* ecma_copy_zt_string_to_buffer */
|
||||
|
||||
/**
|
||||
* Calculate zero-terminated string's length
|
||||
*
|
||||
* @return length of string
|
||||
*/
|
||||
ecma_length_t
|
||||
ecma_zt_string_length (const ecma_char_t *string_p) /**< zero-terminated string */
|
||||
{
|
||||
const ecma_char_t *str_iter_p = string_p;
|
||||
|
||||
ecma_length_t length = 0;
|
||||
|
||||
while (*str_iter_p++)
|
||||
{
|
||||
length++;
|
||||
|
||||
/* checking overflow */
|
||||
JERRY_ASSERT (length != 0);
|
||||
}
|
||||
|
||||
return length;
|
||||
} /* ecma_zt_string_length */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
@ -107,9 +107,11 @@ extern ecma_number_t ecma_string_to_number (const ecma_string_t *str_p);
|
||||
extern ssize_t ecma_string_to_zt_string (const ecma_string_t *string_desc_p,
|
||||
ecma_char_t *buffer_p,
|
||||
ssize_t buffer_size);
|
||||
extern bool ecma_compare_zt_string_to_zt_string (const ecma_char_t *string1_p, const ecma_char_t *string2_p);
|
||||
extern bool ecma_compare_ecma_string_to_ecma_string (const ecma_string_t *string1_p,
|
||||
const ecma_string_t *string2_p);
|
||||
extern bool ecma_compare_zt_string_to_zt_string (const ecma_char_t *string1_p, const ecma_char_t *string2_p);
|
||||
extern ssize_t ecma_copy_zt_string_to_buffer (const ecma_char_t *string_p, ecma_char_t *buffer_p, ssize_t buffer_size);
|
||||
extern ecma_length_t ecma_zt_string_length (const ecma_char_t *string_p);
|
||||
|
||||
/* ecma-helpers-number.c */
|
||||
extern ecma_number_t ecma_number_make_nan (void);
|
||||
|
||||
@ -30,10 +30,10 @@ main( int __unused argc,
|
||||
const ecma_char_t* zt_strings[] =
|
||||
{
|
||||
(const ecma_char_t*) "1",
|
||||
(const ecma_char_t*) "0.1",
|
||||
(const ecma_char_t*) "11000000111001",
|
||||
(const ecma_char_t*) "1e-10010101",
|
||||
(const ecma_char_t*) "-1.01111000001010001e+1111111",
|
||||
(const ecma_char_t*) "0.5",
|
||||
(const ecma_char_t*) "12344.99931",
|
||||
(const ecma_char_t*) "1.401298403e-45",
|
||||
(const ecma_char_t*) "-2.5e+38",
|
||||
(const ecma_char_t*) "NaN",
|
||||
(const ecma_char_t*) "Infinity",
|
||||
(const ecma_char_t*) "-Infinity",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user