You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2014/01/17 23:12:06 UTC

[35/50] [abbrv] git commit: Encode floating point numbers as short as possible

Encode floating point numbers as short as possible

Floating point numbers are no longer encoded as a one to one mapping
of their binary representation, but as short as possible (while still
being acurate). The double-conversion library [1] is used to do the
hard work.

The ECMAScript compatible conversion is used.

[1] https://code.google.com/p/double-conversion/


Project: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/commit/d0f1ea00
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/tree/d0f1ea00
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/diff/d0f1ea00

Branch: refs/heads/import
Commit: d0f1ea00fc037d3936e80b30ba933f4d5ab415d0
Parents: ee788ca
Author: Volker Mische <vo...@gmail.com>
Authored: Sun Feb 24 16:34:48 2013 +0100
Committer: Volker Mische <vo...@gmail.com>
Committed: Sun Feb 24 17:47:29 2013 +0100

----------------------------------------------------------------------
 Makefile            |  2 +-
 README.md           |  2 +-
 c_src/c_api.cc      | 31 +++++++++++++++++++++++++++++++
 c_src/encoder.c     |  3 +--
 c_src/jiffy.h       |  2 ++
 rebar.config        | 13 +++++++++++--
 rebar.config.script | 13 ++++++++++---
 test/003-numbers.t  | 12 ++++++------
 8 files changed, 63 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/d0f1ea00/Makefile
----------------------------------------------------------------------
diff --git a/Makefile b/Makefile
index 1aa9a1b..7227ce4 100644
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,7 @@ devmarker:
 
 
 depends: devmarker
-	@if test ! -d ./deps; then \
+	@if test ! -d ./deps/proper; then \
 		$(REBAR) get-deps; \
 	fi
 

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/d0f1ea00/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 36fc870..efb5300 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ Errors are raised as exceptions.
     2> Doc = {[{foo, [<<"bing">>, 2.3, true]}]}.
     {[{foo,[<<"bing">>,2.3,true]}]}
     3> jiffy:encode(Doc).
-    <<"{\"foo\":[\"bing\",2.2999999999999998224,true]}">>
+    <<"{\"foo\":[\"bing\",2.3,true]}">>
 
 
 Data Format

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/d0f1ea00/c_src/c_api.cc
----------------------------------------------------------------------
diff --git a/c_src/c_api.cc b/c_src/c_api.cc
new file mode 100644
index 0000000..88d7323
--- /dev/null
+++ b/c_src/c_api.cc
@@ -0,0 +1,31 @@
+#include <string.h>
+
+#include "double-conversion.h"
+
+
+using namespace double_conversion;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Returns the length of the string
+int
+double_to_shortest(char *buf, size_t size, double val)
+{
+    int len = -1;
+
+    StringBuilder builder(buf, size);
+    const DoubleToStringConverter& dc =
+        DoubleToStringConverter::EcmaScriptConverter();
+
+    dc.ToShortest(val, &builder);
+    len = builder.position();
+    buf = builder.Finalize();
+    return len;
+}
+
+#ifdef __cplusplus
+}
+#endif

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/d0f1ea00/c_src/encoder.c
----------------------------------------------------------------------
diff --git a/c_src/encoder.c b/c_src/encoder.c
index 640aa68..ad35007 100644
--- a/c_src/encoder.c
+++ b/c_src/encoder.c
@@ -399,8 +399,7 @@ enc_double(Encoder* e, double val)
 
     start = &(e->p[e->i]);
 
-    sprintf(start, "%0.20g", val);
-    len = strlen(start);
+    len = double_to_shortest(start, e->curr->size, val);
 
     // Check if we have a decimal point
     for(i = 0; i < len; i++) {

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/d0f1ea00/c_src/jiffy.h
----------------------------------------------------------------------
diff --git a/c_src/jiffy.h b/c_src/jiffy.h
index c477a43..1fdce39 100644
--- a/c_src/jiffy.h
+++ b/c_src/jiffy.h
@@ -41,4 +41,6 @@ int unicode_to_utf8(int c, unsigned char* buf);
 int unicode_from_pair(int hi, int lo);
 int unicode_uescape(int c, char* buf);
 
+int double_to_shortest(char *buf, size_t size, double val);
+
 #endif // Included JIFFY_H

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/d0f1ea00/rebar.config
----------------------------------------------------------------------
diff --git a/rebar.config b/rebar.config
index 18e62a0..1d7100a 100644
--- a/rebar.config
+++ b/rebar.config
@@ -1,7 +1,12 @@
-{port_specs, [{"priv/jiffy.so", ["c_src/*.c"]}]}.
+{port_specs, [
+    {"priv/jiffy.so", ["c_src/*.c*", "deps/double-conversion/src/*.cc"]}
+]}.
 
 {port_env, [
-    {".*", "CFLAGS", "$CFLAGS -g -Wall"},
+    {".*", "CXXFLAGS", "$CXXFLAGS -g -Wall -Ideps/double-conversion/src"},
+
+    {"(linux|solaris|freebsd|netbsd|openbsd|dragonfly|darwin)",
+        "LDFLAGS", "$LDFLAGS -lstdc++"},
 
     %% OS X Leopard flags for 64-bit
     {"darwin9.*-64$", "CXXFLAGS", "-m64"},
@@ -23,3 +28,7 @@
     }}
 ]}.
 
+{deps, [
+    {'double-conversion', ".*",
+        {git, "https://code.google.com/p/double-conversion/", "master"}, [raw]}
+]}.

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/d0f1ea00/rebar.config.script
----------------------------------------------------------------------
diff --git a/rebar.config.script b/rebar.config.script
index 4b71f42..58d4ff7 100644
--- a/rebar.config.script
+++ b/rebar.config.script
@@ -11,16 +11,23 @@ ErlOpts = {erl_opts, [
     {d, 'JIFFY_DEV'}
 ]},
 
-Deps = {deps, [
+Proper = [
     {proper, ".*", {git, "git://github.com/manopapad/proper.git", "master"}}
-]},
+],
 
 ConfigPath = filename:dirname(SCRIPT),
 DevMarker = filename:join([ConfigPath, ".jiffy.dev"]),
 
 case filelib:is_file(DevMarker) of
     true ->
-        CONFIG ++ [ErlOpts, Deps];
+        % Don't override existing dependencies
+        NewConfig = case lists:keyfind(deps, 1, CONFIG) of
+            false ->
+                CONFIG ++ [{deps, Proper}];
+            {deps, DepsList} ->
+                lists:keyreplace(deps, 1, CONFIG, {deps, DepsList ++ Proper})
+        end,
+        NewConfig ++ [ErlOpts];
     false ->
         CONFIG
 end.

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/d0f1ea00/test/003-numbers.t
----------------------------------------------------------------------
diff --git a/test/003-numbers.t b/test/003-numbers.t
index f580faf..9196706 100755
--- a/test/003-numbers.t
+++ b/test/003-numbers.t
@@ -23,12 +23,12 @@ good() ->
         {
             <<"1234567890123456789012345.0">>,
             1.23456789012345678e24,
-            <<"1.2345678901234568245e+24">>
+            <<"1.2345678901234568e+24">>
         },
         {
             <<"1234567890123456789012345.0E3">>,
             1.2345678901234569e27,
-            <<"1.2345678901234568502e+27">>
+            <<"1.2345678901234569e+27">>
         },
         {
             <<"1234567890123456789012345012">>,
@@ -39,12 +39,12 @@ good() ->
         {
             <<"0.000000000000000000000000000000000001">>,
             1.0E-36,
-            <<"9.9999999999999994104e-37">>
+            <<"1e-36">>
         },
         {<<"0.75">>, 0.75},
-        {<<"2.0123456789">>, 2.0123456789, <<"2.0123456789000000455">>},
-        {<<"2.4234324E24">>, 2.4234324E24, <<"2.4234323999999998107e+24">>},
-        {<<"-3.1416">>, -3.1416, <<"-3.1415999999999999481">>},
+        {<<"2.0123456789">>, 2.0123456789, <<"2.0123456789">>},
+        {<<"2.4234324E24">>, 2.4234324E24, <<"2.4234324e+24">>},
+        {<<"-3.1416">>, -3.1416, <<"-3.1416">>},
         {<<"1E4">>, 10000.0, <<"10000.0">>},
         {<<"1.0E+01">>, 10.0, <<"10.0">>},
         {<<"1e1">>, 10.0, <<"10.0">>},