@@ -213,7 +213,7 @@ enum {
213
213
#define JVP_FLAGS_NUMBER_LITERAL JVP_MAKE_FLAGS(JV_KIND_NUMBER, JVP_MAKE_PFLAGS(JVP_NUMBER_DECIMAL, 1))
214
214
215
215
// the decimal precision of binary double
216
- #define DEC_NUBMER_DOUBLE_PRECISION (16 )
216
+ #define DEC_NUBMER_DOUBLE_PRECISION (17 )
217
217
#define DEC_NUMBER_STRING_GUARD (14)
218
218
#define DEC_NUBMER_DOUBLE_EXTRA_UNITS ((DEC_NUBMER_DOUBLE_PRECISION - DECNUMDIGITS + DECDPUN - 1)/DECDPUN)
219
219
@@ -489,30 +489,22 @@ pthread_getspecific(pthread_key_t key)
489
489
#endif
490
490
491
491
static pthread_key_t dec_ctx_key ;
492
- static pthread_key_t dec_ctx_dbl_key ;
493
492
static pthread_once_t dec_ctx_once = PTHREAD_ONCE_INIT ;
494
493
495
494
#define DEC_CONTEXT () tsd_dec_ctx_get(&dec_ctx_key)
496
- #define DEC_CONTEXT_TO_DOUBLE () tsd_dec_ctx_get(&dec_ctx_dbl_key)
497
495
498
496
// atexit finalizer to clean up the tsd dec contexts if main() exits
499
497
// without having called pthread_exit()
500
498
void jv_tsd_dec_ctx_fini () {
501
499
jv_mem_free (pthread_getspecific (dec_ctx_key ));
502
- jv_mem_free (pthread_getspecific (dec_ctx_dbl_key ));
503
500
pthread_setspecific (dec_ctx_key , NULL );
504
- pthread_setspecific (dec_ctx_dbl_key , NULL );
505
501
}
506
502
507
503
void jv_tsd_dec_ctx_init () {
508
504
if (pthread_key_create (& dec_ctx_key , jv_mem_free ) != 0 ) {
509
505
fprintf (stderr , "error: cannot create thread specific key" );
510
506
abort ();
511
507
}
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
- }
516
508
atexit (jv_tsd_dec_ctx_fini );
517
509
}
518
510
@@ -533,12 +525,6 @@ static decContext* tsd_dec_ctx_get(pthread_key_t *key) {
533
525
INT32_MAX - (DECDPUN - 1 ) - (ctx -> emax - ctx -> emin - 1 ));
534
526
ctx -> traps = 0 ; /*no errors*/
535
527
}
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
- }
542
528
if (pthread_setspecific (* key , ctx ) != 0 ) {
543
529
fprintf (stderr , "error: cannot store thread specific data" );
544
530
abort ();
@@ -610,14 +596,19 @@ static jv jvp_literal_number_new(const char * literal) {
610
596
611
597
static double jvp_literal_number_to_double (jv j ) {
612
598
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 ;
613
604
614
605
decNumber * p_dec_number = jvp_dec_number_ptr (j );
615
606
decNumberDoublePrecision dec_double ;
616
607
char literal [DEC_NUBMER_DOUBLE_PRECISION + DEC_NUMBER_STRING_GUARD + 1 ];
617
608
618
609
// reduce the number to the shortest possible form
619
610
// 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 );
621
612
622
613
decNumberToString (& dec_double .number , literal );
623
614
0 commit comments