Skip to content

Commit f3610e7

Browse files
committed
Convert decnum to binary64 (double) instead of decimal64
This is what the JSON spec suggests and will also be less confusing compared to other jq implementations and langauges. Related to #2939
1 parent 88f01a7 commit f3610e7

File tree

2 files changed

+16
-16
lines changed

2 files changed

+16
-16
lines changed

src/jv.c

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ enum {
213213
#define JVP_FLAGS_NUMBER_LITERAL JVP_MAKE_FLAGS(JV_KIND_NUMBER, JVP_MAKE_PFLAGS(JVP_NUMBER_DECIMAL, 1))
214214

215215
// the decimal precision of binary double
216-
#define DEC_NUBMER_DOUBLE_PRECISION (16)
216+
#define DEC_NUBMER_DOUBLE_PRECISION (17)
217217
#define DEC_NUMBER_STRING_GUARD (14)
218218
#define DEC_NUBMER_DOUBLE_EXTRA_UNITS ((DEC_NUBMER_DOUBLE_PRECISION - DECNUMDIGITS + DECDPUN - 1)/DECDPUN)
219219

@@ -489,30 +489,22 @@ pthread_getspecific(pthread_key_t key)
489489
#endif
490490

491491
static pthread_key_t dec_ctx_key;
492-
static pthread_key_t dec_ctx_dbl_key;
493492
static pthread_once_t dec_ctx_once = PTHREAD_ONCE_INIT;
494493

495494
#define DEC_CONTEXT() tsd_dec_ctx_get(&dec_ctx_key)
496-
#define DEC_CONTEXT_TO_DOUBLE() tsd_dec_ctx_get(&dec_ctx_dbl_key)
497495

498496
// atexit finalizer to clean up the tsd dec contexts if main() exits
499497
// without having called pthread_exit()
500498
void jv_tsd_dec_ctx_fini() {
501499
jv_mem_free(pthread_getspecific(dec_ctx_key));
502-
jv_mem_free(pthread_getspecific(dec_ctx_dbl_key));
503500
pthread_setspecific(dec_ctx_key, NULL);
504-
pthread_setspecific(dec_ctx_dbl_key, NULL);
505501
}
506502

507503
void jv_tsd_dec_ctx_init() {
508504
if (pthread_key_create(&dec_ctx_key, jv_mem_free) != 0) {
509505
fprintf(stderr, "error: cannot create thread specific key");
510506
abort();
511507
}
512-
if (pthread_key_create(&dec_ctx_dbl_key, jv_mem_free) != 0) {
513-
fprintf(stderr, "error: cannot create thread specific key");
514-
abort();
515-
}
516508
atexit(jv_tsd_dec_ctx_fini);
517509
}
518510

@@ -533,12 +525,6 @@ static decContext* tsd_dec_ctx_get(pthread_key_t *key) {
533525
INT32_MAX - (DECDPUN - 1) - (ctx->emax - ctx->emin - 1));
534526
ctx->traps = 0; /*no errors*/
535527
}
536-
else if (key == &dec_ctx_dbl_key)
537-
{
538-
decContextDefault(ctx, DEC_INIT_DECIMAL64);
539-
// just to make sure we got this right
540-
assert(ctx->digits <= DEC_NUBMER_DOUBLE_PRECISION);
541-
}
542528
if (pthread_setspecific(*key, ctx) != 0) {
543529
fprintf(stderr, "error: cannot store thread specific data");
544530
abort();
@@ -610,14 +596,19 @@ static jv jvp_literal_number_new(const char * literal) {
610596

611597
static double jvp_literal_number_to_double(jv j) {
612598
assert(JVP_HAS_FLAGS(j, JVP_FLAGS_NUMBER_LITERAL));
599+
decContext dblCtx;
600+
601+
// init as decimal64 but change digits to allow conversion to binary64 (double)
602+
decContextDefault(&dblCtx, DEC_INIT_DECIMAL64);
603+
dblCtx.digits = DEC_NUBMER_DOUBLE_PRECISION;
613604

614605
decNumber *p_dec_number = jvp_dec_number_ptr(j);
615606
decNumberDoublePrecision dec_double;
616607
char literal[DEC_NUBMER_DOUBLE_PRECISION + DEC_NUMBER_STRING_GUARD + 1];
617608

618609
// reduce the number to the shortest possible form
619610
// that fits into the 64 bit floating point representation
620-
decNumberReduce(&dec_double.number, p_dec_number, DEC_CONTEXT_TO_DOUBLE());
611+
decNumberReduce(&dec_double.number, p_dec_number, &dblCtx);
621612

622613
decNumberToString(&dec_double.number, literal);
623614

tests/jq.test

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,6 +1867,15 @@ false
18671867
1
18681868
1
18691869

1870+
# decnum to double conversion
1871+
.[] as $n | $n+0 | [., tostring, . == $n]
1872+
[-9007199254740993, -9007199254740992, 9007199254740992, 9007199254740993, 13911860366432393]
1873+
[-9007199254740992,"-9007199254740992",true]
1874+
[-9007199254740992,"-9007199254740992",true]
1875+
[9007199254740992,"9007199254740992",true]
1876+
[9007199254740992,"9007199254740992",true]
1877+
[13911860366432392,"13911860366432392",true]
1878+
18701879
# abs, fabs, length
18711880
abs
18721881
"abc"

0 commit comments

Comments
 (0)