diff --git a/src/json.hpp b/src/json.hpp
index 5ca6fd81..068c9658 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -5604,10 +5604,16 @@ class basic_json
 
             case value_t::number_float:
             {
-                // 15 digits of precision allows round-trip IEEE 754
-                // string->double->string; to be safe, we read this value from
-                // std::numeric_limits<number_float_t>::digits10
-                o << std::setprecision(std::numeric_limits<number_float_t>::digits10) << m_value.number_float;
+                // If the number is an integer then output as a fixed with with precision 1
+                // to output "0.0", "1.0" etc as expected for some round trip tests otherwise
+                // 15 digits of precision allows round-trip IEEE 754 string->double->string; 
+                // to be safe, we read this value from std::numeric_limits<number_float_t>::digits10
+                if (std::fmod(m_value.number_float, 1) == 0) o << std::fixed << std::setprecision(1);
+                else {
+                    o.unsetf(std::ios_base::floatfield);  // std::defaultfloat not supported in gcc version < 5
+                    o << std::setprecision(std::numeric_limits<double>::digits10);
+                }
+                o << m_value.number_float;
                 return;
             }
 
@@ -6812,789 +6818,386 @@ class basic_json
             m_start = m_cursor;
             assert(m_start != nullptr);
 
-
-            {
-                lexer_char_t yych;
-                unsigned int yyaccept = 0;
-                static const unsigned char yybm[] =
-                {
-                    0,   0,   0,   0,   0,   0,   0,   0,
-                    0,  32,  32,   0,   0,  32,   0,   0,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    96,  64,   0,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    192, 192, 192, 192, 192, 192, 192, 192,
-                    192, 192,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,   0,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                };
-                if ((m_limit - m_cursor) < 5)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
+            
+    {
+        lexer_char_t yych;
+        unsigned int yyaccept = 0;
+        static const unsigned char yybm[] = {
+              0,   0,   0,   0,   0,   0,   0,   0, 
+              0,  32,  32,   0,   0,  32,   0,   0, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             96,  64,   0,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+            192, 192, 192, 192, 192, 192, 192, 192, 
+            192, 192,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,   0,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+             64,  64,  64,  64,  64,  64,  64,  64, 
+        };
+        if ((m_limit - m_cursor) < 5) yyfill(); // LCOV_EXCL_LINE;
+        yych = *m_cursor;
+        if (yych <= ':') {
+            if (yych <= ' ') {
+                if (yych <= '\n') {
+                    if (yych <= 0x00) goto basic_json_parser_28;
+                    if (yych <= 0x08) goto basic_json_parser_30;
+                    if (yych >= '\n') goto basic_json_parser_4;
+                } else {
+                    if (yych == '\r') goto basic_json_parser_2;
+                    if (yych <= 0x1F) goto basic_json_parser_30;
                 }
-                yych = *m_cursor;
-                if (yych <= ':')
-                {
-                    if (yych <= ' ')
-                    {
-                        if (yych <= '\n')
-                        {
-                            if (yych <= 0x00)
-                            {
-                                goto basic_json_parser_28;
-                            }
-                            if (yych <= 0x08)
-                            {
-                                goto basic_json_parser_30;
-                            }
-                            if (yych >= '\n')
-                            {
-                                goto basic_json_parser_4;
-                            }
-                        }
-                        else
-                        {
-                            if (yych == '\r')
-                            {
-                                goto basic_json_parser_2;
-                            }
-                            if (yych <= 0x1F)
-                            {
-                                goto basic_json_parser_30;
-                            }
-                        }
+            } else {
+                if (yych <= ',') {
+                    if (yych == '"') goto basic_json_parser_27;
+                    if (yych <= '+') goto basic_json_parser_30;
+                    goto basic_json_parser_16;
+                } else {
+                    if (yych <= '/') {
+                        if (yych <= '-') goto basic_json_parser_23;
+                        goto basic_json_parser_30;
+                    } else {
+                        if (yych <= '0') goto basic_json_parser_24;
+                        if (yych <= '9') goto basic_json_parser_26;
+                        goto basic_json_parser_18;
                     }
-                    else
-                    {
-                        if (yych <= ',')
-                        {
-                            if (yych == '"')
-                            {
-                                goto basic_json_parser_27;
-                            }
-                            if (yych <= '+')
-                            {
-                                goto basic_json_parser_30;
-                            }
-                            goto basic_json_parser_16;
-                        }
-                        else
-                        {
-                            if (yych <= '/')
-                            {
-                                if (yych <= '-')
-                                {
-                                    goto basic_json_parser_23;
-                                }
-                                goto basic_json_parser_30;
-                            }
-                            else
-                            {
-                                if (yych <= '0')
-                                {
-                                    goto basic_json_parser_24;
-                                }
-                                if (yych <= '9')
-                                {
-                                    goto basic_json_parser_26;
-                                }
-                                goto basic_json_parser_18;
-                            }
-                        }
-                    }
-                }
-                else
-                {
-                    if (yych <= 'n')
-                    {
-                        if (yych <= ']')
-                        {
-                            if (yych == '[')
-                            {
-                                goto basic_json_parser_8;
-                            }
-                            if (yych <= '\\')
-                            {
-                                goto basic_json_parser_30;
-                            }
-                            goto basic_json_parser_10;
-                        }
-                        else
-                        {
-                            if (yych == 'f')
-                            {
-                                goto basic_json_parser_22;
-                            }
-                            if (yych <= 'm')
-                            {
-                                goto basic_json_parser_30;
-                            }
-                            goto basic_json_parser_20;
-                        }
-                    }
-                    else
-                    {
-                        if (yych <= '{')
-                        {
-                            if (yych == 't')
-                            {
-                                goto basic_json_parser_21;
-                            }
-                            if (yych <= 'z')
-                            {
-                                goto basic_json_parser_30;
-                            }
-                            goto basic_json_parser_12;
-                        }
-                        else
-                        {
-                            if (yych <= '}')
-                            {
-                                if (yych <= '|')
-                                {
-                                    goto basic_json_parser_30;
-                                }
-                                goto basic_json_parser_14;
-                            }
-                            else
-                            {
-                                if (yych == 0xEF)
-                                {
-                                    goto basic_json_parser_6;
-                                }
-                                goto basic_json_parser_30;
-                            }
-                        }
-                    }
-                }
-basic_json_parser_2:
-                ++m_cursor;
-                yych = *m_cursor;
-                goto basic_json_parser_5;
-basic_json_parser_3:
-                {
-                    return scan();
-                }
-basic_json_parser_4:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-basic_json_parser_5:
-                if (yybm[0 + yych] & 32)
-                {
-                    goto basic_json_parser_4;
-                }
-                goto basic_json_parser_3;
-basic_json_parser_6:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych == 0xBB)
-                {
-                    goto basic_json_parser_64;
-                }
-basic_json_parser_7:
-                {
-                    return token_type::parse_error;
-                }
-basic_json_parser_8:
-                ++m_cursor;
-                {
-                    return token_type::begin_array;
-                }
-basic_json_parser_10:
-                ++m_cursor;
-                {
-                    return token_type::end_array;
-                }
-basic_json_parser_12:
-                ++m_cursor;
-                {
-                    return token_type::begin_object;
-                }
-basic_json_parser_14:
-                ++m_cursor;
-                {
-                    return token_type::end_object;
-                }
-basic_json_parser_16:
-                ++m_cursor;
-                {
-                    return token_type::value_separator;
-                }
-basic_json_parser_18:
-                ++m_cursor;
-                {
-                    return token_type::name_separator;
-                }
-basic_json_parser_20:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych == 'u')
-                {
-                    goto basic_json_parser_60;
-                }
-                goto basic_json_parser_7;
-basic_json_parser_21:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych == 'r')
-                {
-                    goto basic_json_parser_56;
-                }
-                goto basic_json_parser_7;
-basic_json_parser_22:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych == 'a')
-                {
-                    goto basic_json_parser_51;
-                }
-                goto basic_json_parser_7;
-basic_json_parser_23:
-                yych = *++m_cursor;
-                if (yych <= '/')
-                {
-                    goto basic_json_parser_7;
-                }
-                if (yych <= '0')
-                {
-                    goto basic_json_parser_50;
-                }
-                if (yych <= '9')
-                {
-                    goto basic_json_parser_41;
-                }
-                goto basic_json_parser_7;
-basic_json_parser_24:
-                yyaccept = 1;
-                yych = *(m_marker = ++m_cursor);
-                if (yych <= 'D')
-                {
-                    if (yych == '.')
-                    {
-                        goto basic_json_parser_43;
-                    }
-                }
-                else
-                {
-                    if (yych <= 'E')
-                    {
-                        goto basic_json_parser_44;
-                    }
-                    if (yych == 'e')
-                    {
-                        goto basic_json_parser_44;
-                    }
-                }
-basic_json_parser_25:
-                {
-                    return token_type::value_number;
-                }
-basic_json_parser_26:
-                yyaccept = 1;
-                yych = *(m_marker = ++m_cursor);
-                goto basic_json_parser_42;
-basic_json_parser_27:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych <= 0x0F)
-                {
-                    goto basic_json_parser_7;
-                }
-                goto basic_json_parser_32;
-basic_json_parser_28:
-                ++m_cursor;
-                {
-                    return token_type::end_of_input;
-                }
-basic_json_parser_30:
-                yych = *++m_cursor;
-                goto basic_json_parser_7;
-basic_json_parser_31:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-basic_json_parser_32:
-                if (yybm[0 + yych] & 64)
-                {
-                    goto basic_json_parser_31;
-                }
-                if (yych <= 0x0F)
-                {
-                    goto basic_json_parser_33;
-                }
-                if (yych <= '"')
-                {
-                    goto basic_json_parser_35;
-                }
-                goto basic_json_parser_34;
-basic_json_parser_33:
-                m_cursor = m_marker;
-                if (yyaccept == 0)
-                {
-                    goto basic_json_parser_7;
-                }
-                else
-                {
-                    goto basic_json_parser_25;
-                }
-basic_json_parser_34:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= 'e')
-                {
-                    if (yych <= '/')
-                    {
-                        if (yych == '"')
-                        {
-                            goto basic_json_parser_31;
-                        }
-                        if (yych <= '.')
-                        {
-                            goto basic_json_parser_33;
-                        }
-                        goto basic_json_parser_31;
-                    }
-                    else
-                    {
-                        if (yych <= '\\')
-                        {
-                            if (yych <= '[')
-                            {
-                                goto basic_json_parser_33;
-                            }
-                            goto basic_json_parser_31;
-                        }
-                        else
-                        {
-                            if (yych == 'b')
-                            {
-                                goto basic_json_parser_31;
-                            }
-                            goto basic_json_parser_33;
-                        }
-                    }
-                }
-                else
-                {
-                    if (yych <= 'q')
-                    {
-                        if (yych <= 'f')
-                        {
-                            goto basic_json_parser_31;
-                        }
-                        if (yych == 'n')
-                        {
-                            goto basic_json_parser_31;
-                        }
-                        goto basic_json_parser_33;
-                    }
-                    else
-                    {
-                        if (yych <= 's')
-                        {
-                            if (yych <= 'r')
-                            {
-                                goto basic_json_parser_31;
-                            }
-                            goto basic_json_parser_33;
-                        }
-                        else
-                        {
-                            if (yych <= 't')
-                            {
-                                goto basic_json_parser_31;
-                            }
-                            if (yych <= 'u')
-                            {
-                                goto basic_json_parser_37;
-                            }
-                            goto basic_json_parser_33;
-                        }
-                    }
-                }
-basic_json_parser_35:
-                ++m_cursor;
-                {
-                    return token_type::value_string;
-                }
-basic_json_parser_37:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= '@')
-                {
-                    if (yych <= '/')
-                    {
-                        goto basic_json_parser_33;
-                    }
-                    if (yych >= ':')
-                    {
-                        goto basic_json_parser_33;
-                    }
-                }
-                else
-                {
-                    if (yych <= 'F')
-                    {
-                        goto basic_json_parser_38;
-                    }
-                    if (yych <= '`')
-                    {
-                        goto basic_json_parser_33;
-                    }
-                    if (yych >= 'g')
-                    {
-                        goto basic_json_parser_33;
-                    }
-                }
-basic_json_parser_38:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= '@')
-                {
-                    if (yych <= '/')
-                    {
-                        goto basic_json_parser_33;
-                    }
-                    if (yych >= ':')
-                    {
-                        goto basic_json_parser_33;
-                    }
-                }
-                else
-                {
-                    if (yych <= 'F')
-                    {
-                        goto basic_json_parser_39;
-                    }
-                    if (yych <= '`')
-                    {
-                        goto basic_json_parser_33;
-                    }
-                    if (yych >= 'g')
-                    {
-                        goto basic_json_parser_33;
-                    }
-                }
-basic_json_parser_39:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= '@')
-                {
-                    if (yych <= '/')
-                    {
-                        goto basic_json_parser_33;
-                    }
-                    if (yych >= ':')
-                    {
-                        goto basic_json_parser_33;
-                    }
-                }
-                else
-                {
-                    if (yych <= 'F')
-                    {
-                        goto basic_json_parser_40;
-                    }
-                    if (yych <= '`')
-                    {
-                        goto basic_json_parser_33;
-                    }
-                    if (yych >= 'g')
-                    {
-                        goto basic_json_parser_33;
-                    }
-                }
-basic_json_parser_40:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= '@')
-                {
-                    if (yych <= '/')
-                    {
-                        goto basic_json_parser_33;
-                    }
-                    if (yych <= '9')
-                    {
-                        goto basic_json_parser_31;
-                    }
-                    goto basic_json_parser_33;
-                }
-                else
-                {
-                    if (yych <= 'F')
-                    {
-                        goto basic_json_parser_31;
-                    }
-                    if (yych <= '`')
-                    {
-                        goto basic_json_parser_33;
-                    }
-                    if (yych <= 'f')
-                    {
-                        goto basic_json_parser_31;
-                    }
-                    goto basic_json_parser_33;
-                }
-basic_json_parser_41:
-                yyaccept = 1;
-                m_marker = ++m_cursor;
-                if ((m_limit - m_cursor) < 3)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-basic_json_parser_42:
-                if (yybm[0 + yych] & 128)
-                {
-                    goto basic_json_parser_41;
-                }
-                if (yych <= 'D')
-                {
-                    if (yych != '.')
-                    {
-                        goto basic_json_parser_25;
-                    }
-                }
-                else
-                {
-                    if (yych <= 'E')
-                    {
-                        goto basic_json_parser_44;
-                    }
-                    if (yych == 'e')
-                    {
-                        goto basic_json_parser_44;
-                    }
-                    goto basic_json_parser_25;
-                }
-basic_json_parser_43:
-                yych = *++m_cursor;
-                if (yych <= '/')
-                {
-                    goto basic_json_parser_33;
-                }
-                if (yych <= '9')
-                {
-                    goto basic_json_parser_48;
-                }
-                goto basic_json_parser_33;
-basic_json_parser_44:
-                yych = *++m_cursor;
-                if (yych <= ',')
-                {
-                    if (yych != '+')
-                    {
-                        goto basic_json_parser_33;
-                    }
-                }
-                else
-                {
-                    if (yych <= '-')
-                    {
-                        goto basic_json_parser_45;
-                    }
-                    if (yych <= '/')
-                    {
-                        goto basic_json_parser_33;
-                    }
-                    if (yych <= '9')
-                    {
-                        goto basic_json_parser_46;
-                    }
-                    goto basic_json_parser_33;
-                }
-basic_json_parser_45:
-                yych = *++m_cursor;
-                if (yych <= '/')
-                {
-                    goto basic_json_parser_33;
-                }
-                if (yych >= ':')
-                {
-                    goto basic_json_parser_33;
-                }
-basic_json_parser_46:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= '/')
-                {
-                    goto basic_json_parser_25;
-                }
-                if (yych <= '9')
-                {
-                    goto basic_json_parser_46;
-                }
-                goto basic_json_parser_25;
-basic_json_parser_48:
-                yyaccept = 1;
-                m_marker = ++m_cursor;
-                if ((m_limit - m_cursor) < 3)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= 'D')
-                {
-                    if (yych <= '/')
-                    {
-                        goto basic_json_parser_25;
-                    }
-                    if (yych <= '9')
-                    {
-                        goto basic_json_parser_48;
-                    }
-                    goto basic_json_parser_25;
-                }
-                else
-                {
-                    if (yych <= 'E')
-                    {
-                        goto basic_json_parser_44;
-                    }
-                    if (yych == 'e')
-                    {
-                        goto basic_json_parser_44;
-                    }
-                    goto basic_json_parser_25;
-                }
-basic_json_parser_50:
-                yyaccept = 1;
-                yych = *(m_marker = ++m_cursor);
-                if (yych <= 'D')
-                {
-                    if (yych == '.')
-                    {
-                        goto basic_json_parser_43;
-                    }
-                    goto basic_json_parser_25;
-                }
-                else
-                {
-                    if (yych <= 'E')
-                    {
-                        goto basic_json_parser_44;
-                    }
-                    if (yych == 'e')
-                    {
-                        goto basic_json_parser_44;
-                    }
-                    goto basic_json_parser_25;
-                }
-basic_json_parser_51:
-                yych = *++m_cursor;
-                if (yych != 'l')
-                {
-                    goto basic_json_parser_33;
-                }
-                yych = *++m_cursor;
-                if (yych != 's')
-                {
-                    goto basic_json_parser_33;
-                }
-                yych = *++m_cursor;
-                if (yych != 'e')
-                {
-                    goto basic_json_parser_33;
-                }
-                ++m_cursor;
-                {
-                    return token_type::literal_false;
-                }
-basic_json_parser_56:
-                yych = *++m_cursor;
-                if (yych != 'u')
-                {
-                    goto basic_json_parser_33;
-                }
-                yych = *++m_cursor;
-                if (yych != 'e')
-                {
-                    goto basic_json_parser_33;
-                }
-                ++m_cursor;
-                {
-                    return token_type::literal_true;
-                }
-basic_json_parser_60:
-                yych = *++m_cursor;
-                if (yych != 'l')
-                {
-                    goto basic_json_parser_33;
-                }
-                yych = *++m_cursor;
-                if (yych != 'l')
-                {
-                    goto basic_json_parser_33;
-                }
-                ++m_cursor;
-                {
-                    return token_type::literal_null;
-                }
-basic_json_parser_64:
-                yych = *++m_cursor;
-                if (yych != 0xBF)
-                {
-                    goto basic_json_parser_33;
-                }
-                ++m_cursor;
-                {
-                    return scan();
                 }
             }
+        } else {
+            if (yych <= 'n') {
+                if (yych <= ']') {
+                    if (yych == '[') goto basic_json_parser_8;
+                    if (yych <= '\\') goto basic_json_parser_30;
+                    goto basic_json_parser_10;
+                } else {
+                    if (yych == 'f') goto basic_json_parser_22;
+                    if (yych <= 'm') goto basic_json_parser_30;
+                    goto basic_json_parser_20;
+                }
+            } else {
+                if (yych <= '{') {
+                    if (yych == 't') goto basic_json_parser_21;
+                    if (yych <= 'z') goto basic_json_parser_30;
+                    goto basic_json_parser_12;
+                } else {
+                    if (yych <= '}') {
+                        if (yych <= '|') goto basic_json_parser_30;
+                        goto basic_json_parser_14;
+                    } else {
+                        if (yych == 0xEF) goto basic_json_parser_6;
+                        goto basic_json_parser_30;
+                    }
+                }
+            }
+        }
+basic_json_parser_2:
+        ++m_cursor;
+        yych = *m_cursor;
+        goto basic_json_parser_5;
+basic_json_parser_3:
+        { return scan(); }
+basic_json_parser_4:
+        ++m_cursor;
+        if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE;
+        yych = *m_cursor;
+basic_json_parser_5:
+        if (yybm[0+yych] & 32) {
+            goto basic_json_parser_4;
+        }
+        goto basic_json_parser_3;
+basic_json_parser_6:
+        yyaccept = 0;
+        yych = *(m_marker = ++m_cursor);
+        if (yych == 0xBB) goto basic_json_parser_64;
+basic_json_parser_7:
+        { return token_type::parse_error; }
+basic_json_parser_8:
+        ++m_cursor;
+        { return token_type::begin_array; }
+basic_json_parser_10:
+        ++m_cursor;
+        { return token_type::end_array; }
+basic_json_parser_12:
+        ++m_cursor;
+        { return token_type::begin_object; }
+basic_json_parser_14:
+        ++m_cursor;
+        { return token_type::end_object; }
+basic_json_parser_16:
+        ++m_cursor;
+        { return token_type::value_separator; }
+basic_json_parser_18:
+        ++m_cursor;
+        { return token_type::name_separator; }
+basic_json_parser_20:
+        yyaccept = 0;
+        yych = *(m_marker = ++m_cursor);
+        if (yych == 'u') goto basic_json_parser_60;
+        goto basic_json_parser_7;
+basic_json_parser_21:
+        yyaccept = 0;
+        yych = *(m_marker = ++m_cursor);
+        if (yych == 'r') goto basic_json_parser_56;
+        goto basic_json_parser_7;
+basic_json_parser_22:
+        yyaccept = 0;
+        yych = *(m_marker = ++m_cursor);
+        if (yych == 'a') goto basic_json_parser_51;
+        goto basic_json_parser_7;
+basic_json_parser_23:
+        yych = *++m_cursor;
+        if (yych <= '/') goto basic_json_parser_7;
+        if (yych <= '0') goto basic_json_parser_50;
+        if (yych <= '9') goto basic_json_parser_41;
+        goto basic_json_parser_7;
+basic_json_parser_24:
+        yyaccept = 1;
+        yych = *(m_marker = ++m_cursor);
+        if (yych <= 'D') {
+            if (yych == '.') goto basic_json_parser_43;
+        } else {
+            if (yych <= 'E') goto basic_json_parser_44;
+            if (yych == 'e') goto basic_json_parser_44;
+        }
+basic_json_parser_25:
+        { return token_type::value_number; }
+basic_json_parser_26:
+        yyaccept = 1;
+        yych = *(m_marker = ++m_cursor);
+        goto basic_json_parser_42;
+basic_json_parser_27:
+        yyaccept = 0;
+        yych = *(m_marker = ++m_cursor);
+        if (yych <= 0x0F) goto basic_json_parser_7;
+        goto basic_json_parser_32;
+basic_json_parser_28:
+        ++m_cursor;
+        { return token_type::end_of_input; }
+basic_json_parser_30:
+        yych = *++m_cursor;
+        goto basic_json_parser_7;
+basic_json_parser_31:
+        ++m_cursor;
+        if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE;
+        yych = *m_cursor;
+basic_json_parser_32:
+        if (yybm[0+yych] & 64) {
+            goto basic_json_parser_31;
+        }
+        if (yych <= 0x0F) goto basic_json_parser_33;
+        if (yych <= '"') goto basic_json_parser_35;
+        goto basic_json_parser_34;
+basic_json_parser_33:
+        m_cursor = m_marker;
+        if (yyaccept == 0) {
+            goto basic_json_parser_7;
+        } else {
+            goto basic_json_parser_25;
+        }
+basic_json_parser_34:
+        ++m_cursor;
+        if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE;
+        yych = *m_cursor;
+        if (yych <= 'e') {
+            if (yych <= '/') {
+                if (yych == '"') goto basic_json_parser_31;
+                if (yych <= '.') goto basic_json_parser_33;
+                goto basic_json_parser_31;
+            } else {
+                if (yych <= '\\') {
+                    if (yych <= '[') goto basic_json_parser_33;
+                    goto basic_json_parser_31;
+                } else {
+                    if (yych == 'b') goto basic_json_parser_31;
+                    goto basic_json_parser_33;
+                }
+            }
+        } else {
+            if (yych <= 'q') {
+                if (yych <= 'f') goto basic_json_parser_31;
+                if (yych == 'n') goto basic_json_parser_31;
+                goto basic_json_parser_33;
+            } else {
+                if (yych <= 's') {
+                    if (yych <= 'r') goto basic_json_parser_31;
+                    goto basic_json_parser_33;
+                } else {
+                    if (yych <= 't') goto basic_json_parser_31;
+                    if (yych <= 'u') goto basic_json_parser_37;
+                    goto basic_json_parser_33;
+                }
+            }
+        }
+basic_json_parser_35:
+        ++m_cursor;
+        { return token_type::value_string; }
+basic_json_parser_37:
+        ++m_cursor;
+        if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE;
+        yych = *m_cursor;
+        if (yych <= '@') {
+            if (yych <= '/') goto basic_json_parser_33;
+            if (yych >= ':') goto basic_json_parser_33;
+        } else {
+            if (yych <= 'F') goto basic_json_parser_38;
+            if (yych <= '`') goto basic_json_parser_33;
+            if (yych >= 'g') goto basic_json_parser_33;
+        }
+basic_json_parser_38:
+        ++m_cursor;
+        if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE;
+        yych = *m_cursor;
+        if (yych <= '@') {
+            if (yych <= '/') goto basic_json_parser_33;
+            if (yych >= ':') goto basic_json_parser_33;
+        } else {
+            if (yych <= 'F') goto basic_json_parser_39;
+            if (yych <= '`') goto basic_json_parser_33;
+            if (yych >= 'g') goto basic_json_parser_33;
+        }
+basic_json_parser_39:
+        ++m_cursor;
+        if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE;
+        yych = *m_cursor;
+        if (yych <= '@') {
+            if (yych <= '/') goto basic_json_parser_33;
+            if (yych >= ':') goto basic_json_parser_33;
+        } else {
+            if (yych <= 'F') goto basic_json_parser_40;
+            if (yych <= '`') goto basic_json_parser_33;
+            if (yych >= 'g') goto basic_json_parser_33;
+        }
+basic_json_parser_40:
+        ++m_cursor;
+        if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE;
+        yych = *m_cursor;
+        if (yych <= '@') {
+            if (yych <= '/') goto basic_json_parser_33;
+            if (yych <= '9') goto basic_json_parser_31;
+            goto basic_json_parser_33;
+        } else {
+            if (yych <= 'F') goto basic_json_parser_31;
+            if (yych <= '`') goto basic_json_parser_33;
+            if (yych <= 'f') goto basic_json_parser_31;
+            goto basic_json_parser_33;
+        }
+basic_json_parser_41:
+        yyaccept = 1;
+        m_marker = ++m_cursor;
+        if ((m_limit - m_cursor) < 3) yyfill(); // LCOV_EXCL_LINE;
+        yych = *m_cursor;
+basic_json_parser_42:
+        if (yybm[0+yych] & 128) {
+            goto basic_json_parser_41;
+        }
+        if (yych <= 'D') {
+            if (yych != '.') goto basic_json_parser_25;
+        } else {
+            if (yych <= 'E') goto basic_json_parser_44;
+            if (yych == 'e') goto basic_json_parser_44;
+            goto basic_json_parser_25;
+        }
+basic_json_parser_43:
+        yych = *++m_cursor;
+        if (yych <= '/') goto basic_json_parser_33;
+        if (yych <= '9') goto basic_json_parser_48;
+        goto basic_json_parser_33;
+basic_json_parser_44:
+        yych = *++m_cursor;
+        if (yych <= ',') {
+            if (yych != '+') goto basic_json_parser_33;
+        } else {
+            if (yych <= '-') goto basic_json_parser_45;
+            if (yych <= '/') goto basic_json_parser_33;
+            if (yych <= '9') goto basic_json_parser_46;
+            goto basic_json_parser_33;
+        }
+basic_json_parser_45:
+        yych = *++m_cursor;
+        if (yych <= '/') goto basic_json_parser_33;
+        if (yych >= ':') goto basic_json_parser_33;
+basic_json_parser_46:
+        ++m_cursor;
+        if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE;
+        yych = *m_cursor;
+        if (yych <= '/') goto basic_json_parser_25;
+        if (yych <= '9') goto basic_json_parser_46;
+        goto basic_json_parser_25;
+basic_json_parser_48:
+        yyaccept = 1;
+        m_marker = ++m_cursor;
+        if ((m_limit - m_cursor) < 3) yyfill(); // LCOV_EXCL_LINE;
+        yych = *m_cursor;
+        if (yych <= 'D') {
+            if (yych <= '/') goto basic_json_parser_25;
+            if (yych <= '9') goto basic_json_parser_48;
+            goto basic_json_parser_25;
+        } else {
+            if (yych <= 'E') goto basic_json_parser_44;
+            if (yych == 'e') goto basic_json_parser_44;
+            goto basic_json_parser_25;
+        }
+basic_json_parser_50:
+        yyaccept = 1;
+        yych = *(m_marker = ++m_cursor);
+        if (yych <= 'D') {
+            if (yych == '.') goto basic_json_parser_43;
+            goto basic_json_parser_25;
+        } else {
+            if (yych <= 'E') goto basic_json_parser_44;
+            if (yych == 'e') goto basic_json_parser_44;
+            goto basic_json_parser_25;
+        }
+basic_json_parser_51:
+        yych = *++m_cursor;
+        if (yych != 'l') goto basic_json_parser_33;
+        yych = *++m_cursor;
+        if (yych != 's') goto basic_json_parser_33;
+        yych = *++m_cursor;
+        if (yych != 'e') goto basic_json_parser_33;
+        ++m_cursor;
+        { return token_type::literal_false; }
+basic_json_parser_56:
+        yych = *++m_cursor;
+        if (yych != 'u') goto basic_json_parser_33;
+        yych = *++m_cursor;
+        if (yych != 'e') goto basic_json_parser_33;
+        ++m_cursor;
+        { return token_type::literal_true; }
+basic_json_parser_60:
+        yych = *++m_cursor;
+        if (yych != 'l') goto basic_json_parser_33;
+        yych = *++m_cursor;
+        if (yych != 'l') goto basic_json_parser_33;
+        ++m_cursor;
+        { return token_type::literal_null; }
+basic_json_parser_64:
+        yych = *++m_cursor;
+        if (yych != 0xBF) goto basic_json_parser_33;
+        ++m_cursor;
+        { return scan(); }
+    }
 
 
         }
@@ -7757,6 +7360,63 @@ basic_json_parser_64:
             return result;
         }
 
+        /*!
+        @brief parse floating point number
+
+        This function (and its overloads) serves to select the most approprate
+        standard floating point number parsing function based on the type
+        supplied via the first parameter.  Set this to 
+        @a static_cast<number_float_t>(nullptr).
+
+        @param type  the @ref number_float_t in use
+
+        @param endptr  recieves a pointer to the first character after the number
+
+        @return the floating point number
+        */
+        long double str_to_float_t(long double* /* type */, char** endptr) const
+        {
+            return std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
+        }
+
+        /*!
+        @brief parse floating point number
+
+        This function (and its overloads) serves to select the most approprate
+        standard floating point number parsing function based on the type
+        supplied via the first parameter.  Set this to
+        @a static_cast<number_float_t>(nullptr).
+
+        @param type  the @ref number_float_t in use
+
+        @param endptr  recieves a pointer to the first character after the number
+
+        @return the floating point number
+        */
+        double str_to_float_t(double* /* type */, char** endptr) const
+        {
+            return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
+        }
+
+        /*!
+        @brief parse floating point number
+
+        This function (and its overloads) serves to select the most approprate
+        standard floating point number parsing function based on the type
+        supplied via the first parameter.  Set this to 
+        @a static_cast<number_float_t>(nullptr).
+
+        @param type  the @ref number_float_t in use
+
+        @param endptr  recieves a pointer to the first character after the number
+
+        @return the floating point number
+        */
+        float str_to_float_t(float* /* type */, char** endptr) const
+        {
+            return std::strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
+        }
+
         /*!
         @brief return number value for number tokens
 
@@ -7774,13 +7434,12 @@ basic_json_parser_64:
 
         @throw std::range_error if passed value is out of range
         */
-        long double get_number() const
+        number_float_t get_number() const
         {
             // conversion
             typename string_t::value_type* endptr;
             assert(m_start != nullptr);
-            const auto float_val = std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start),
-                                                &endptr);
+            number_float_t float_val = str_to_float_t(static_cast<number_float_t*>(nullptr), &endptr);
 
             // return float_val if the whole number was translated and NAN
             // otherwise
@@ -8014,11 +7673,11 @@ basic_json_parser_64:
 
                 case lexer::token_type::value_number:
                 {
-                    auto float_val = m_lexer.get_number();
+                    result.m_value = m_lexer.get_number();
 
                     // NAN is returned if token could not be translated
                     // completely
-                    if (std::isnan(float_val))
+                    if (std::isnan(result.m_value.number_float))
                     {
                         throw std::invalid_argument(std::string("parse error - ") +
                                                     m_lexer.get_token() + " is not a number");
@@ -8026,9 +7685,10 @@ basic_json_parser_64:
 
                     get_token();
 
-                    // check if conversion loses precision
-                    const auto int_val = static_cast<number_integer_t>(float_val);
-                    if (float_val == static_cast<long double>(int_val))
+                    // check if conversion loses precision (special case -0.0 always loses precision)
+                    const auto int_val = static_cast<number_integer_t>(result.m_value.number_float);
+                    if (result.m_value.number_float == static_cast<number_float_t>(int_val) &&
+                        result.m_value.number_integer != json_value(-0.0f).number_integer)
                     {
                         // we would not lose precision -> return int
                         result.m_type = value_t::number_integer;
@@ -8038,7 +7698,6 @@ basic_json_parser_64:
                     {
                         // we would lose precision -> return float
                         result.m_type = value_t::number_float;
-                        result.m_value = static_cast<number_float_t>(float_val);
                     }
                     break;
                 }
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 1b65a095..0f84baa0 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -5604,10 +5604,16 @@ class basic_json
 
             case value_t::number_float:
             {
-                // 15 digits of precision allows round-trip IEEE 754
-                // string->double->string; to be safe, we read this value from
-                // std::numeric_limits<number_float_t>::digits10
-                o << std::setprecision(std::numeric_limits<number_float_t>::digits10) << m_value.number_float;
+                // If the number is an integer then output as a fixed with with precision 1
+                // to output "0.0", "1.0" etc as expected for some round trip tests otherwise
+                // 15 digits of precision allows round-trip IEEE 754 string->double->string; 
+                // to be safe, we read this value from std::numeric_limits<number_float_t>::digits10
+                if (std::fmod(m_value.number_float, 1) == 0) o << std::fixed << std::setprecision(1);
+                else {
+                    o.unsetf(std::ios_base::floatfield);  // std::defaultfloat not supported in gcc version < 5
+                    o << std::setprecision(std::numeric_limits<double>::digits10);
+                }
+                o << m_value.number_float;
                 return;
             }
 
@@ -7036,6 +7042,63 @@ class basic_json
             return result;
         }
 
+        /*!
+        @brief parse floating point number
+
+        This function (and its overloads) serves to select the most approprate
+        standard floating point number parsing function based on the type
+        supplied via the first parameter.  Set this to 
+        @a static_cast<number_float_t>(nullptr).
+
+        @param type  the @ref number_float_t in use
+
+        @param endptr  recieves a pointer to the first character after the number
+
+        @return the floating point number
+        */
+        long double str_to_float_t(long double* /* type */, char** endptr) const
+        {
+            return std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
+        }
+
+        /*!
+        @brief parse floating point number
+
+        This function (and its overloads) serves to select the most approprate
+        standard floating point number parsing function based on the type
+        supplied via the first parameter.  Set this to
+        @a static_cast<number_float_t>(nullptr).
+
+        @param type  the @ref number_float_t in use
+
+        @param endptr  recieves a pointer to the first character after the number
+
+        @return the floating point number
+        */
+        double str_to_float_t(double* /* type */, char** endptr) const
+        {
+            return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
+        }
+
+        /*!
+        @brief parse floating point number
+
+        This function (and its overloads) serves to select the most approprate
+        standard floating point number parsing function based on the type
+        supplied via the first parameter.  Set this to 
+        @a static_cast<number_float_t>(nullptr).
+
+        @param type  the @ref number_float_t in use
+
+        @param endptr  recieves a pointer to the first character after the number
+
+        @return the floating point number
+        */
+        float str_to_float_t(float* /* type */, char** endptr) const
+        {
+            return std::strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
+        }
+
         /*!
         @brief return number value for number tokens
 
@@ -7053,13 +7116,12 @@ class basic_json
 
         @throw std::range_error if passed value is out of range
         */
-        long double get_number() const
+        number_float_t get_number() const
         {
             // conversion
             typename string_t::value_type* endptr;
             assert(m_start != nullptr);
-            const auto float_val = std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start),
-                                                &endptr);
+            number_float_t float_val = str_to_float_t(static_cast<number_float_t*>(nullptr), &endptr);
 
             // return float_val if the whole number was translated and NAN
             // otherwise
@@ -7293,11 +7355,11 @@ class basic_json
 
                 case lexer::token_type::value_number:
                 {
-                    auto float_val = m_lexer.get_number();
+                    result.m_value = m_lexer.get_number();
 
                     // NAN is returned if token could not be translated
                     // completely
-                    if (std::isnan(float_val))
+                    if (std::isnan(result.m_value.number_float))
                     {
                         throw std::invalid_argument(std::string("parse error - ") +
                                                     m_lexer.get_token() + " is not a number");
@@ -7305,9 +7367,10 @@ class basic_json
 
                     get_token();
 
-                    // check if conversion loses precision
-                    const auto int_val = static_cast<number_integer_t>(float_val);
-                    if (float_val == static_cast<long double>(int_val))
+                    // check if conversion loses precision (special case -0.0 always loses precision)
+                    const auto int_val = static_cast<number_integer_t>(result.m_value.number_float);
+                    if (result.m_value.number_float == static_cast<number_float_t>(int_val) &&
+                        result.m_value.number_integer != json_value(-0.0f).number_integer)
                     {
                         // we would not lose precision -> return int
                         result.m_type = value_t::number_integer;
@@ -7317,7 +7380,6 @@ class basic_json
                     {
                         // we would lose precision -> return float
                         result.m_type = value_t::number_float;
-                        result.m_value = static_cast<number_float_t>(float_val);
                     }
                     break;
                 }
diff --git a/test/unit.cpp b/test/unit.cpp
index 94b5084c..f098170d 100644
--- a/test/unit.cpp
+++ b/test/unit.cpp
@@ -11090,7 +11090,7 @@ TEST_CASE("compliance tests from nativejson-benchmark")
                     //"test/json_roundtrip/roundtrip18.json",
                     //"test/json_roundtrip/roundtrip19.json",
                     //"test/json_roundtrip/roundtrip20.json",
-                    //"test/json_roundtrip/roundtrip21.json",
+                    "test/json_roundtrip/roundtrip21.json",
                     "test/json_roundtrip/roundtrip22.json",
                     "test/json_roundtrip/roundtrip23.json",
                     //"test/json_roundtrip/roundtrip24.json",
@@ -11407,7 +11407,8 @@ TEST_CASE("regression tests")
     SECTION("issue #89 - nonstandard integer type")
     {
         // create JSON class with nonstandard integer number type
-        nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, float> j;
+        using custom_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, float>;
+        custom_json j;
         j["int_1"] = 1;
         // we need to cast to int to compile with Catch - the value is int32_t
         CHECK(static_cast<int>(j["int_1"]) == 1);
@@ -11557,4 +11558,51 @@ TEST_CASE("regression tests")
         // Const access with key as "static constexpr const char *"
         CHECK(j_const[constexpr_ptr_key] == json(5));
     }
+
+    SECTION("issue #186 miloyip/nativejson-benchmark: floating-point parsing")
+    {
+        json j;
+
+        j = json::parse("-0.0");
+        CHECK(j.get<double>() == -0.0);
+
+        j = json::parse("2.22507385850720113605740979670913197593481954635164564e-308");
+        CHECK(j.get<double>() == 2.2250738585072009e-308);
+
+        j = json::parse("0.999999999999999944488848768742172978818416595458984374");
+        CHECK(j.get<double>() == 0.99999999999999989);
+
+        // Test fails under GCC/clang due to strtod() error (may originate in libstdc++
+        // but seems to have been fixed in the most current versions - just not on Travis)
+#if !defined(__clang__) && !defined(__GNUC__) && !defined(__GNUG__)
+        j = json::parse("1.00000000000000011102230246251565404236316680908203126");
+        CHECK(j.get<double>() == 1.00000000000000022);
+#endif
+
+        j = json::parse("7205759403792793199999e-5");
+        CHECK(j.get<double>() == 72057594037927928.0);
+
+        j = json::parse("922337203685477529599999e-5");
+        CHECK(j.get<double>() == 9223372036854774784.0);
+
+        j = json::parse("1014120480182583464902367222169599999e-5");
+        CHECK(j.get<double>() == 10141204801825834086073718800384.0);
+
+        j = json::parse("5708990770823839207320493820740630171355185151999e-3");
+        CHECK(j.get<double>() == 5708990770823838890407843763683279797179383808.0);
+
+        // create JSON class with nonstandard float number type
+
+        // float
+        nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, float> j_float = 1.23e25f;
+        CHECK(j_float.get<float>() == 1.23e25f);
+
+        // double
+        nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, double> j_double = 1.23e45;
+        CHECK(j_double.get<double>() == 1.23e45);
+
+        // long double
+        nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, long double> j_long_double = 1.23e45L;
+        CHECK(j_long_double.get<long double>() == 1.23e45L);
+    }
 }