diff --git a/src/real.cpp b/src/real.cpp
index 066cb38e..f62b5ec9 100644
--- a/src/real.cpp
+++ b/src/real.cpp
@@ -121,6 +121,66 @@ real::operator double() const
     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
 {
     return *this;
diff --git a/src/real.h b/src/real.h
index 1cbc2328..acaaecfe 100644
--- a/src/real.h
+++ b/src/real.h
@@ -37,6 +37,8 @@ public:
     real(int i);
     real(unsigned int i);
 
+    real(char const *str);
+
     operator float() const;
     operator double() const;
     operator int() const;
diff --git a/test/unit/real.cpp b/test/unit/real.cpp
index 6047ce87..70612ef9 100644
--- a/test/unit/real.cpp
+++ b/test/unit/real.cpp
@@ -103,6 +103,23 @@ LOLUNIT_FIXTURE(RealTest)
         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)
     {
         float a1 = - real(1.0f);