       

' http://www.rit.edu/~meseec/eecc250-winter99/IEEE-754.html
     
#If 0
  February 1998
  This page was created by a Queens College undergraduate
  Quanfei Wen, a member of 
  www.pbk.org and "www.qc.edu/~upeqc. 
  "mailto:fei@mindspring.com" 

  
  September 1998
  The page was revised significantly by Kevin J. Brewer of
  Delco Electronics, who added several features and made significant 
  improvements in how well the JavaScript code adheres to the IEEE-754 
  standard. 
  c2xkjb@eng.delcoelect.com
  www.delphiauto.com/delco/delcoprod.html

              

  "IEEE-754hex32.html">Convert IEEE-754
  32-bit Hexadecimal Representations to Decimal Floating-Point Numbers. 
  
  "IEEE-754hex64.html">Convert IEEE-754
  64-bit Hexadecimal Representations to Decimal Floating-Point Numbers. 
  
  "IEEE-754references.html">Reference
  Material on the IEEE-754 Standard. 
  
  "babbage.cs.qc.edu/courses/cs341/index.html">CS-341 Home Page. 
  
  "babbage.cs.qc.edu/index.html">Dr. Vickery's Home Page.  
                                 


   Copyright (C)1997 Quanfei Wen.
   All Rights Reserved.

   Modifications by Kevin J. Brewer, 1998/08/20 to 1998/09/21

   - Corrected exponential ranges to those specified in IEEE-754.
   - Correction of decimal exponent field size.
   - Made correction so that decimal significand is displayed even when
     its value is 0.
   - decBinVal array sizes corrected for small values (those near 1.0*2**-126
     for 32-bit or 1.0*2**-1022 for 64-bit).
   - Corrected ieee32.Convert2Dec() to ieee64.Convert2Dec() in the ieee64
     section.
   - Added support for zero and unnormalized numbers (those less than
     1.0*2**-126 for 32-bit or 1.0*2**-1022 for 64-bit).
   - Modified significand input field to hold the notationally largest range
     input value (with the most significant digits, exponent, and signs),
     -4.94065645841246544E-324 .
   - Use only 1 set of intBinVal and decBinVal arrays so that 32-bit results
     will be marked invalid when 64-bit values greater than 3.40282347E38
     are entered.
   - Joined arrays intBinVal and decBinVal into one array, BinVal, in order
     to ease the manipulations involved in rounding.

   - Added IEEE-754 round-to-nearest value rounding mode.

   - Added input echo field which displays how the host machine sees the
     input value (round-off, number of significant digits, max and min
     exponentials, etc.).
   - For both precisions, added an echo field which displays the input value
     accurate to the number of bits in that precision's significand.
   - Added action so that when an input value overflows a precision, set that
     precision's outputs to the precision's Infinity values instead of having
     the bits be replaced by "#"s.
   - For both precisions, added a status field indicating from high to low:
     overflow, normal, unnormalized, underflow, and normal for zero.
   - Run Convert2Bin() only once per precision (not for each substring).
   - Added the ability to round or not to round by providing 2 activation
     buttons labeled as such.
   - Reduced exponent input field to hold up to the notationally largest
     exponent value (with the most significant digits and sign), -324, unless
     someone wants to oddly decimalize (add fractional/decimal parts to) the
     exponent.
   - Replaced calls to round() with tests and corrections for rounding up to
     calls to floor() which always rounds down.

   1998/09/28 to 1998/09/30

   - Made BinVal external to Convert2Bin (and therefore local to function ieee)
     as this.BinVal as is required in IEEE-754hex64.html and IEEE-754hex32.html
     so that Unix 'diff' has some chance at comparing this file with
     IEEE-754hex64.html or IEEE-754hex32.html .
   - General clean-ups.
   - Removed the optional "Exponent:" input field due to its problem of causing
     the entire input to underflow to zero when its value is -324, the problems
     encountered when trying to correct this deficiency programatically, and
     its superfluousness due to the ability of entering scientific notation
     (4.94065645841246544E-324) into the "Significand:" field alone.
   - Renamed the "Significand:" input field to "Decimal Floating-Point:".

   1998/10/06 to 1998/10/07

   - Added removal of input leading and trailing blanks by adding RemoveBlanks
     routine.
   - Added converting all floating-point inputs into canonical form (scientific
     notation, +x.xxE+xxxx form) with constant exponential width and plus sign
     usage by adding the Canonical routine, in order to simplify the string
     number comparisons involved in the 1.7976931348623157E+308 overflow check.
   - Found and corrected bug in both binary outputs created by some unknown
     JavaScript scoping problem for the symbol 'sOut' by introduction of the
     Canonical routine (never in a released version).

   - Floating-point input is now hand parsed and then its magnitude is compared
     against +1.7976931348623157E+00308 in the OvfCheck routine.  If the
     magnitude is greater than this value (compared as a string), set all
     outputs to the appropriate Infinity values.  The JavaScript implementation
     of IEEE-754 64-bit precision clips such values at 1.7976931348623157E+308.

   - Greatly improved the efficiency of the Convert2Hex routine.

   1998/10/20

   - Allow power of 10 indicator in numStrClipOff to be "E" as well as "e" in
     case not all browsers use "e".
   - Reordered 'numerals' in OvfCheck so that their index (value) is the same
     as that which the numeral represents.

   1998/10/23

   - With hand parsed floating-point input, compare its magnitude against
     +2.4703282292062328E-00324 in the UndfCheck routine.  If the magnitude is
     less than this value (compared as a string), set 'this.StatCond' to
     "underflow".  The JavaScript implementation of IEEE-754 64-bit precision
     underflows such values to zero.
   - The above required all settings of 'this.StatCond' to "normal" to have to
     be removed, "normal" rather than "error" is now the default.
   - With hand parsed input, set the output sign bit from its minus sign
     character before the input is turned into a numeric.  This supports input
     of negative zeros, "-0", and those values which underflow to it.

   1998/10/28

   - The central testing section of OvfCheck and UndfCheck were joined together
     as the single routine A_gt_B.
   - The translation which moves an input's base 10 exponential (the sign and
     value to the right of the "E") to its left end as its sign and most
     significant digits is now performed by the MostSigOrder routine.
   - Due to tests now involving negative exponentials in A_gt_B (via UndfCheck),
     a bias of 50,000 is added to all exponentials, when moved by MostSigOrder,
     in order to simplify numeric compares performed as iterative comparisons of
     individual digits in strings.

   1998/10/29

   - Floating-point input is now hand parsed, manipulated, and placed into the
     this.BinVal array only once by introduction of the Dec2Bin routine.
     As a result, the Convert2Bin routine now used is quite similar to that of
     IEEE-754hex64.html and IEEE-754hex32.html .

   32-bit:
     3.4028234663852886E+38   down to        (1.9999998 * 2**127)
     1.1754942807573643E-38   normalized     (1.0 * 2**-126)
     1.4012984643248170E-45   unnormalized   (1.0 * 2**-149)
    (7.0064923216240862E-46)       "         (1.0 * 2**-150)

   64-bit:
     1.7976931348623157E+308  down to        (1.9999999999999996 * 2**1023)
     2.2250738585072016E-308  normalized     (1.0 * 2**-1022)
     4.9406564584124654E-324  unnormalized   (1.0 * 2**-1074)
    (2.4703282292062328E-324)      "         (1.0 * 2**-1075)


                           Float Values (b = bias)

         Sign Exponent (e)  Mantissa (m)            Value
         ----------------------------------------------------------
                              11..11                Quiet
          1      11..11          :                  -NaN
                              10..01
         ----------------------------------------------------------
          1      11..11       10..00            Indeterminate
         ----------------------------------------------------------
                              01..11              Signaling
          1      11..11          :                  -NaN
                              00..01
         ----------------------------------------------------------
          1      11..11       00..00              -Infinity
         ----------------------------------------------------------
                 11..10       11..11      Negative Normalized Real
          1         :            :            -1.m * 2**(e-b)
                 00..01       00..00
         ----------------------------------------------------------
                              11..11     Negative Denormalized Real
          1      00..00          :            -0.m * 2**(-b+1)
                              00..01
         ----------------------------------------------------------
          1      00..00       00..00                 -0
         ----------------------------------------------------------
          0      00..00       00..00                 +0
         ----------------------------------------------------------
                              00..01     Positive Denormalized Real
          0      00..00          :             0.m * 2**(-b+1)
                              11..11
         ----------------------------------------------------------
                 00..01       00..00      Positive Normalized Real
          0         :            :             1.m * 2**(e-b)
                 11..10       11..11
         ----------------------------------------------------------
          0      11..11       00..00              +Infinity
         ----------------------------------------------------------
                              00..01              Signaling
          0      11..11          :                  +NaN
                              01..11
         ----------------------------------------------------------
                              10..00                Quiet
          0      11..11          :                  +NaN
                              11..11
         ----------------------------------------------------------


  In the following, 's' stands for the sign bit, 'e' stands for the exponent,
  and 'm' stands for the fractional part of the mantissa.  The symbol 'x' stands
  for a "don't care" bit (either a 0 or 1). 

For single-precision (32-bit) floating point numbers: 

        Type                  s (1 bit)   e (8 bits)    m (23 bits)
        ----                  ---------   ----------    -----------
        signaling NaN         x           255 (max)     .0xxxxx---x
                                                        (with at least
                                                         one 1 bit)

        quiet NaN             x           255 (max)     .1xxxxx---x

        Indeterminate         1           255 (max)     .100000---0

        negative infinity     1           255 (max)     .000000---0

        positive infinity     0           255 (max)     .000000---0

        negative zero         1           0             .000000---0

        positive zero         0           0             .000000---0


For double-precision (64-bit) floating point numbers:

        Type                  s (1 bit)   e (11 bits)   m (52 bits)
        ----                  ---------   -----------   -----------
        signaling NaN         x           2047 (max)    .0xxxxx---x
                                                        (with at least
                                                         one 1 bit)

        quiet NaN             x           2047 (max)    .1xxxxx---x

        Indeterminate         1           2047 (max)    .100000---0

        negative infinity     1           2047 (max)    .000000---0

        positive infinity     0           2047 (max)    .000000---0

        negative zero         1           0             .000000---0

        positive zero         0           0             .000000---0



#EndIf


FUNCTION Convert2Bin(outstring, statstring, signBit, power, rounding)
{
  sOut = NEW STRING()                  ' Output

  var binexpnt, index1, index2, cnst, bias, lastbit, rounded, index3, binexpnt2
  var moreBits

  cnst = 2102		 '  1 (carry bit) + 1023 + 1 + 1022 + 53 + 2 (round bits)
  bias = 1024

   ' init
  FOR (index1 = 0; index1 < this.SIZE; index1++)  this.Result[index1] = 0     

  WITH (Math) 					
  {
     ' sign bit
    this.Result[0] = signBit

     ' obtain exponent value
    index1 = 0

    IF (this.SIZE == 32) index2 = 9
    ELSE index2 = 12

    IF (rounding && (statstring == "normal"))
    {
       ' find most significant bit of significand
      WHILE ((index1 < cnst) && (this.BinVal[index1] != 1)) index1++

      binexpnt = bias - index1

       ' regular normalized numbers
      IF (binexpnt >= this.MinExp)
      {
				 ' the value is shifted until the most
        index1++		 ' significant 1 is to the left of the binary
				 ' point and that bit is implicit in the encoding
      } ' if normalized numbers

       ' support for zero and unnormalized numbers
       ' exponent underflow for this precision
      ELSE
      {
        binexpnt = this.MinExp - 1
        index1 = bias - binexpnt
      } ' if zero or unnormalized (else section)


       ' use round to nearest value mode

       ' compute least significant (low-order) bit of significand
      lastbit = this.SIZE - 1 - index2 + index1

       ' the bits folllowing the low-order bit have a value of (at least) 1/2
      IF (this.BinVal[lastbit + 1] == 1)
      {
        rounded = 0

         ' odd low-order bit
        IF (this.BinVal[lastbit] == 1)
        {
           ' exactly 1/2 the way between odd and even rounds up to the even,
           ' so the rest of the bits don't need to be checked to see if the value
           ' is more than 1/2 since the round up to the even number will occur
           ' anyway due to the 1/2
          rounded = 1
        } ' if odd low-order bit

         ' even low-order bit
        ELSE   ' this.BinVal[lastbit] == 0
        {
           ' exactly 1/2 the way between even and odd rounds down to the even,
           ' so the rest of the bits need to be checked to see if the value
           ' is more than 1/2 in order to round up to the odd number
          index3 = lastbit + 2
          WHILE ((rounded == 0) && (index3 < cnst))
          {
            rounded = this.BinVal[index3]
            index3++
          } ' while checking for more than 1/2

        } ' if even low-order bit (else section)

         ' do rounding "additions"
        index3 = lastbit
        WHILE ((rounded == 1) && (index3 >= 0))
        {
           '  0 + 1 -> 1 result with 0 carry
          IF (this.BinVal[index3] == 0)
          {
             '  1 result
            this.BinVal[index3] = 1

             '  0 carry
            rounded = 0

          } ' if bit is a 0

           '  1 + 1 -> 0 result with 1 carry
          ELSE   ' this.BinVal[index3] == 1
          {
             '  0 result
            this.BinVal[index3] = 0

             '  1 carry
 '           rounded = 1
          } ' if bit is a 1 (else section)

          index3--
        } ' while "adding" carries from right to left in bits

      } ' if at least 1/2

       ' obtain exponent value
      index1 = index1 - 2
      IF (index1 < 0) index1 = 0

    } ' if rounding

     ' find most significant bit of significand
    WHILE ((index1 < cnst) && (this.BinVal[index1] != 1)) index1++

    binexpnt2 = bias - index1

    IF (statstring == "normal")
    {
      binexpnt = binexpnt2

       ' regular normalized numbers
      IF ((binexpnt >= this.MinExp) && (binexpnt <= this.MaxExp))
      {
                                 ' the value is shifted until the most
        index1++                 ' significant 1 is to the left of the binary
                                 ' point and that bit is implicit in the encoding
      } ' if normalized numbers

       ' support for zero and unnormalized numbers
       ' exponent underflow for this precision
      ELSE IF (binexpnt < this.MinExp)
      {
        IF (binexpnt2 == bias - cnst)
           ' value is truely zero
          this.StatCond = "normal"
        ELSE IF (binexpnt2 < this.MinUnnormExp)
          this.StatCond = "underflow"
        ELSE
          this.StatCond = "unnormalized"

        binexpnt = this.MinExp - 1
        index1 = bias - binexpnt
      } ' if zero or unnormalized (else if section)
    }

    ELSE  ' already special values
    {
      binexpnt = power
      index1 = bias - binexpnt

      IF (binexpnt > this.MaxExp)
        binexpnt = this.MaxExp + 1

      ELSE IF (binexpnt < this.MinExp)
        binexpnt = this.MinExp - 1

    } ' if already special (else section)

     ' copy the result
    WHILE ((index2 < this.SIZE) && (index1 < cnst))
    {
      this.Result[index2] = this.BinVal[index1]
      index2++
      index1++
    } ' while

     ' max exponent for this precision
    IF ((binexpnt > this.MaxExp) || (statstring != "normal"))
    {
       ' overflow of this precision, set infinity
      IF (statstring == "normal")
      {
        binexpnt = this.MaxExp + 1
        this.StatCond = "overflow"
        this.DispStr = "Infinity"

        IF (this.Result[0] == 1)
          this.DispStr = "-" + this.DispStr

        IF (this.SIZE == 32) index2 = 9
        ELSE index2 = 12

         ' zero the significand
        WHILE (index2 < this.SIZE)
        {
          this.Result[index2] = 0
          index2++
        } ' while

      } ' if overflowed

      ELSE  ' already special values
      {
        this.StatCond = statstring
        this.DispStr = outstring
      } ' if already special (else section)

    } ' if max exponent

     ' convert exponent value to binary representation
    IF (this.SIZE == 32) index1 = 8
    ELSE index1 = 11
    this.BinaryPower = binexpnt
    binexpnt += this.ExpBias		 ' bias
    WHILE ((binexpnt / 2) != 0)
    {
      this.Result[index1] = binexpnt % 2
      IF (binexpnt % 2 == 0) binexpnt = binexpnt / 2
        ELSE binexpnt = binexpnt / 2 - 0.5
      index1 -= 1
    }

     ' output binary result
    sOut = ""
    FOR (index1 = 0; index1 < this.SIZE; index1++) 
      sOut = sOut + this.Result[index1]  
    RETURN sOut

  } ' with Math
}

FUNCTION Dec2Bin(INPUT)
{
  var value, intpart, decpart, binexpnt, index1, cnst, bias

  cnst = 2102		 '  1 (carry bit) + 1023 + 1 + 1022 + 53 + 2 (round bits)
  bias = 1024

   ' init
  FOR (index1 = 0; index1 < cnst; index1++)  this.BinVal[index1] = 0

  WITH (Math) 					
  {
    INPUT = Canonical(INPUT)

     ' sign bit
    IF (INPUT.charAt(0) == "-")
      this.Result[0] = 1
    ELSE
      this.Result[0] = 0

     ' if value magnitude greater than 1.7976931348623157E+308, set infinity
    INPUT = OvfCheck(INPUT)

    IF (INPUT.indexOf("Infinity") != -1)
    {
      binexpnt = this.MaxExp + 1
      this.StatCond64 = "overflow"
      this.DispStr = INPUT

    } ' if greater than 1.7976931348623157E+308

     ' Value magnitude is not greater than 1.7976931348623157E+308
    ELSE
    {

       ' if value magnitude less than 2.4703282292062328E-324, set "underflow".
      this.StatCond64 = UndfCheck(INPUT)

      IF (this.StatCond64 == "underflow")
      {
        binexpnt = this.MinExp - 1

      } ' if less than 2.4703282292062328E-324

       ' Value magnitude is not less than 2.4703282292062328E-324
      ELSE
      {

         ' convert 'input' from string to numeric
        INPUT = INPUT * 1.0

         ' convert and seperate input to integer and decimal parts
        value = ABS(INPUT)
        intpart = floor(value)
        decpart = value - intpart    

         ' convert integer part       
        index1 = bias			
        WHILE (((intpart / 2) != 0) && (index1 >= 0))
        {
          this.BinVal[index1] = intpart % 2
          IF (intpart % 2 == 0) intpart = intpart / 2
            ELSE intpart = intpart / 2 - 0.5
          index1 -= 1
        }  

         ' convert decimal part
        index1 = bias + 1
        WHILE ((decpart > 0) && (index1 < cnst))
        {
          decpart *= 2
          IF (decpart >= 1)
            {this.BinVal[index1] = 1; decpart --; index1++}
          ELSE {this.BinVal[index1] = 0; index1++}
        }         

         ' obtain exponent value
        index1 = 0

         ' find most significant bit of significand
        WHILE ((index1 < cnst) && (this.BinVal[index1] != 1)) index1++

        binexpnt = bias - index1

         ' support for zero and unnormalized numbers
         ' exponent underflow for this precision
        IF (binexpnt < this.MinExp)
        {
          binexpnt = this.MinExp - 1

        } ' if zero or unnormalized

      } ' if not less than 2.4703282292062328E-324 (else section)

    } ' if not greater than 1.7976931348623157E+308 (else section)

     ' output exponent value
    this.BinaryPower = binexpnt

  } ' with Math
}

FUNCTION Canonical(INPUT)
{
  sOut = NEW STRING()
  numerals = NEW STRING()
  expstr = NEW STRING()
  signstr = NEW STRING()
  expsignstr = NEW STRING()
  expstrtmp = NEW STRING()

  var locE, STOP, expnum, locDPact, locDP, start, MSDfound, index, expdelta
  var expstart, expprecision

  numerals = "0123456789";

  expprecision = 5

  INPUT = INPUT.toUpperCase()

  locE = INPUT.indexOf("E");
  IF (locE != -1)
  {
    STOP = locE
    expstr = INPUT.substring(locE + 1, INPUT.length)
    expnum = expstr * 1
  }
  ELSE
  {
    STOP = INPUT.length
    expnum = 0
  }

  locDPact = INPUT.indexOf(".");
  IF (locDPact != -1)
    locDP = locDPact
  ELSE
    locDP = STOP

  start = 0
  IF (INPUT.charAt(start) == "-")
  {
    start++
    signstr = "-"
  }
  ELSE IF (INPUT.charAt(start) == "+")
  {
    start++
    signstr = "+"
  }
  ELSE
    signstr = "+"

  MSDfound = false
  WHILE ((start < STOP) && !MSDfound)
  {
    index = 1
    WHILE (index < numerals.length)
    {
      IF (INPUT.charAt(start) == numerals.charAt(index))
      {
        MSDfound = true
        BREAK
      }
      index++
    }
    start++
  }
  start--

  IF (MSDfound)
  {
    expdelta = locDP - start
    IF (expdelta > 0)
      expdelta = expdelta - 1

    expnum = expnum + expdelta
  }
  ELSE   ' No significant digits found, value is zero
    expnum = 0

  expstrtmp = "" + expnum

  expstart = 0
  IF (expstrtmp.charAt(expstart) == "-")
  {
    expstart++
    expsignstr = "-"
  }
  ELSE
    expsignstr = "+"

  expstr = "E" + expsignstr

  index = 0
  WHILE (index < expprecision - expstrtmp.length + expstart)
  {
    expstr += "0"
    index++
  }

  expstr += expstrtmp.substring(expstart, expstrtmp.length)

  sOut = signstr

  IF (locDPact == start + 1) 
  {
    sOut += INPUT.substring(start, STOP)
  }
  ELSE IF (STOP == start + 1)
  {
    sOut += INPUT.substring(start, STOP)
    sOut += "."
  }
  ELSE IF (locDPact < start)
  {
    sOut += INPUT.substring(start, start + 1)
    sOut += "."
    sOut += INPUT.substring(start + 1, STOP)
  }
  ELSE IF (locDPact != -1)
  {
    sOut += INPUT.substring(start, start + 1)
    sOut += "."
    sOut += INPUT.substring(start + 1, locDPact)
    sOut += INPUT.substring(locDPact + 1, STOP)
  }
  ELSE
  {
    sOut += INPUT.substring(start, STOP)
    sOut += "."
  }

  sOut += expstr

  RETURN sOut;
}

FUNCTION MostSigOrder(INPUT)
{
  sOut = NEW STRING()
  expstr = NEW STRING()

  var expprecision, expbias, STOP, expnum, index

  expprecision = 5
  expbias = 50000

  STOP = INPUT.indexOf("E");

  sOut = INPUT.substring(STOP + 1, INPUT.length)
  expnum = sOut * 1
  expnum += expbias

  expstr = "" + expnum

  sOut = expstr

  index = 0
  WHILE (index < expprecision - expstr.length)
  {
    sOut = "0" + sOut
    index++
  }

  sOut += INPUT.substring(1, 2)
  sOut += INPUT.substring(3, STOP)

  RETURN sOut;
}

FUNCTION A_gt_B(A, B)
{
  numerals = NEW STRING()

  var greater, STOP, index, Adigit, Bdigit

  numerals = "0123456789";

  greater = false

  IF (A.length > B.length)
    STOP = A.length
  ELSE
    STOP = B.length

  index = 0
  WHILE (index < STOP)
  {
    IF (index < A.length)
      Adigit = numerals.indexOf(A.charAt(index))
    ELSE
      Adigit = 0

    IF (index < B.length)
      Bdigit = numerals.indexOf(B.charAt(index))
    ELSE
      Bdigit = 0

    IF (Adigit < Bdigit)
      BREAK
    ELSE IF (Adigit > Bdigit)
    {
      greater = true
      BREAK
    }

    index++
  } ' end while

  RETURN greater;
}

FUNCTION OvfCheck(INPUT)
{
  sOut = NEW STRING()

   ' Is value magnitude greater than +1.7976931348623157E+00308
  IF (A_gt_B(MostSigOrder(INPUT), "5030817976931348623157"))
  {
    sOut = "Infinity"
    IF (INPUT.charAt(0) == "-")
      sOut = "-" + sOut
  }
  ELSE
    sOut = INPUT

  RETURN sOut;
}

FUNCTION UndfCheck(INPUT)
{
  sOut = NEW STRING()

   ' Is value magnitude less than +2.4703282292062328E-00324
  IF (A_gt_B("4967624703282292062328", MostSigOrder(INPUT)))
    sOut = "underflow"
  ELSE
    sOut = "normal"

  RETURN sOut;
}

FUNCTION RemoveBlanks(INPUT)
{
  sOut = NEW STRING()

  var start, STOP

  start = 0
  WHILE ((INPUT.charAt(start) == " ") && (start < INPUT.length))
    start++

  STOP = INPUT.length - 1
  WHILE ((INPUT.charAt(STOP) == " ") && (STOP >= 0))
    STOP--

  sOut = INPUT.substring(start, STOP + 1)

  RETURN sOut
}

FUNCTION Convert2Hex()
{
  sOut = NEW STRING()
  numerals = NEW STRING()

  var temp, index, i

  numerals = "0123456789ABCDEF"

  WITH (Math)
  {
     ' convert binary result to hex and sOut
    FOR (index = 0; index < this.SIZE; index +=4)
    {
      temp = 0
      FOR (i = 0; i < 4; i++)
        temp += pow(2, 3 - i)*this.Result[index + i]

      sOut = sOut + numerals.charAt(temp)
    }
  }
  RETURN sOut
}

FUNCTION numStrClipOff(INPUT, precision)
{
  result = NEW STRING()
  numerals = NEW STRING()

  var locE, STOP, count, index, index2

  numerals = "0123456789";

  locE = INPUT.indexOf("e");
  IF (locE != -1)
    STOP = locE
  ELSE
  {
    locE = INPUT.indexOf("E");
    IF (locE != -1)
      STOP = locE
    ELSE
      STOP = INPUT.length
  }

  count = 0
  index = 0
  WHILE ((count < precision) && (index < STOP))
  {
    index2 = 0
    WHILE (index2 < numerals.length)
    {
      IF (INPUT.charAt(index) == numerals.charAt(index2))
        count += 1
      index2++
    }
    index++
  }

  result = INPUT.substring(0, index)

  IF (INPUT.indexOf(".") == -1)
    result += "."

  count = count + 1
  WHILE (count <= precision)
  {
    result += "0"
    count += 1
  }

  IF (INPUT.length != STOP)
    result += INPUT.substring(locE, INPUT.length)

  RETURN result;
}

FUNCTION numCutOff(INPUT, precision)
{
  result = NEW STRING()
  tempstr = NEW STRING()

  var temp = INPUT;
  IF(temp < 1)
    temp += 1;

  tempstr = "" + temp;

  tempstr = numStrClipOff(tempstr, precision);

  IF(temp == INPUT)
    result = tempstr.substring(0, 1);
  ELSE
    result = "0";

  result += tempstr.substring(1, tempstr.length);

  RETURN result;
}

FUNCTION Convert2Dec()
{
  sOut = NEW STRING()

  var s, i, dp, VAL, hid, temp, decValue, power

  WITH (Math)
  {
  IF (this.SIZE == 32) s = 9
  ELSE s = 12

  IF ((this.BinaryPower < this.MinExp) || (this.BinaryPower > this.MaxExp))
  {
    dp = 0
    VAL = 0
  }
  ELSE
  {
    dp = - 1
    VAL = 1
  }

  FOR (i = s; i < this.SIZE; i++)
    VAL += parseInt(this.Result[i])*pow(2, dp + s - i)

  decValue = VAL * pow(2, this.BinaryPower)

  IF (this.SIZE == 32)
  {
    s = 8
    power = floor( LOG(decValue) / LN10 )
    decValue += 0.5 * pow(10, power - s + 1)
  }
  ELSE s = 17

  IF (this.Result[0] == 1) decValue = - decValue

   ' the system refuses to display negative "0"s with a minus sign
  this.DecValue = "" + decValue
  IF ((this.DecValue == "0") && (this.Result[0] == 1))
    this.DecValue = "-" + this.DecValue

  this.DecValue = numStrClipOff(this.DecValue, s)

  sOut = numCutOff(VAL, s)

  } 
  RETURN sOut
}

 ' object construction function
FUNCTION ieee (SIZE){

  this.SIZE = SIZE
  this.BinaryPower = 0
  this.DecValue = ""
  this.DispStr = ""
  this.Convert2Bin = Convert2Bin    ' convert input to bin.
  this.Convert2Hex = Convert2Hex    ' convert bin. to hex.
  this.Convert2Dec = Convert2Dec    ' convert bin. significand to dec.
  this.Dec2Bin = Dec2Bin            ' convert dec. to bin.
  this.StatCond = "normal"
  this.StatCond64 = "normal"
  this.BinString = ""
   '  1 (carry bit) + 1023 + 1 + 1022 + 53 + 2 (round bits)
  this.BinVal = NEW ARRAY(2102)     ' Binary Representation
  IF (SIZE == 32){
    this.ExpBias = 127
    this.MaxExp = 127
    this.MinExp = -126
    this.MinUnnormExp = -149
    this.Result = NEW ARRAY(32)
  }
  ELSE IF (SIZE == 64){
    this.ExpBias = 1023
    this.MaxExp = 1023
    this.MinExp = -1022
    this.MinUnnormExp = -1074
    this.Result = NEW ARRAY(64)
  }

}

FUNCTION compute(obj, rounding){

'  in this javascript program, bit positions are numbered 
'  0 ~ 32/64 from left to right instead of right to left, the
'  way the output is presented

  ieee32 = NEW ieee(32)
  ieee64 = NEW ieee(64)

  var INPUT, index1, cnst

  INPUT = obj.INPUT.value
  INPUT = RemoveBlanks(INPUT)

  ieee64.Dec2Bin(INPUT)
  ieee64.BinString =
    ieee64.Convert2Bin(ieee64.DispStr, ieee64.StatCond64, ieee64.Result[0],
                         ieee64.BinaryPower, false)
  obj.bin64_0.value = ieee64.BinString.substring(0, 1)
  obj.bin64_1.value = ieee64.BinString.substring(1, 12)
  IF ((ieee64.BinaryPower < ieee64.MinExp) ||
      (ieee64.BinaryPower > ieee64.MaxExp))
  {
    obj.bin64_12.value = "  "
    obj.bin64_12.value += ieee64.BinString.substring(12, 13)
    obj.bin64_12.value += "."
    obj.bin64_12.value += ieee64.BinString.substring(13, 64)
  }
  ELSE
  {
    obj.bin64_12.value = "1 ."
    obj.bin64_12.value += ieee64.BinString.substring(12, 64)
  }
  obj.stat64.value = ieee64.StatCond
  obj.binpwr64.value = ieee64.BinaryPower
  obj.binpwr64f.value = ieee64.BinaryPower + ieee64.ExpBias
  obj.dec64sig.value = ieee64.Convert2Dec()
  IF (ieee64.DispStr != "")
  {
    obj.dec64.value = ieee64.DispStr
    obj.dec64sig.value = ""
  }
  ELSE
    obj.dec64.value = ieee64.DecValue
  obj.hex64.value = ieee64.Convert2Hex()

    cnst = 2102          '  1 (carry bit) + 1023 + 1 + 1022 + 53 + 2 (round bits)
    FOR (index1 = 0; index1 < cnst; index1++)
      ieee32.BinVal[index1] = ieee64.BinVal[index1]

  ieee32.BinString =
    ieee32.Convert2Bin(ieee64.DispStr, ieee64.StatCond64, ieee64.Result[0],
                         ieee64.BinaryPower, rounding)
  obj.bin32_0.value = ieee32.BinString.substring(0, 1)
  obj.bin32_1.value = ieee32.BinString.substring(1, 9)
  IF ((ieee32.BinaryPower < ieee32.MinExp) ||
      (ieee32.BinaryPower > ieee32.MaxExp))
  {
    obj.bin32_9.value = "  "
    obj.bin32_9.value += ieee32.BinString.substring(9, 10)
    obj.bin32_9.value += "."
    obj.bin32_9.value += ieee32.BinString.substring(10, 32)
  }
  ELSE
  {
    obj.bin32_9.value = "1 ."
    obj.bin32_9.value += ieee32.BinString.substring(9, 32)
  }
  obj.stat32.value = ieee32.StatCond
  obj.binpwr32.value = ieee32.BinaryPower
  obj.binpwr32f.value = ieee32.BinaryPower + ieee32.ExpBias
  obj.dec32sig.value = ieee32.Convert2Dec()
  IF (ieee32.DispStr != "")
  {
    obj.dec32.value = ieee32.DispStr
    obj.dec32sig.value = ""
  }
  ELSE
    obj.dec32.value = ieee32.DecValue
  obj.hex32.value = ieee32.Convert2Hex()

  IF ((ieee64.DispStr != "") && (ieee32.DispStr != ""))
    obj.entered.value = ieee64.DispStr
  ELSE
    obj.entered.value = INPUT * 1.0
} 







'  From Decimal Floating-Point
'  To 32-bit and 64-bit Hexadecimal Representations
'  Along with Their Binary Equivalents
  
'  Enter a decimal floating-point number here,
'  then click either the Rounded or the Not Rounded button.

'  Decimal Floating-Point: <input type="text" name="input" size=25>

'  <input type="button" value="Rounded" onClick="compute(this.form, true)">
'  <input type="button" value="Not Rounded" onClick="compute(this.form, false)">

'  Rounding from floating-point to 32-bit representation uses the IEEE-754
'  round-to-nearest-value mode.

'  Results:
'  Decimal Value Entered:
'  <input type="text" name="entered" size=24>

'  Single precision (32 bits):
'  Binary:Status:
'  <input type="text" name="stat32" size=12>

'  Bit 31 
'  Sign Bit 
'  <input type="text" name="bin32_0" size=1>
'  0: +
'  1: -

'  Bits 30 - 23
'  Exponent 
'  <input type="text" name="bin32_1" size=8>
'  Decimal value of the exponent
'  127 + <input type="text" name="binpwr32" size=4> = <input type="text" name="binpwr32f" size=3>

'  Bits 22 - 0
'  Significand
'  <input type="text" name="bin32_9" size=26>
'  Decimal value of the significand
'  <input type="text" name="dec32sig" size=9>
 
'  Hexadecimal:
'  <input type="text" name="hex32" size=8>
'  Decimal:
'  <input type="text" name="dec32" size=14>
 
'  Double precision (64 bits):
'  Binary:Status:
'  <input type="text" name="stat64" size=12>
'  <TABLE BORDER=1 CELLSPACING=1 CELLPADDING=5 ><tr align = center> 
'  Bit 63
'  Sign Bit 
'  <input type="text" name="bin64_0" size=1>
'  0: +
'  1: -

'  Bits 62 - 52
'  Exponent 
'  <input type="text" name="bin64_1" size=11>
'  Decimal value of the exponent
'  1023 + <input type="text" name="binpwr64" size=5> = <input type="text" name="binpwr64f" size=4>

'  Bits 51 - 0
'  Significand
'  <input type="text" name="bin64_12" size=55>
'  Decimal value of the significand
'  <input type="text" name="dec64sig" size=18>

'  Hexadecimal:
'  <input type="text" name="hex64" size=16>
'  Decimal:
'  <input type="text" name="dec64" size=24>

