@@ -2384,94 +2384,43 @@ public double ToDouble() {
23842384 }
23852385 return Extras .IntegersToDouble (nan );
23862386 }
2387- if (this .isNegative () && this .isZero ()) {
2388- return Extras .IntegersToDouble (new int [] { 0 , ((int )(1 << 31 )) });
2389- }
2390- EInteger bigmant = this .unsignedMantissa .Abs ();
2391- FastInteger bigexponent = FastInteger .FromBig (this .exponent );
2392- int bitLeftmost = 0 ;
2393- int bitsAfterLeftmost = 0 ;
2394- if (this .unsignedMantissa .isZero ()) {
2395- return 0.0d ;
2387+ EFloat thisValue = this .RoundToPrecision (EContext .Binary64 );
2388+ if (!thisValue .isFinite ()) {
2389+ return thisValue .ToDouble ();
23962390 }
2397- int [] mantissaBits ;
2398- if (bigmant .compareTo (ValueOneShift52 ) < 0 ) {
2399- mantissaBits = FastInteger .GetLastWords (bigmant , 2 );
2400- // This will be an infinite loop if both elements
2401- // of the bits array are 0, but the check for
2402- // 0 was already done above
2403- while (!NumberUtility .HasBitSet (mantissaBits , 52 )) {
2404- NumberUtility .ShiftLeftOne (mantissaBits );
2405- bigexponent .Decrement ();
2406- }
2407- } else {
2408- BitShiftAccumulator accum = new BitShiftAccumulator (bigmant , 0 , 0 );
2409- accum .ShiftToDigitsInt (53 );
2410- bitsAfterLeftmost = accum .getOlderDiscardedDigits ();
2411- bitLeftmost = accum .getLastDiscardedDigit ();
2412- bigexponent .Add (accum .getDiscardedDigitCount ());
2413- mantissaBits = FastInteger .GetLastWords (accum .getShiftedInt (), 2 );
2414- }
2415- // Round half-even
2416- if (bitLeftmost > 0 && (bitsAfterLeftmost > 0 ||
2417- NumberUtility .HasBitSet (mantissaBits , 0 ))) {
2418- // Add 1 to the bits
2419- mantissaBits [0 ] = ((int )(mantissaBits [0 ] + 1 ));
2420- if (mantissaBits [0 ] == 0 ) {
2421- mantissaBits [1 ] = ((int )(mantissaBits [1 ] + 1 ));
2422- }
2423- if (mantissaBits [0 ] == 0 &&
2424- mantissaBits [1 ] == (1 << 21 )) { // if mantissa is now 2^53
2425- mantissaBits [1 ] >>= 1 ; // change it to 2^52
2426- bigexponent .Increment ();
2427- }
2391+ EInteger mant = thisValue .unsignedMantissa ;
2392+ if (thisValue .isNegative () && mant .isZero ()) {
2393+ return Extras .IntegersToDouble (new int [] { 0 , ((int )(1 << 31 )) });
2394+ } else if (mant .isZero ()) {
2395+ return 0.0 ;
24282396 }
2397+ // DebugUtility.Log("-->" + (//
2398+ // thisValue.unsignedMantissa.ToRadixString(2)) + ", " + (//
2399+ // thisValue.exponent));
2400+ int bitLength = mant .GetUnsignedBitLength ();
2401+
2402+ int expo = thisValue .exponent .ToInt32Checked ();
24292403 boolean subnormal = false ;
2430- if (bigexponent .CompareToInt (971 ) > 0 ) {
2431- // exponent too big
2432- return this .isNegative () ? Double .NEGATIVE_INFINITY :
2433- Double .POSITIVE_INFINITY ;
2434- }
2435- if (bigexponent .CompareToInt (-1074 ) < 0 ) {
2436- // subnormal
2437- subnormal = true ;
2438- // Shift while number remains subnormal
2439- BitShiftAccumulator accum = new BitShiftAccumulator (
2440- FastInteger .WordsToEInteger (mantissaBits ),
2441- 0 ,
2442- 0 );
2443- FastInteger fi = bigexponent .Copy ().SubtractInt (-1074 ).Abs ();
2444- accum .ShiftRight (fi );
2445- bitsAfterLeftmost = accum .getOlderDiscardedDigits ();
2446- bitLeftmost = accum .getLastDiscardedDigit ();
2447- bigexponent .Add (accum .getDiscardedDigitCount ());
2448- mantissaBits = FastInteger .GetLastWords (accum .getShiftedInt (), 2 );
2449- // Round half-even
2450- if (bitLeftmost > 0 && (bitsAfterLeftmost > 0 ||
2451- NumberUtility .HasBitSet (mantissaBits , 0 ))) {
2452- // Add 1 to the bits
2453- mantissaBits [0 ] = ((int )(mantissaBits [0 ] + 1 ));
2454- if (mantissaBits [0 ] == 0 ) {
2455- mantissaBits [1 ] = ((int )(mantissaBits [1 ] + 1 ));
2456- }
2457- if (mantissaBits [0 ] == 0 &&
2458- mantissaBits [1 ] == (1 << 21 )) { // if mantissa is now 2^53
2459- mantissaBits [1 ] >>= 1 ; // change it to 2^52
2460- bigexponent .Increment ();
2461- }
2404+ if (bitLength < 53 ) {
2405+ int diff = 53 - bitLength ;
2406+ expo -= diff ;
2407+ if (expo < -1074 ) {
2408+ // DebugUtility.Log("Diff changed from " + diff + " to " + (diff -
2409+ // (-1074 - expo)));
2410+ diff -= -1074 - expo ;
2411+ expo = -1074 ;
2412+ subnormal = true ;
24622413 }
2414+ mant = mant .ShiftLeft (diff );
2415+ bitLength += diff ;
24632416 }
2464- if (bigexponent .CompareToInt (-1074 ) < 0 ) {
2465- // exponent too small, so return zero
2466- return this .isNegative () ?
2467- Extras .IntegersToDouble (new int [] { 0 , ((int )0x80000000 ) }) :
2468- 0.0d ;
2469- }
2470- bigexponent .AddInt (1075 );
2417+ // DebugUtility.Log("2->" + (mant.ToRadixString(2)) + ", " + expo);
2418+ int [] mantissaBits ;
2419+ mantissaBits = FastInteger .GetLastWords (mant , 2 );
24712420 // Clear the high bits where the exponent and sign are
24722421 mantissaBits [1 ] &= 0xfffff ;
24732422 if (!subnormal ) {
2474- int smallexponent = bigexponent . AsInt32 ( ) << 20 ;
2423+ int smallexponent = ( expo + 1075 ) << 20 ;
24752424 mantissaBits [1 ] |= smallexponent ;
24762425 }
24772426 if (this .isNegative ()) {
@@ -2728,89 +2677,45 @@ public float ToSingle() {
27282677 }
27292678 return Float .intBitsToFloat (nan );
27302679 }
2731- if (this .isNegative () && this .isZero ()) {
2732- return Float .intBitsToFloat (1 << 31 );
2680+ EFloat thisValue = this .RoundToPrecision (EContext .Binary32 );
2681+ if (!thisValue .isFinite ()) {
2682+ return thisValue .ToSingle ();
27332683 }
2734- EInteger bigmant = this .unsignedMantissa .Abs ();
2735- FastInteger bigexponent = FastInteger .FromBig (this .exponent );
2736- int bitLeftmost = 0 ;
2737- int bitsAfterLeftmost = 0 ;
2738- if (this .unsignedMantissa .isZero ()) {
2684+ EInteger mant = thisValue .unsignedMantissa ;
2685+ if (thisValue .isNegative () && mant .isZero ()) {
2686+ return Float .intBitsToFloat (1 << 31 );
2687+ } else if (mant .isZero ()) {
27392688 return 0.0f ;
27402689 }
2741- int smallmant = 0 ;
2742- FastInteger fastSmallMant ;
2743- if (bigmant .compareTo (ValueOneShift23 ) < 0 ) {
2744- smallmant = bigmant .AsInt32Checked ();
2745- int exponentchange = 0 ;
2746- while (smallmant < (1 << 23 )) {
2747- smallmant <<= 1 ;
2748- ++exponentchange ;
2749- }
2750- bigexponent .SubtractInt (exponentchange );
2751- fastSmallMant = new FastInteger (smallmant );
2752- } else {
2753- BitShiftAccumulator accum = new BitShiftAccumulator (bigmant , 0 , 0 );
2754- accum .ShiftToDigitsInt (24 );
2755- bitsAfterLeftmost = accum .getOlderDiscardedDigits ();
2756- bitLeftmost = accum .getLastDiscardedDigit ();
2757- bigexponent .Add (accum .getDiscardedDigitCount ());
2758- fastSmallMant = accum .getShiftedIntFast ();
2759- }
2760- // Round half-even
2761- if (bitLeftmost > 0 && (bitsAfterLeftmost > 0 ||
2762- !fastSmallMant .isEvenNumber ())) {
2763- fastSmallMant .Increment ();
2764- if (fastSmallMant .CompareToInt (1 << 24 ) == 0 ) {
2765- fastSmallMant = new FastInteger (1 << 23 );
2766- bigexponent .Increment ();
2767- }
2768- }
2690+ // DebugUtility.Log("-->" + (//
2691+ // thisValue.unsignedMantissa.ToRadixString(2)) + ", " + (//
2692+ // thisValue.exponent));
2693+ int bitLength = mant .GetUnsignedBitLength ();
2694+
2695+ int expo = thisValue .exponent .ToInt32Checked ();
27692696 boolean subnormal = false ;
2770- if (bigexponent .CompareToInt (104 ) > 0 ) {
2771- // exponent too big
2772- return this .isNegative () ? Float .NEGATIVE_INFINITY :
2773- Float .POSITIVE_INFINITY ;
2774- }
2775- if (bigexponent .CompareToInt (-149 ) < 0 ) {
2776- // subnormal
2777- subnormal = true ;
2778- // Shift while number remains subnormal
2779- BitShiftAccumulator accum =
2780- BitShiftAccumulator .FromInt32 (fastSmallMant .AsInt32 ());
2781- FastInteger fi = bigexponent .Copy ().SubtractInt (-149 ).Abs ();
2782- accum .ShiftRight (fi );
2783- bitsAfterLeftmost = accum .getOlderDiscardedDigits ();
2784- bitLeftmost = accum .getLastDiscardedDigit ();
2785- bigexponent .Add (accum .getDiscardedDigitCount ());
2786- fastSmallMant = accum .getShiftedIntFast ();
2787- // Round half-even
2788- if (bitLeftmost > 0 && (bitsAfterLeftmost > 0 ||
2789- !fastSmallMant .isEvenNumber ())) {
2790- fastSmallMant .Increment ();
2791- if (fastSmallMant .CompareToInt (1 << 24 ) == 0 ) {
2792- fastSmallMant = new FastInteger (1 << 23 );
2793- bigexponent .Increment ();
2794- }
2697+ if (bitLength < 24 ) {
2698+ int diff = 24 - bitLength ;
2699+ expo -= diff ;
2700+ if (expo < -149 ) {
2701+ // DebugUtility.Log("Diff changed from " + diff + " to " + (diff -
2702+ // (-149 - expo)));
2703+ diff -= -149 - expo ;
2704+ expo = -149 ;
2705+ subnormal = true ;
27952706 }
2707+ mant = mant .ShiftLeft (diff );
2708+ bitLength += diff ;
27962709 }
2797- if (bigexponent .CompareToInt (-149 ) < 0 ) {
2798- // exponent too small, so return zero
2799- return this .isNegative () ?
2800- Float .intBitsToFloat (1 << 31 ) :
2801- Float .intBitsToFloat (0 );
2802- } else {
2803- int smallexponent = bigexponent .AsInt32 ();
2804- smallexponent += 150 ;
2805- int smallmantissa = ((int )fastSmallMant .AsInt32 ()) & 0x7fffff ;
2806- if (!subnormal ) {
2807- smallmantissa |= smallexponent << 23 ;
2808- }
2809- if (this .isNegative ()) {
2710+ // DebugUtility.Log("2->" + (mant.ToRadixString(2)) + ", " + expo);
2711+ int smallmantissa = ((int )mant .ToInt32Checked ()) & 0x7fffff ;
2712+ if (!subnormal ) {
2713+ smallmantissa |= (expo + 150 ) << 23 ;
2714+ }
2715+ if (this .isNegative ()) {
28102716 smallmantissa |= 1 << 31 ;
2811- }
2812- return Float .intBitsToFloat (smallmantissa );
28132717 }
2718+ return Float .intBitsToFloat (smallmantissa );
28142719 }
28152720
28162721 /**
0 commit comments