diff --git a/modcc/lexer.cpp b/modcc/lexer.cpp
index ea371d104ea9c283a3dd47ca73636da18b2a7b65..0a85de24500d1f846c1f0156f863908453cca961 100644
--- a/modcc/lexer.cpp
+++ b/modcc/lexer.cpp
@@ -257,6 +257,10 @@ std::string Lexer::number() {
             uses_scientific_notation++;
             str += c;
             current_++;
+            // Consume the next char if +/-
+            if (*current_ == '+' || *current_ == '-') {
+                str += *current_++;
+            }
         }
         else {
             break;
diff --git a/tests/modcc/test_lexer.cpp b/tests/modcc/test_lexer.cpp
index 091a752b4ee0f25ea929bed86129ba7efc41e573..b7d94515798b966b2e6d39f26ab68f1787f46e4b 100644
--- a/tests/modcc/test_lexer.cpp
+++ b/tests/modcc/test_lexer.cpp
@@ -1,4 +1,5 @@
 #include <cmath>
+#include <iterator>
 
 #include "test.hpp"
 #include "lexer.hpp"
@@ -230,40 +231,36 @@ TEST(Lexer, comments) {
 
 // test numbers
 TEST(Lexer, numbers) {
-    char string[] = "1 .3 23 87.99 12. -3";
-    PRINT_LEX_STRING
-    Lexer lexer(string, string+sizeof(string));
-
-    auto t1 = lexer.parse();
-    EXPECT_EQ(t1.type, tok::number);
-    EXPECT_EQ(std::stod(t1.spelling), 1.0);
-
-    auto t2 = lexer.parse();
-    EXPECT_EQ(t2.type, tok::number);
-    EXPECT_EQ(std::stod(t2.spelling), 0.3);
-
-    auto t3 = lexer.parse();
-    EXPECT_EQ(t3.type, tok::number);
-    EXPECT_EQ(std::stod(t3.spelling), 23.0);
-
-    auto t4 = lexer.parse();
-    EXPECT_EQ(t4.type, tok::number);
-    EXPECT_EQ(std::stod(t4.spelling), 87.99);
-
-    auto t5 = lexer.parse();
-    EXPECT_EQ(t5.type, tok::number);
-    EXPECT_EQ(std::stod(t5.spelling), 12.0);
-
-    // the lexer does not decide where the - sign goes
-    // the parser uses additional contextual information to
-    // decide if the minus is a binary or unary expression
-    auto t6 = lexer.parse();
-    EXPECT_EQ(t6.type, tok::minus);
-
-    auto t7 = lexer.parse();
-    EXPECT_EQ(t7.type, tok::number);
-    EXPECT_EQ(std::stod(t7.spelling), 3.0);
-
-    auto t8 = lexer.parse();
-    EXPECT_EQ(t8.type, tok::eof);
+    std::istringstream floats_stream("1 23 .3 87.99 12. 1.e3 1.2e+2 23e-3 -3");
+
+    std::vector<double> floats;
+    std::copy(std::istream_iterator<double>(floats_stream),
+              std::istream_iterator<double>(),
+              std::back_inserter(floats));
+
+    Lexer lexer(floats_stream.str());
+    auto t = lexer.parse();
+    auto iter = floats.cbegin();
+    while (t.type != tok::eof && iter != floats.cend()) {
+        EXPECT_EQ(lexerStatus::happy, lexer.status());
+        if (*iter < 0) {
+            // the lexer does not decide where the - sign goes
+            // the parser uses additional contextual information to
+            // decide if the minus is a binary or unary expression
+            EXPECT_EQ(tok::minus, t.type);
+            t = lexer.parse();
+            EXPECT_EQ(tok::number, t.type);
+            EXPECT_EQ(-(*iter), std::stod(t.spelling));
+        }
+        else {
+            EXPECT_EQ(t.type, tok::number);
+            EXPECT_EQ(*iter, std::stod(t.spelling));
+        }
+
+        ++iter;
+        t = lexer.parse();
+    }
+
+    EXPECT_EQ(floats.cend(), iter);
+    EXPECT_EQ(tok::eof, t.type);
 }