Diff
Not logged in

Differences From Artifact [df6dd2545e]:

To Artifact [a905748ab8]:


2720
2721
2722
2723
2724
2725
2726
2727

2728
2729
2730
2731
2732
2733
2734
2720
2721
2722
2723
2724
2725
2726

2727
2728
2729
2730
2731
2732
2733
2734







-
+








static inline char *
QuickConversion(
    double e,			/* Number to format. */
    int k,			/* floor(log10(d)), approximately. */
    int k_check,		/* 0 if k is exact, 1 if it may be too high */
    int flags,			/* Flags passed to dtoa:
				 *    TCL_DD_SHORTEN_FLAG */
				 *    TCL_DD_SHORTEST */
    int len,			/* Length of the return value. */
    int ilim,			/* Number of digits to store. */
    int ilim1,			/* Number of digits to store if we misguessed
				 * k. */
    int *decpt,			/* OUTPUT: Location of the decimal point. */
    char **endPtr)		/* OUTPUT: Pointer to the terminal null
				 * byte. */
2791
2792
2793
2794
2795
2796
2797
2798

2799
2800
2801
2802
2803
2804
2805
2791
2792
2793
2794
2795
2796
2797

2798
2799
2800
2801
2802
2803
2804
2805







-
+







	}
    }

    /*
     * Format the digit string.
     */

    if (flags & TCL_DD_SHORTEN_FLAG) {
    if (flags & TCL_DD_SHORTEST) {
	end = ShorteningQuickFormat(d, k, ilim, eps.d, retval, decpt);
    } else {
	end = StrictQuickFormat(d, k, ilim, eps.d, retval, decpt);
    }
    if (end == NULL) {
	ckfree(retval);
	return NULL;
4007
4008
4009
4010
4011
4012
4013
4014

4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025

4026
4027
4028
4029
4030
4031
4032
4007
4008
4009
4010
4011
4012
4013

4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024

4025
4026
4027
4028
4029
4030
4031
4032







-
+










-
+







 *		With this value, the 'ndigits' parameter is ignored.
 *	TCL_DD_E_FORMAT - This value is used to prepare numbers for %e format
 *		conversion (or for default floating->string if tcl_precision
 *		is not 0). It constructs a string of at most 'ndigits' digits,
 *		choosing the one that is closest to the given number (and
 *		resolving ties with 'round to even').  It is allowed to return
 *		fewer than 'ndigits' if the number converts exactly; if the
 *		TCL_DD_E_FORMAT|TCL_DD_SHORTEN_FLAG is supplied instead, it
 *		TCL_DD_E_FORMAT|TCL_DD_SHORTEST is supplied instead, it
 *		also returns fewer digits if the shorter string will still
 *		reconvert without loss to the given input number. In any case,
 *		strings of trailing zeroes are suppressed.
 *	TCL_DD_F_FORMAT - This value is used to prepare numbers for %f format
 *		conversion. It requests that conversion proceed until
 *		'ndigits' digits after the decimal point have been converted.
 *		It is possible for this format to result in a zero-length
 *		string if the number is sufficiently small. Again, it is
 *		permissible for TCL_DD_F_FORMAT to return fewer digits for a
 *		number that converts exactly, and changing the argument to
 *		TCL_DD_F_FORMAT|TCL_DD_SHORTEN_FLAG will allow the routine
 *		TCL_DD_F_FORMAT|TCL_DD_SHORTEST will allow the routine
 *		also to return fewer digits if the shorter string will still
 *		reconvert without loss to the given input number. Strings of
 *		trailing zeroes are suppressed.
 *
 *	To any of these flags may be OR'ed TCL_DD_NO_QUICK; this flag requires
 *	all calculations to be done in exact arithmetic. Normally, E and F
 *	format with fewer than about 14 digits will be done with a quick
4155
4156
4157
4158
4159
4160
4161
4162

4163
4164
4165
4166
4167
4168
4169
4155
4156
4157
4158
4159
4160
4161

4162
4163
4164
4165
4166
4167
4168
4169







-
+







     *        side, and
     *   m- = (2**m2minus * 5**m5) / (2**s2 * 5**s5) is the limit on the low
     *        side.
     * We may need to increase s2 to put m2plus, m2minus, b2 over a common
     * denominator.
     */

    if (flags & TCL_DD_SHORTEN_FLAG) {
    if (flags & TCL_DD_SHORTEST) {
	int m2minus = b2;
	int m2plus;
	int m5 = b5;
	int len = i;

	/*
	 * Find the quantity i so that (2**i*5**b5)/(2**s2*5**s5) is 1/2 unit
4544
4545
4546
4547
4548
4549
4550
4551
4552


4553
4554

4555
4556
4557
4558
4559
4560
4561
4544
4545
4546
4547
4548
4549
4550


4551
4552
4553

4554
4555
4556
4557
4558
4559
4560
4561







-
-
+
+

-
+







     * We need a 'mantBits'-bit significand.  Determine what shift will
     * give us that.
     */

    bits = mp_count_bits(a);
    if (bits > DBL_MAX_EXP*log2FLT_RADIX) {
	errno = ERANGE;
	if (a->sign == MP_ZPOS) {
	    return HUGE_VAL;
	if (mp_isneg(a)) {
	    return -HUGE_VAL;
	} else {
	    return -HUGE_VAL;
	    return HUGE_VAL;
	}
    }
    shift = mantBits - bits;

    /*
     * If shift > 0, shift the significand left by the requisite number of
     * bits.  If shift == 0, the significand is already exactly 'mantBits'
4577
4578
4579
4580
4581
4582
4583
4584
4585


4586
4587

4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598


4599
4600

4601
4602
4603
4604
4605
4606
4607
4577
4578
4579
4580
4581
4582
4583


4584
4585
4586

4587
4588
4589
4590
4591
4592
4593
4594
4595
4596


4597
4598
4599

4600
4601
4602
4603
4604
4605
4606
4607







-
-
+
+

-
+









-
-
+
+

-
+








	    /*
	     * Round to even
	     */

	    mp_div_2d(a, -shift, &b, NULL);
	    if (mp_isodd(&b)) {
		if (b.sign == MP_ZPOS) {
		    mp_add_d(&b, 1, &b);
		if (mp_isneg(&b)) {
		    mp_sub_d(&b, 1, &b);
		} else {
		    mp_sub_d(&b, 1, &b);
		    mp_add_d(&b, 1, &b);
		}
	    }
	} else {

	    /*
	     * Ordinary rounding
	     */

	    mp_div_2d(a, -1-shift, &b, NULL);
	    if (b.sign == MP_ZPOS) {
		mp_add_d(&b, 1, &b);
	    if (mp_isneg(&b)) {
		mp_sub_d(&b, 1, &b);
	    } else {
		mp_sub_d(&b, 1, &b);
		mp_add_d(&b, 1, &b);
	    }
	    mp_div_2d(&b, 1, &b, NULL);
	}
    }

    /*
     * Accumulate the result, one mp_digit at a time.
4619
4620
4621
4622
4623
4624
4625
4626
4627


4628
4629

4630
4631
4632
4633
4634
4635
4636
4619
4620
4621
4622
4623
4624
4625


4626
4627
4628

4629
4630
4631
4632
4633
4634
4635
4636







-
-
+
+

-
+








    r = ldexp(r, bits - mantBits);

    /*
     * Return the result with the appropriate sign.
     */

    if (a->sign == MP_ZPOS) {
	return r;
    if (mp_isneg(a)) {
	return -r;
    } else {
	return -r;
	return r;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclCeil --
4648
4649
4650
4651
4652
4653
4654
4655

4656
4657
4658
4659
4660
4661
4662
4648
4649
4650
4651
4652
4653
4654

4655
4656
4657
4658
4659
4660
4661
4662







-
+







TclCeil(
    const mp_int *a)			/* Integer to convert. */
{
    double r = 0.0;
    mp_int b;

    mp_init(&b);
    if (a->sign != MP_ZPOS) {
    if (mp_isneg(a)) {
	mp_neg(a, &b);
	r = -TclFloor(&b);
    } else {
	int bits = mp_count_bits(a);

	if (bits > DBL_MAX_EXP*log2FLT_RADIX) {
	    r = HUGE_VAL;
4705
4706
4707
4708
4709
4710
4711
4712

4713
4714
4715
4716
4717
4718
4719
4705
4706
4707
4708
4709
4710
4711

4712
4713
4714
4715
4716
4717
4718
4719







-
+







TclFloor(
    const mp_int *a)			/* Integer to convert. */
{
    double r = 0.0;
    mp_int b;

    mp_init(&b);
    if (a->sign != MP_ZPOS) {
    if (mp_isneg(a)) {
	mp_neg(a, &b);
	r = -TclCeil(&b);
    } else {
	int bits = mp_count_bits(a);

	if (bits > DBL_MAX_EXP*log2FLT_RADIX) {
	    r = DBL_MAX;
4795
4796
4797
4798
4799
4800
4801
4802

4803
4804
4805
4806
4807
4808
4809
4795
4796
4797
4798
4799
4800
4801

4802
4803
4804
4805
4806
4807
4808
4809







-
+







    mp_clear(&b);

    /*
     * Return the result with the appropriate sign.
     */

    *machexp = bits - mantBits + 2;
    return ((a->sign == MP_ZPOS) ? r : -r);
    return (mp_isneg(a) ? -r : r);
}

/*
 *----------------------------------------------------------------------
 *
 * Pow10TimesFrExp --
 *