Browse Source

Merge aed0a5d626 into ee788ca28f

pull/32/merge
Ryan Flynn 12 years ago
parent
commit
ed023f5ba1
4 changed files with 21 additions and 16 deletions
  1. +1
    -1
      README.md
  2. +11
    -3
      c_src/encoder.c
  3. +7
    -12
      test/003-numbers.t
  4. +2
    -0
      test/util.erl

+ 1
- 1
README.md View File

@ -25,7 +25,7 @@ Errors are raised as exceptions.
2> Doc = {[{foo, [<<"bing">>, 2.3, true]}]}. 2> Doc = {[{foo, [<<"bing">>, 2.3, true]}]}.
{[{foo,[<<"bing">>,2.3,true]}]} {[{foo,[<<"bing">>,2.3,true]}]}
3> jiffy:encode(Doc). 3> jiffy:encode(Doc).
<<"{\"foo\":[\"bing\",2.2999999999999998224,true]}">>
<<"{\"foo\":[\"bing\",2.3,true]}">>
Data Format Data Format

+ 11
- 3
c_src/encoder.c View File

@ -4,12 +4,15 @@
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <float.h>
#include "erl_nif.h" #include "erl_nif.h"
#include "jiffy.h" #include "jiffy.h"
#define BIN_INC_SIZE 2048 #define BIN_INC_SIZE 2048
#define FLOAT_BUFLEN (LDBL_DIG*2)
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
#define MAYBE_PRETTY(e) \ #define MAYBE_PRETTY(e) \
@ -393,13 +396,18 @@ enc_double(Encoder* e, double val)
size_t len; size_t len;
size_t i; size_t i;
if(!enc_ensure(e, 32)) {
if(!enc_ensure(e, FLOAT_BUFLEN)) {
return 0; return 0;
} }
start = &(e->p[e->i]); start = &(e->p[e->i]);
sprintf(start, "%0.20g", val);
// try to encode doubles using the fewest digits possible...
if (snprintf(start, FLOAT_BUFLEN, "%.*g", DBL_DIG, val) > FLT_DIG)
{
// ...fall back to full expansion to be safe
snprintf(start, FLOAT_BUFLEN, "%.*g", LDBL_DIG, val);
}
len = strlen(start); len = strlen(start);
// Check if we have a decimal point // Check if we have a decimal point
@ -408,7 +416,7 @@ enc_double(Encoder* e, double val)
goto done; goto done;
} }
if(len > 29) return 0;
if(len >= FLOAT_BUFLEN-2) return 0;
// Force a decimal point // Force a decimal point
start[len++] = '.'; start[len++] = '.';

+ 7
- 12
test/003-numbers.t View File

@ -21,30 +21,25 @@ good() ->
{<<"1234567890123456789012345">>, 1234567890123456789012345}, {<<"1234567890123456789012345">>, 1234567890123456789012345},
{<<"1310050760199">>, 1310050760199}, {<<"1310050760199">>, 1310050760199},
{ {
<<"1234567890123456789012345.0">>,
1.23456789012345678e24,
<<"1.2345678901234568245e+24">>
1.23456789012345678e24
}, },
{ {
<<"1234567890123456789012345.0E3">>,
1.2345678901234569e27,
<<"1.2345678901234568502e+27">>
1.2345678901234569e27
}, },
{ {
<<"1234567890123456789012345012">>, <<"1234567890123456789012345012">>,
1234567890123456789012345012,
<<"1234567890123456789012345012">>
1234567890123456789012345012
}, },
{<<"1.0">>, 1.0}, {<<"1.0">>, 1.0},
{ {
<<"0.000000000000000000000000000000000001">>, <<"0.000000000000000000000000000000000001">>,
1.0E-36, 1.0E-36,
<<"9.9999999999999994104e-37">>
<<"1e-36">>
}, },
{<<"0.75">>, 0.75}, {<<"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.4234324E24},
{-3.1416},
{<<"1E4">>, 10000.0, <<"10000.0">>}, {<<"1E4">>, 10000.0, <<"10000.0">>},
{<<"1.0E+01">>, 10.0, <<"10.0">>}, {<<"1.0E+01">>, 10.0, <<"10.0">>},
{<<"1e1">>, 10.0, <<"10.0">>}, {<<"1e1">>, 10.0, <<"10.0">>},

+ 2
- 0
test/util.erl View File

@ -22,6 +22,8 @@ do_encode(E, Options) ->
error_mesg(J) -> error_mesg(J) ->
lists:flatten(io_lib:format("Decoding ~p returns an error.", [J])). lists:flatten(io_lib:format("Decoding ~p returns an error.", [J])).
check_good({E}, Options) ->
check_good({jiffy:encode(E), E}, Options);
check_good({J, E}, Options) -> check_good({J, E}, Options) ->
etap:is(jiffy:decode(J), E, ok_dec(J, E)), etap:is(jiffy:decode(J), E, ok_dec(J, E)),
etap:is(do_encode(E, Options), J, ok_enc(E, J)); etap:is(do_encode(E, Options), J, ok_enc(E, J));

Loading…
Cancel
Save