| ︙ | | | ︙ | |
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 */
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. */
|
|
|
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_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
|
}
}
/*
* Format the digit string.
*/
if (flags & TCL_DD_SHORTEN_FLAG) {
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;
|
|
|
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
|
}
}
/*
* Format the digit string.
*/
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
|
* 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
* 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
* 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
|
|
|
|
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_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_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
|
* 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) {
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
|
|
|
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_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
|
* 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;
} else {
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'
|
|
|
|
|
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 (mp_isneg(a)) {
return -HUGE_VAL;
} else {
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
|
/*
* 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);
} else {
mp_sub_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);
} else {
mp_sub_d(&b, 1, &b);
}
mp_div_2d(&b, 1, &b, NULL);
}
}
/*
* Accumulate the result, one mp_digit at a time.
|
|
|
|
|
|
|
|
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 (mp_isneg(&b)) {
mp_sub_d(&b, 1, &b);
} else {
mp_add_d(&b, 1, &b);
}
}
} else {
/*
* Ordinary rounding
*/
mp_div_2d(a, -1-shift, &b, NULL);
if (mp_isneg(&b)) {
mp_sub_d(&b, 1, &b);
} else {
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
|
r = ldexp(r, bits - mantBits);
/*
* Return the result with the appropriate sign.
*/
if (a->sign == MP_ZPOS) {
return r;
} else {
return -r;
}
}
/*
*----------------------------------------------------------------------
*
* TclCeil --
|
|
|
|
|
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 (mp_isneg(a)) {
return -r;
} else {
return r;
}
}
/*
*----------------------------------------------------------------------
*
* TclCeil --
|
| ︙ | | | ︙ | |
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) {
mp_neg(a, &b);
r = -TclFloor(&b);
} else {
int bits = mp_count_bits(a);
if (bits > DBL_MAX_EXP*log2FLT_RADIX) {
r = HUGE_VAL;
|
|
|
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 (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
|
TclFloor(
const mp_int *a) /* Integer to convert. */
{
double r = 0.0;
mp_int b;
mp_init(&b);
if (a->sign != MP_ZPOS) {
mp_neg(a, &b);
r = -TclCeil(&b);
} else {
int bits = mp_count_bits(a);
if (bits > DBL_MAX_EXP*log2FLT_RADIX) {
r = DBL_MAX;
|
|
|
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 (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
|
mp_clear(&b);
/*
* Return the result with the appropriate sign.
*/
*machexp = bits - mantBits + 2;
return ((a->sign == MP_ZPOS) ? r : -r);
}
/*
*----------------------------------------------------------------------
*
* Pow10TimesFrExp --
*
|
|
|
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 (mp_isneg(a) ? -r : r);
}
/*
*----------------------------------------------------------------------
*
* Pow10TimesFrExp --
*
|
| ︙ | | | ︙ | |