| ︙ | | |
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
|
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
|
-
+
|
*
* Side effects:
* Stores base*5**n in result.
*
*----------------------------------------------------------------------
*/
inline static void
static inline void
MulPow5(
mp_int *base, /* Number to multiply. */
unsigned n, /* Power of 5 to multiply by. */
mp_int *result) /* Place to store the result. */
{
mp_int *p = base;
int n13 = n / 13;
|
| ︙ | | |
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
|
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
|
-
+
|
*
* Side effects:
* Shifts the number in place; *wPtr is replaced by the shifted number.
*
*----------------------------------------------------------------------
*/
inline static int
static inline int
NormalizeRightward(
Tcl_WideUInt *wPtr) /* INOUT: Number to shift. */
{
int rv = 0;
Tcl_WideUInt w = *wPtr;
if (!(w & (Tcl_WideUInt) 0xffffffff)) {
|
| ︙ | | |
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
|
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
|
-
+
|
* Stores the significand in '*significand' and the exponent in '*expon'
* so that dv == significand * 2.0**expon, and significand is odd. Also
* stores the position of the leftmost 1-bit in 'significand' in 'bits'.
*
*----------------------------------------------------------------------
*/
inline static void
static inline void
DoubleToExpAndSig(
double dv, /* Number to convert. */
Tcl_WideUInt *significand, /* OUTPUT: Significand of the number. */
int *expon, /* OUTPUT: Exponent to multiply the number
* by. */
int *bits) /* OUTPUT: Number of significant bits. */
{
|
| ︙ | | |
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
|
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
|
-
+
|
* Side effects:
* The 'double' in *d is replaced with its absolute value. The signum is
* stored in 'sign': 1 for negative, 0 for nonnegative.
*
*----------------------------------------------------------------------
*/
inline static void
static inline void
TakeAbsoluteValue(
Double *d, /* Number to replace with absolute value. */
int *sign) /* Place to put the signum. */
{
if (d->w.word0 & SIGN_BIT) {
*sign = 1;
d->w.word0 &= ~SIGN_BIT;
|
| ︙ | | |
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
|
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
|
-
+
|
* Side effects:
* Stores 9999 in *decpt, and sets '*endPtr' to designate the terminating
* NUL byte of the string if 'endPtr' is not NULL.
*
*----------------------------------------------------------------------
*/
inline static char *
static inline char *
FormatInfAndNaN(
Double *d, /* Exceptional number to format. */
int *decpt, /* Decimal point to set to a bogus value. */
char **endPtr) /* Pointer to the end of the formatted data */
{
char *retval;
|
| ︙ | | |
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
|
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
|
-
+
|
* Side effects:
* Stores 1 in '*decpt' and puts a pointer to the NUL byte terminating
* the string in '*endPtr' if 'endPtr' is not NULL.
*
*----------------------------------------------------------------------
*/
inline static char *
static inline char *
FormatZero(
int *decpt, /* Location of the decimal point. */
char **endPtr) /* Pointer to the end of the formatted data */
{
char *retval = ckalloc(2);
strcpy(retval, "0");
|
| ︙ | | |
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
|
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
|
-
+
|
* Results:
* Return an approximation to floor(log10(bw*2**be)) that is either exact
* or 1 too high.
*
*----------------------------------------------------------------------
*/
inline static int
static inline int
ApproximateLog10(
Tcl_WideUInt bw, /* Integer significand of the number. */
int be, /* Power of two to scale bw. */
int bbits) /* Number of bits of precision in bw. */
{
int i; /* Log base 2 of the number. */
int k; /* Floor(Log base 10 of the number) */
|
| ︙ | | |
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
|
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
|
-
+
|
*
* Results:
* Returns the improved approximation to log10(d).
*
*----------------------------------------------------------------------
*/
inline static int
static inline int
BetterLog10(
double d, /* Original number to format. */
int k, /* Characteristic(Log base 10) of the
* number. */
int *k_check) /* Flag == 1 if k is inexact. */
{
/*
|
| ︙ | | |
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
|
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
|
-
+
|
* exactly represents the value of the x/10**k. This value will lie in
* the range [1 .. 10), and allows for computing successive digits by
* multiplying sig%10 by 10.
*
*----------------------------------------------------------------------
*/
inline static void
static inline void
ComputeScale(
int be, /* Exponent part of number: d = bw * 2**be. */
int k, /* Characteristic of log10(number). */
int *b2, /* OUTPUT: Power of 2 in the numerator. */
int *b5, /* OUTPUT: Power of 5 in the numerator. */
int *s2, /* OUTPUT: Power of 2 in the denominator. */
int *s5) /* OUTPUT: Power of 5 in the denominator. */
|
| ︙ | | |
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
|
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
|
-
+
|
* digits to convert if k has been guessed correctly, and '*iLim1Ptr' to
* the limiting number of digits to convert if k has been guessed to be
* one too high.
*
*----------------------------------------------------------------------
*/
inline static void
static inline void
SetPrecisionLimits(
int convType, /* Type of conversion: TCL_DD_SHORTEST,
* TCL_DD_STEELE0, TCL_DD_E_FMT,
* TCL_DD_F_FMT. */
int k, /* Floor(log10(number to convert)) */
int *ndigitsPtr, /* IN/OUT: Number of digits requested (will be
* adjusted if needed). */
|
| ︙ | | |
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
|
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
|
-
+
|
* Side effects:
* In the case that the string consists solely of '999999', sets it to
* "1" and moves the decimal point (*kPtr) one place to the right.
*
*----------------------------------------------------------------------
*/
inline static char *
static inline char *
BumpUp(
char *s, /* Cursor pointing one past the end of the
* string. */
char *retval, /* Start of the string of digits. */
int *kPtr) /* Position of the decimal point. */
{
while (*--s == '9') {
|
| ︙ | | |
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
|
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
|
-
+
|
* Results:
* Returns the precision that has been lost in the prescaling as a count
* of units in the least significant place.
*
*----------------------------------------------------------------------
*/
inline static int
static inline int
AdjustRange(
double *dPtr, /* INOUT: Number to adjust. */
int k) /* IN: floor(log10(d)) */
{
int ieps; /* Number of roundoff errors that have
* accumulated. */
double d = *dPtr; /* Number to adjust. */
|
| ︙ | | |
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
|
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
|
-
+
|
*
* Side effects:
* Stores the position of the decimal point at '*kPtr'.
*
*----------------------------------------------------------------------
*/
inline static char *
static inline char *
ShorteningQuickFormat(
double d, /* Number to convert. */
int k, /* floor(log10(d)) */
int ilim, /* Number of significant digits to return. */
double eps, /* Estimated roundoff error. */
char *retval, /* Buffer to receive the digit string. */
int *kPtr) /* Pointer to stash the position of the
|
| ︙ | | |
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
|
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
|
-
+
|
*
* Side effects:
* Stores the position of the decimal point in '*kPtr'.
*
*----------------------------------------------------------------------
*/
inline static char *
static inline char *
StrictQuickFormat(
double d, /* Number to convert. */
int k, /* floor(log10(d)) */
int ilim, /* Number of significant digits to return. */
double eps, /* Estimated roundoff error. */
char *retval, /* Start of the digit string. */
int *kPtr) /* Pointer to stash the position of the
|
| ︙ | | |
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
|
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
|
-
+
|
* Results:
* Returns the converted string, or NULL if the bignum method must be
* used.
*
*----------------------------------------------------------------------
*/
inline static char *
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. */
|
| ︙ | | |
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
|
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
|
-
+
|
* Adjust the factors 'b2', 'm2', and 's2' to cast out common powers of 2
* from numerator and denominator in preparation for the 'bignum' method
* of floating point conversion.
*
*----------------------------------------------------------------------
*/
inline static void
static inline void
CastOutPowersOf2(
int *b2, /* Power of 2 to multiply the significand. */
int *m2, /* Power of 2 to multiply 1/2 ulp. */
int *s2) /* Power of 2 to multiply the common
* denominator. */
{
int i;
|
| ︙ | | |
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
|
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
|
-
+
|
* Side effects:
* Stores the location of the decimal point in '*decpt' and the location
* of the terminal null byte in '*endPtr'.
*
*----------------------------------------------------------------------
*/
inline static char *
static inline char *
ShorteningInt64Conversion(
Double *dPtr, /* Original number to convert. */
int convType, /* Type of conversion (shortest, Steele,
* E format, F format). */
Tcl_WideUInt bw, /* Integer significand. */
int b2, int b5, /* Scale factor for the significand in the
* numerator. */
|
| ︙ | | |
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
|
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
|
-
+
|
* Side effects:
* Stores the location of the decimal point in '*decpt' and the location
* of the terminal null byte in '*endPtr'.
*
*----------------------------------------------------------------------
*/
inline static char *
static inline char *
StrictInt64Conversion(
Double *dPtr, /* Original number to convert. */
int convType, /* Type of conversion (shortest, Steele,
* E format, F format). */
Tcl_WideUInt bw, /* Integer significand. */
int b2, int b5, /* Scale factor for the significand in the
* numerator. */
|
| ︙ | | |
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
|
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
|
-
+
|
* Results:
* Returns 1 iff the fraction is more than 1/2, or if the fraction is
* exactly 1/2 and the digit is odd.
*
*----------------------------------------------------------------------
*/
inline static int
static inline int
ShouldBankerRoundUpPowD(
mp_int *b, /* Numerator of the fraction. */
int sd, /* Denominator is 2**(sd*DIGIT_BIT). */
int isodd) /* 1 if the digit is odd, 0 if even. */
{
int i;
static const mp_digit topbit = 1 << (DIGIT_BIT - 1);
|
| ︙ | | |
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
|
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
|
-
+
|
* Results:
* Returns 1 if the rounding will be performed - which increases the
* digit by one - and 0 otherwise.
*
*----------------------------------------------------------------------
*/
inline static int
static inline int
ShouldBankerRoundUpToNextPowD(
mp_int *b, /* Numerator of the fraction. */
mp_int *m, /* Numerator of the rounding tolerance. */
int sd, /* Common denominator is 2**(sd*DIGIT_BIT). */
int convType, /* Conversion type: STEELE defeats
* round-to-even (not sure why one wants to do
* this; I copied it from Gay). FIXME */
|
| ︙ | | |
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
|
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
|
-
+
|
* Side effects:
* Stores the location of the decimal point in '*decpt' and the location
* of the terminal null byte in '*endPtr'.
*
*----------------------------------------------------------------------
*/
inline static char *
static inline char *
ShorteningBignumConversionPowD(
Double *dPtr, /* Original number to convert. */
int convType, /* Type of conversion (shortest, Steele,
* E format, F format). */
Tcl_WideUInt bw, /* Integer significand. */
int b2, int b5, /* Scale factor for the significand in the
* numerator. */
|
| ︙ | | |
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
|
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
|
-
+
|
* Side effects:
* Stores the location of the decimal point in '*decpt' and the location
* of the terminal null byte in '*endPtr'.
*
*----------------------------------------------------------------------
*/
inline static char *
static inline char *
StrictBignumConversionPowD(
Double *dPtr, /* Original number to convert. */
int convType, /* Type of conversion (shortest, Steele,
* E format, F format). */
Tcl_WideUInt bw, /* Integer significand. */
int b2, int b5, /* Scale factor for the significand in the
* numerator. */
|
| ︙ | | |
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
|
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
|
-
+
|
*
* Results:
* Returns 1 if the number needs to be rounded up, 0 otherwise.
*
*----------------------------------------------------------------------
*/
inline static int
static inline int
ShouldBankerRoundUp(
mp_int *twor, /* 2x the remainder from thd division that
* produced the last digit. */
mp_int *S, /* Denominator. */
int isodd) /* Flag == 1 if the last digit is odd. */
{
int r = mp_cmp_mag(twor, S);
|
| ︙ | | |
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
|
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
|
-
+
|
*
* Results:
* Returns 1 if the number should be rounded up, 0 otherwise.
*
*----------------------------------------------------------------------
*/
inline static int
static inline int
ShouldBankerRoundUpToNext(
mp_int *b, /* Remainder from the division that produced
* the last digit. */
mp_int *m, /* Numerator of the rounding tolerance. */
mp_int *S, /* Denominator. */
int convType, /* Conversion type: STEELE0 defeats
* round-to-even. (Not sure why one would want
|
| ︙ | | |
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
|
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
|
-
+
|
* Side effects:
* Stores the position of the decimal point in *decpt. Stores a pointer
* to the end of the number in *endPtr.
*
*----------------------------------------------------------------------
*/
inline static char *
static inline char *
ShorteningBignumConversion(
Double *dPtr, /* Original number being converted. */
int convType, /* Conversion type. */
Tcl_WideUInt bw, /* Integer significand and exponent. */
int b2, /* Scale factor for the significand. */
int m2plus, int m2minus, /* Scale factors for 1/2 ulp in numerator. */
int s2, int s5, /* Scale factors for denominator. */
|
| ︙ | | |
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
|
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
|
-
+
|
* Side effects:
* Stores the position of the decimal point in *decpt. Stores a pointer
* to the end of the number in *endPtr.
*
*----------------------------------------------------------------------
*/
inline static char *
static inline char *
StrictBignumConversion(
Double *dPtr, /* Original number being converted. */
int convType, /* Conversion type. */
Tcl_WideUInt bw, /* Integer significand and exponent. */
int b2, /* Scale factor for the significand. */
int s2, int s5, /* Scale factors for denominator. */
int k, /* Guessed position of the decimal point. */
|
| ︙ | | |