@@ -121,6 +121,66 @@ real::operator double() const | |||||
return u.d; | return u.d; | ||||
} | } | ||||
/* | |||||
* Create a real number from an ASCII representation | |||||
*/ | |||||
real::real(char const *str) | |||||
{ | |||||
real ret = 0; | |||||
int exponent = 0; | |||||
bool comma = false, nonzero = false, negative = false, finished = false; | |||||
for (char const *p = str; *p && !finished; p++) | |||||
{ | |||||
switch (*p) | |||||
{ | |||||
case '-': | |||||
case '+': | |||||
if (p != str) | |||||
break; | |||||
negative = (*p == '-'); | |||||
break; | |||||
case '.': | |||||
if (comma) | |||||
finished = true; | |||||
comma = true; | |||||
break; | |||||
case '0': case '1': case '2': case '3': case '4': | |||||
case '5': case '6': case '7': case '8': case '9': | |||||
if (nonzero) | |||||
{ | |||||
real x = ret + ret; | |||||
x = x + x + ret; | |||||
ret = x + x; | |||||
} | |||||
if (*p != '0') | |||||
{ | |||||
ret += (int)(*p - '0'); | |||||
nonzero = true; | |||||
} | |||||
if (comma) | |||||
exponent--; | |||||
break; | |||||
case 'e': | |||||
case 'E': | |||||
exponent += atoi(p + 1); | |||||
finished = true; | |||||
break; | |||||
default: | |||||
finished = true; | |||||
break; | |||||
} | |||||
} | |||||
if (exponent) | |||||
ret *= pow(R_10, (real)exponent); | |||||
if (negative) | |||||
ret = -ret; | |||||
new(this) real(ret); | |||||
} | |||||
real real::operator +() const | real real::operator +() const | ||||
{ | { | ||||
return *this; | return *this; | ||||
@@ -37,6 +37,8 @@ public: | |||||
real(int i); | real(int i); | ||||
real(unsigned int i); | real(unsigned int i); | ||||
real(char const *str); | |||||
operator float() const; | operator float() const; | ||||
operator double() const; | operator double() const; | ||||
operator int() const; | operator int() const; | ||||
@@ -103,6 +103,23 @@ LOLUNIT_FIXTURE(RealTest) | |||||
LOLUNIT_ASSERT_DOUBLES_EQUAL(a6, 1234567876543210.0, 0.0); | LOLUNIT_ASSERT_DOUBLES_EQUAL(a6, 1234567876543210.0, 0.0); | ||||
} | } | ||||
LOLUNIT_TEST(StringToReal) | |||||
{ | |||||
float a1 = real("0"); | |||||
float a2 = real("1"); | |||||
float a3 = real("-1"); | |||||
/* 2^-128 * 2^128 */ | |||||
float a4 = real("0.0000000000000000000000000000000000000029387358770" | |||||
"557187699218413430556141945466638919302188037718792" | |||||
"6569604314863681793212890625") | |||||
* real("340282366920938463463374607431768211456"); | |||||
LOLUNIT_ASSERT_EQUAL(a1, 0.0f); | |||||
LOLUNIT_ASSERT_EQUAL(a2, 1.0f); | |||||
LOLUNIT_ASSERT_EQUAL(a3, -1.0f); | |||||
LOLUNIT_ASSERT_EQUAL(a4, 1.0f); | |||||
} | |||||
LOLUNIT_TEST(UnaryMinus) | LOLUNIT_TEST(UnaryMinus) | ||||
{ | { | ||||
float a1 = - real(1.0f); | float a1 = - real(1.0f); | ||||