Diff
Not logged in

Differences From Artifact [d87a4547a8]:

To Artifact [4e6f6765d9]:


201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215







-
+







    1.0e+16,
    1.0e+32,
    1.0e+64,
    1.0e+128,
    1.0e+256
};

static int n770_fp;		/* Flag is 1 on Nokia N770 floating point.
static bool n770_fp;		/* Flag is true on Nokia N770 floating point.
				 * Nokia's floating point has the words
				 * reversed: if big-endian is 7654 3210,
				 * and little-endian is       0123 4567,
				 * then Nokia's FP is         4567 0123;
				 * little-endian within the 32-bit words but
				 * big-endian between them. */

291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
291
292
293
294
295
296
297

298
299
300
301
302
303
304
305







-
+







    (Tcl_WideUInt) 3125U*3125U*3125U*3125U*3125U*25U /* 5**27 */
};

/*
 * Static functions defined in this file.
 */

static int		AccumulateDecimalDigit(unsigned, int,
static bool		AccumulateDecimalDigit(unsigned, int,
			    Tcl_WideUInt *, mp_int *, int);
static double		MakeHighPrecisionDouble(int signum,
			    mp_int *significand, int nSigDigs, int exponent);
static double		MakeLowPrecisionDouble(int signum,
			    Tcl_WideUInt significand, int nSigDigs,
			    int exponent);
#ifdef IEEE_FLOATING_POINT
331
332
333
334
335
336
337
338
339
340



341
342
343
344
345
346
347
348
349
350
351
352
353
354



355
356
357
358
359
360
361
331
332
333
334
335
336
337



338
339
340
341
342
343
344
345
346
347
348
349
350
351



352
353
354
355
356
357
358
359
360
361







-
-
-
+
+
+











-
-
-
+
+
+







static void		CastOutPowersOf2(int *, int *, int *);
static char *		ShorteningInt64Conversion(Double *, Tcl_WideUInt,
			    int, int, int, int, int, int, int, int, int,
			    int, int, int *, char **);
static char *		StrictInt64Conversion(Tcl_WideUInt,
			    int, int, int, int, int, int,
			    int, int, int *, char **);
static int		ShouldBankerRoundUpPowD(mp_int *, int, int);
static int		ShouldBankerRoundUpToNextPowD(mp_int *, mp_int *,
			    int, int, mp_int *);
static bool		ShouldBankerRoundUpPowD(mp_int *, int, bool);
static bool		ShouldBankerRoundUpToNextPowD(mp_int *, mp_int *,
			    int, bool, mp_int *);
static char *		ShorteningBignumConversionPowD(Double *dPtr,
			    Tcl_WideUInt bw, int b2, int b5,
			    int m2plus, int m2minus, int m5,
			    int sd, int k, int len,
			    int ilim, int ilim1, int *decpt,
			    char **endPtr);
static char *		StrictBignumConversionPowD(
			    Tcl_WideUInt bw, int b2, int b5,
			    int sd, int k, int len,
			    int ilim, int ilim1, int *decpt,
			    char **endPtr);
static int		ShouldBankerRoundUp(mp_int *, mp_int *, int);
static int		ShouldBankerRoundUpToNext(mp_int *, mp_int *,
			    mp_int *, int);
static bool		ShouldBankerRoundUp(mp_int *, mp_int *, bool);
static bool		ShouldBankerRoundUpToNext(mp_int *, mp_int *,
			    mp_int *, bool);
static char *		ShorteningBignumConversion(Double *dPtr,
			    Tcl_WideUInt bw, int b2,
			    int m2plus, int m2minus,
			    int s2, int s5, int k, int len,
			    int ilim, int ilim1, int *decpt,
			    char **endPtr);
static char *		StrictBignumConversion(
504
505
506
507
508
509
510
511

512
513
514
515
516
517
518
519
520


521
522
523
524
525
526
527
504
505
506
507
508
509
510

511
512
513
514
515
516
517
518


519
520
521
522
523
524
525
526
527







-
+







-
-
+
+








    int signum = 0;		/* Sign of the number being parsed. */
    Tcl_WideUInt significandWide = 0;
				/* Significand of the number being parsed (if
				 * no overflow). */
    mp_int significandBig;	/* Significand of the number being parsed (if
				 * it overflows significandWide). */
    int significandOverflow = 0;/* Flag==1 iff significandBig is used. */
    bool significandOverflow = false;/* True iff significandBig is used. */
    Tcl_WideUInt octalSignificandWide = 0;
				/* Significand of an octal number; needed
				 * because we don't know whether a number with
				 * a leading zero is octal or decimal until
				 * we've scanned forward to a '.' or 'e'. */
    mp_int octalSignificandBig;	/* Significand of octal number once
				 * octalSignificandWide overflows. */
    int octalSignificandOverflow = 0;
				/* Flag==1 if octalSignificandBig is used. */
    bool octalSignificandOverflow = false;
				/* True if octalSignificandBig is used. */
    int numSigDigs = 0;		/* Number of significant digits in the decimal
				 * significand. */
    int numTrailZeros = 0;	/* Number of trailing zeroes at the current
				 * point in the parse. */
    int numDigitsAfterDp = 0;	/* Number of digits scanned after the decimal
				 * point. */
    int exponentSignum = 0;	/* Signum of the exponent of a floating point
791
792
793
794
795
796
797
798

799
800
801
802
803
804
805
791
792
793
794
795
796
797

798
799
800
801
802
803
804
805







-
+







			 */

			if ((octalSignificandWide != 0)
				&& (((size_t)shift >=
					CHAR_BIT*sizeof(Tcl_WideUInt))
				|| (octalSignificandWide >
					(UWIDE_MAX >> shift)))) {
			    octalSignificandOverflow = 1;
			    octalSignificandOverflow = true;
			    err = mp_init_u64(&octalSignificandBig,
				    octalSignificandWide);
			}
		    }
		    if (!octalSignificandOverflow) {
			/*
			 * When the significand is 0, it is possible for the
872
873
874
875
876
877
878
879

880
881
882
883
884
885
886
872
873
874
875
876
877
878

879
880
881
882
883
884
885
886







-
+







		     * value being shifted is undefined behavior. Check
		     * for too large shifts first.
		     */

		    if (significandWide != 0 &&
			    ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
			    significandWide > (UWIDE_MAX >> shift))) {
			significandOverflow = 1;
			significandOverflow = true;
			err = mp_init_u64(&significandBig,
				significandWide);
		    }
		}
		if (!significandOverflow) {
		    /*
		     * When the significand is 0, it is possible for the
929
930
931
932
933
934
935
936

937
938
939
940
941
942
943
929
930
931
932
933
934
935

936
937
938
939
940
941
942
943







-
+







		     * value being shifted is undefined behavior. Check
		     * for too large shifts first.
		     */

		    if (significandWide != 0 &&
			    ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
			    significandWide > (UWIDE_MAX >> shift))) {
			significandOverflow = 1;
			significandOverflow = true;
			err = mp_init_u64(&significandBig,
				significandWide);
		    }
		}
		if (!significandOverflow) {
		    /*
		     * When the significand is 0, it is possible for the
1290
1291
1292
1293
1294
1295
1296
1297

1298
1299
1300
1301
1302
1303
1304
1290
1291
1292
1293
1294
1295
1296

1297
1298
1299
1300
1301
1302
1303
1304







-
+







	    Tcl_Panic("TclParseNumber: bad acceptState %d parsing '%s'",
		    acceptState, bytes);
	case BINARY:
	    shift = numTrailZeros;
	    if (!significandOverflow && significandWide != 0 &&
		    ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
		    significandWide > (MOST_BITS + signum) >> shift)) {
		significandOverflow = 1;
		significandOverflow = true;
		err = mp_init_u64(&significandBig, significandWide);
	    }
	    if (shift) {
		if (!significandOverflow) {
		    /*
		     * When the significand is 0, it is possible for the
		     * amount to be shifted to equal or exceed the width
1322
1323
1324
1325
1326
1327
1328
1329

1330
1331
1332
1333
1334
1335
1336
1322
1323
1324
1325
1326
1327
1328

1329
1330
1331
1332
1333
1334
1335
1336







-
+







	     * Returning a hex integer. Final scaling step.
	     */

	    shift = 4 * numTrailZeros;
	    if (!significandOverflow && significandWide !=0 &&
		    ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
		    significandWide > (MOST_BITS + signum) >> shift)) {
		significandOverflow = 1;
		significandOverflow = true;
		err = mp_init_u64(&significandBig, significandWide);
	    }
	    if (shift) {
		if (!significandOverflow) {
		    /*
		     * When the significand is 0, it is possible for the
		     * amount to be shifted to equal or exceed the width
1354
1355
1356
1357
1358
1359
1360
1361

1362
1363
1364
1365
1366
1367
1368
1354
1355
1356
1357
1358
1359
1360

1361
1362
1363
1364
1365
1366
1367
1368







-
+







	     * Returning an octal integer. Final scaling step.
	     */

	    shift = 3 * numTrailZeros;
	    if (!octalSignificandOverflow && octalSignificandWide != 0 &&
		    ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
		    octalSignificandWide > (MOST_BITS + signum) >> shift)) {
		octalSignificandOverflow = 1;
		octalSignificandOverflow = true;
		err = mp_init_u64(&octalSignificandBig,
			octalSignificandWide);
	    }
	    if (shift) {
		if (!octalSignificandOverflow) {
		    /*
		     * When the significand is 0, it is possible for the
1378
1379
1380
1381
1382
1383
1384
1385

1386
1387
1388
1389
1390
1391
1392
1378
1379
1380
1381
1382
1383
1384

1385
1386
1387
1388
1389
1390
1391
1392







-
+







			    &octalSignificandBig);
		}
	    }
	    if (!octalSignificandOverflow) {
		if ((err == MP_OKAY) && (octalSignificandWide > (MOST_BITS + signum))) {
		    err = mp_init_u64(&octalSignificandBig,
			    octalSignificandWide);
		    octalSignificandOverflow = 1;
		    octalSignificandOverflow = true;
		} else {
		    objPtr->typePtr = &tclIntType;
		    if (signum) {
			objPtr->internalRep.wideValue =
				(Tcl_WideInt)(-octalSignificandWide);
		    } else {
			objPtr->internalRep.wideValue =
1406
1407
1408
1409
1410
1411
1412
1413

1414
1415
1416
1417
1418
1419
1420
1421

1422
1423
1424
1425
1426
1427
1428
1406
1407
1408
1409
1410
1411
1412

1413
1414
1415
1416
1417
1418
1419
1420

1421
1422
1423
1424
1425
1426
1427
1428







-
+







-
+







	    break;

	case ZERO:
	case DECIMAL:
	    significandOverflow = AccumulateDecimalDigit(0, numTrailZeros-1,
		    &significandWide, &significandBig, significandOverflow);
	    if ((err == MP_OKAY) && !significandOverflow && (significandWide > MOST_BITS+signum)) {
		significandOverflow = 1;
		significandOverflow = true;
		err = mp_init_u64(&significandBig, significandWide);
	    }
	returnInteger:
	    if (!significandOverflow) {
		if ((err == MP_OKAY) && (significandWide > MOST_BITS+signum)) {
		    err = mp_init_u64(&significandBig,
			    significandWide);
		    significandOverflow = 1;
		    significandOverflow = true;
		} else {
		    objPtr->typePtr = &tclIntType;
		    if (signum) {
			objPtr->internalRep.wideValue =
				(Tcl_WideInt)(-significandWide);
		    } else {
			objPtr->internalRep.wideValue =
1560
1561
1562
1563
1564
1565
1566
1567
1568


1569
1570
1571
1572
1573
1574
1575
1576

1577
1578
1579
1580
1581
1582
1583
1560
1561
1562
1563
1564
1565
1566


1567
1568
1569
1570
1571
1572
1573
1574
1575

1576
1577
1578
1579
1580
1581
1582
1583







-
-
+
+







-
+







 *----------------------------------------------------------------------
 *
 * AccumulateDecimalDigit --
 *
 *	Consume a decimal digit in a number being scanned.
 *
 * Results:
 *	Returns 1 if the number has overflowed to a bignum, 0 if it still fits
 *	in a wide integer.
 *	Returns true if the number has overflowed to a bignum, false if it
 *	still fits in a wide integer.
 *
 * Side effects:
 *	Updates either the wide or bignum representation.
 *
 *----------------------------------------------------------------------
 */

static int
static bool
AccumulateDecimalDigit(
    unsigned digit,		/* Digit being scanned. */
    int numZeros,		/* Count of zero digits preceding the digit
				 * being scanned. */
    Tcl_WideUInt *wideRepPtr,	/* Representation of the partial number as a
				 * wide integer. */
    mp_int *bignumRepPtr,	/* Representation of the partial number as a
1593
1594
1595
1596
1597
1598
1599
1600

1601
1602
1603
1604
1605
1606
1607
1608
1609

1610
1611
1612
1613
1614
1615
1616
1617

1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633



1634
1635
1636
1637
1638
1639
1640
1593
1594
1595
1596
1597
1598
1599

1600
1601
1602
1603
1604
1605
1606
1607
1608

1609
1610
1611
1612
1613
1614
1615
1616

1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631


1632
1633
1634
1635
1636
1637
1638
1639
1640
1641







-
+








-
+







-
+














-
-
+
+
+







	Tcl_WideUInt w = *wideRepPtr;
	if (w == 0) {
	    /*
	     * There's no need to multiply if the multiplicand is zero.
	     */

	    *wideRepPtr = digit;
	    return 0;
	    return false;
	} else if (numZeros >= maxpow10_wide
		|| w > (UWIDE_MAX-digit)/pow10_wide[numZeros+1]) {
	    /*
	     * Wide multiplication will overflow.  Expand the number to a
	     * bignum and fall through into the bignum case.
	     */

	    if (mp_init_u64(bignumRepPtr, w) != MP_OKAY) {
		return 0;
		return false;
	    }
	} else {
	    /*
	     * Wide multiplication.
	     */

	    *wideRepPtr = w * pow10_wide[numZeros+1] + digit;
	    return 0;
	    return false;
	}
    }

    /*
     * Bignum multiplication.
     */

    if (numZeros < log10_DIGIT_MAX) {
	/*
	 * Up to about 8 zeros - single digit multiplication.
	 */

	if ((mp_mul_d(bignumRepPtr, (mp_digit) pow10_wide[numZeros+1],
		bignumRepPtr) != MP_OKAY)
		|| (mp_add_d(bignumRepPtr, (mp_digit) digit, bignumRepPtr) != MP_OKAY))
	return 0;
		|| (mp_add_d(bignumRepPtr, (mp_digit) digit, bignumRepPtr) != MP_OKAY)) {
	    return false;
	}
    } else {
	/*
	 * More than single digit multiplication. Multiply by the appropriate
	 * small powers of 5, and then shift. Large strings of zeroes are
	 * eaten 256 at a time; this is less efficient than it could be, but
	 * seems implausible. We presume that MP_DIGIT_BIT is at least 27. The
	 * first multiplication, by up to 10**7, is done with a one-DIGIT
1651
1652
1653
1654
1655
1656
1657
1658

1659
1660
1661
1662

1663
1664
1665
1666
1667
1668
1669
1652
1653
1654
1655
1656
1657
1658

1659
1660
1661
1662

1663
1664
1665
1666
1667
1668
1669
1670







-
+



-
+







	while ((err == MP_OKAY) && (n >= 256)) {
	    err = mp_mul(bignumRepPtr, pow5+8, bignumRepPtr);
	    n -= 256;
	}
	if ((err != MP_OKAY)
		|| (mp_mul_2d(bignumRepPtr, (int)(numZeros+1)&~0x7, bignumRepPtr) != MP_OKAY)
		|| (mp_add_d(bignumRepPtr, (mp_digit) digit, bignumRepPtr) != MP_OKAY)) {
	    return 0;
	    return false;
	}
    }

    return 1;
    return true;
}

/*
 *----------------------------------------------------------------------
 *
 * MakeLowPrecisionDouble --
 *
2021
2022
2023
2024
2025
2026
2027
2028
2029


2030
2031
2032
2033
2034
2035
2036
2022
2023
2024
2025
2026
2027
2028


2029
2030
2031
2032
2033
2034
2035
2036
2037







-
-
+
+







    int scale;			/* Scale factor for M. */
    int multiplier;		/* Power of two to scale M. */
    double num, den;		/* Numerator and denominator of the correction
				 * term. */
    double quot;		/* Correction term. */
    double minincr;		/* Lower bound on the absolute value of the
				 * correction term. */
    int roundToEven = 0;	/* Flag == TRUE if we need to invoke
				 * "round to even" functionality */
    bool roundToEven = false;	/* True if we need to invoke "round to even"
				 * functionality */
    double rteSignificand;	/* Significand of the round-to-even result */
    int rteExponent;		/* Exponent of the round-to-even result */
    int shift;			/* Shift count for converting numerator
				 * and denominator of corrector to floating
				 * point */
    Tcl_WideInt rteSigWide;	/* Wide integer version of the significand
				 * for testing evenness */
2173
2174
2175
2176
2177
2178
2179
2180

2181
2182
2183
2184
2185
2186
2187
2174
2175
2176
2177
2178
2179
2180

2181
2182
2183
2184
2185
2186
2187
2188







-
+







	mp_clear(&twoMd);
	mp_clear(&twoMv);
	return approxResult;
    case MP_EQ:
	/*
	 * If the error is exactly 1/2 ULP, we need to round to even.
	 */
	roundToEven = 1;
	roundToEven = true;
	break;
    case MP_GT:
	/*
	 * We need to correct the result if the error exceeds 1/2 ULP.
	 */
	break;
    }
3406
3407
3408
3409
3410
3411
3412
3413

3414
3415
3416
3417

3418
3419
3420
3421
3422

3423
3424
3425

3426
3427
3428
3429

3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445


3446
3447
3448
3449
3450

3451
3452
3453
3454
3455

3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466

3467
3468
3469
3470

3471
3472
3473
3474
3475

3476
3477
3478
3479
3480
3481
3482
3407
3408
3409
3410
3411
3412
3413

3414
3415
3416
3417

3418
3419
3420
3421
3422

3423
3424
3425

3426
3427
3428
3429

3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444


3445
3446
3447
3448
3449
3450

3451
3452
3453
3454
3455

3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466

3467
3468
3469
3470

3471
3472
3473
3474
3475

3476
3477
3478
3479
3480
3481
3482
3483







-
+



-
+




-
+


-
+



-
+














-
-
+
+




-
+




-
+










-
+



-
+




-
+







 * Results:
 *	Returns 1 iff the fraction is more than 1/2, or if the fraction is
 *	exactly 1/2 and the digit is odd.
 *
 *----------------------------------------------------------------------
 */

static inline int
static inline bool
ShouldBankerRoundUpPowD(
    mp_int *b,			/* Numerator of the fraction. */
    int sd,			/* Denominator is 2**(sd*MP_DIGIT_BIT). */
    int isodd)			/* 1 if the digit is odd, 0 if even. */
    bool isodd)			/* true if the digit is odd, false if even. */
{
    static const mp_digit topbit = ((mp_digit)1) << (MP_DIGIT_BIT - 1);

    if (b->used < sd || (b->dp[sd-1] & topbit) == 0) {
	return 0;
	return false;
    }
    if (b->dp[sd-1] != topbit) {
	return 1;
	return true;
    }
    for (int i = sd-2; i >= 0; --i) {
	if (b->dp[i] != 0) {
	    return 1;
	    return true;
	}
    }
    return isodd;
}

/*
 *----------------------------------------------------------------------
 *
 * ShouldBankerRoundUpToNextPowD --
 *
 *	Tests whether bankers' rounding will round down in the "denominator is
 *	a power of 2**MP_DIGIT" case.
 *
 * Results:
 *	Returns 1 if the rounding will be performed - which increases the
 *	digit by one - and 0 otherwise.
 *	Returns true if the rounding will be performed - which increases the
 *	digit by one - and false otherwise.
 *
 *----------------------------------------------------------------------
 */

static inline int
static inline bool
ShouldBankerRoundUpToNextPowD(
    mp_int *b,			/* Numerator of the fraction. */
    mp_int *m,			/* Numerator of the rounding tolerance. */
    int sd,			/* Common denominator is 2**(sd*MP_DIGIT_BIT). */
    int isodd,			/* 1 if the integer significand is odd. */
    bool isodd,			/* 1 if the integer significand is odd. */
    mp_int *temp)		/* Work area for the calculation. */
{
    /*
     * Compare B and S-m - which is the same as comparing B+m and S - which we
     * do by computing b+m and doing a bitwhack compare against
     * 2**(MP_DIGIT_BIT*sd)
     */

    if ((mp_add(b, m, temp) != MP_OKAY) || (temp->used <= sd)) {
	/* Too few digits to be > s */
	return 0;
	return false;
    }
    if (temp->used > sd+1 || temp->dp[sd] > 1) {
				/* >= 2s */
	return 1;
	return true;
    }
    for (int i = sd-1; i >= 0; --i) {
				/* Check for ==s */
	if (temp->dp[i] != 0) {	/* > s */
	    return 1;
	    return true;
	}
    }
    return isodd;
}

/*
 *----------------------------------------------------------------------
3822
3823
3824
3825
3826
3827
3828
3829

3830
3831
3832
3833
3834

3835
3836
3837
3838
3839

3840
3841
3842
3843
3844
3845
3846
3847

3848
3849

3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867

3868
3869
3870
3871
3872
3873

3874
3875
3876
3877
3878
3879
3880
3881
3882
3883

3884
3885
3886
3887
3888
3889
3890
3891

3892
3893

3894
3895
3896
3897
3898
3899
3900
3823
3824
3825
3826
3827
3828
3829

3830
3831
3832
3833
3834

3835
3836
3837
3838
3839

3840
3841
3842
3843
3844
3845
3846
3847

3848
3849

3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867

3868
3869
3870
3871
3872
3873

3874
3875
3876
3877
3878
3879
3880
3881
3882
3883

3884
3885
3886
3887
3888
3889
3890
3891

3892
3893

3894
3895
3896
3897
3898
3899
3900
3901







-
+




-
+




-
+







-
+

-
+

















-
+





-
+









-
+







-
+

-
+







 *
 * ShouldBankerRoundUp --
 *
 *	Tests whether a digit should be rounded up or down when finishing
 *	bignum-based floating point conversion.
 *
 * Results:
 *	Returns 1 if the number needs to be rounded up, 0 otherwise.
 *	Returns true if the number needs to be rounded up, false otherwise.
 *
 *----------------------------------------------------------------------
 */

static inline int
static inline bool
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. */
    bool isodd)			/* Flag == 1 if the last digit is odd. */
{
    int r = mp_cmp_mag(twor, S);

    switch (r) {
    case MP_EQ:
	return isodd;
    case MP_GT:
	return 1;
	return true;
    default:
	return 0;
	return false;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ShouldBankerRoundUpToNext --
 *
 *	Tests whether the remainder is great enough to force rounding to the
 *	next higher digit.
 *
 * Results:
 *	Returns 1 if the number should be rounded up, 0 otherwise.
 *
 *----------------------------------------------------------------------
 */

static inline int
static inline bool
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 isodd)			/* 1 if the integer significand is odd. */
    bool isodd)			/* 1 if the integer significand is odd. */
{
    int r;
    mp_int temp;

    /*
     * Compare b and S-m: this is the same as comparing B+m and S.
     */

    if ((mp_init(&temp) != MP_OKAY) || (mp_add(b, m, &temp) != MP_OKAY)) {
	return 0;
	return false;
    }
    r = mp_cmp_mag(&temp, S);
    mp_clear(&temp);
    switch (r) {
    case MP_EQ:
	return isodd;
    case MP_GT:
	return 1;
	return true;
    default:
	return 0;
	return false;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ShorteningBignumConversion --
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4643
4644
4645
4646
4647
4648
4649






4650
4651
4652
4653
4654
4655
4656







-
-
-
-
-
-







 */

void
TclInitDoubleConversion(void)
{
    Tcl_WideUInt u;
    double d;
#ifdef IEEE_FLOATING_POINT
    union {
	double dv;
	Tcl_WideUInt iv;
    } bitwhack;
#endif
    mp_err err = MP_OKAY;
#if defined(__sgi) && defined(_COMPILER_VERSION)
    union fpc_csr mipsCR;

    mipsCR.fc_word = get_fpc_csr();
    mipsCR.fc_struct.flush = 0;
    set_fpc_csr(mipsCR.fc_word);
4742
4743
4744
4745
4746
4747
4748




4749
4750
4751
4752

4753
4754

4755
4756
4757
4758
4759
4760
4761
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750

4751
4752

4753
4754
4755
4756
4757
4758
4759
4760







+
+
+
+



-
+

-
+







     * Nokia 770's software-emulated floating point is "middle endian": the
     * bytes within a 32-bit word are little-endian (like the native
     * integers), but the two words of a 'double' are presented most
     * significant word first.
     */

#ifdef IEEE_FLOATING_POINT
    union {
	double dv;
	Tcl_WideUInt iv;
    } bitwhack;
    bitwhack.dv = 1.000000238418579;
				/* 3ff0 0000 4000 0000 */
    if ((bitwhack.iv >> 32) == 0x3FF00000) {
	n770_fp = 0;
	n770_fp = false;
    } else if ((bitwhack.iv & 0xFFFFFFFF) == 0x3FF00000) {
	n770_fp = 1;
	n770_fp = true;
    } else {
	Tcl_Panic("unknown floating point word order on this machine");
    }
#endif
}

/*
5000
5001
5002
5003
5004
5005
5006

5007

5008
5009
5010
5011
5012
5013
5014
4999
5000
5001
5002
5003
5004
5005
5006

5007
5008
5009
5010
5011
5012
5013
5014







+
-
+







	r = -TclFloor(&b);
    } else {
	int bits = mp_count_bits(a);

	if (bits > DBL_MAX_EXP*log2FLT_RADIX) {
	    r = HUGE_VAL;
	} else {
	    bool exact = true;
	    int exact = 1, shift = mantBits - bits;
	    int shift = mantBits - bits;

	    if (err != MP_OKAY) {
		/* just skip */
	    } else if (shift > 0) {
		err = mp_mul_2d(a, shift, &b);
	    } else if (shift < 0) {
		mp_int d;
5328
5329
5330
5331
5332
5333
5334
5335
5336


5337
5338
5339
5340
5341

5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5328
5329
5330
5331
5332
5333
5334


5335
5336
5337
5338
5339
5340

5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353







-
-
+
+




-
+












#endif

/*
 *----------------------------------------------------------------------
 *
 * TclNokia770Doubles --
 *
 *	Transpose the two words of a number for Nokia 770 floating point
 *	handling.
 *	Report whether the two words of a number need to be transposed for
 *	Nokia 770 floating point handling.
 *
 *----------------------------------------------------------------------
 */

int
bool
TclNokia770Doubles(void)
{
    return n770_fp;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */