| @@ -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); | ||||