Decimal Arithmetic Specification, version 1.07 Copyright (c) IBM Corporation, 2002. All rights reserved. © | 6 Nov 2002
[previous | contents | next]

# Conversions

This section defines the required conversions between the abstract representation of numbers and string (character) form.[1] Two number-to-string conversions and one string-to-number conversion are defined.

It is recommended that implementations also provide conversions to and from binary floating-point or integer numbers, if appropriate (that is, if such encodings are supported in the environment of the implementation). It is suggested that such conversions be exact, if possible (that is, when converting from binary to decimal), or alternatively give the same results as converting using an appropriate string representation as an intermediate form. It is also recommended that if a number is too large to be converted to a given binary integer format then an exceptional or error condition be raised, rather than losing high-order significant bits (decapitating).

It is recommended that implementations also provide additional number formatting routines (including some which are locale-dependent), and if available should accept non-Arabic decimal digits in strings.

Notes:

1. The setting of precision may be used to convert a number from any precision to any other precision, using the plus operation. This meets the requirements of IEEE 854 §5.3.
2. Integers are a proper subset of numbers, hence no conversion operation from an integer to a number is necessary. Conversion from a number to an integer is effected by using the round-to-integer operation. This meets the requirements of IEEE 854 §5.4 and §5.5.

### Numeric string syntax

Strings which are acceptable for conversion to the abstract representation of numbers, or which might result from conversion from the abstract representation to a string, are called numeric strings.

A numeric string is a character string that describes either a finite number or a special value.

- If it describes a finite number, it includes one or more decimal digits, with an optional decimal point. The decimal point may be embedded in the digits, or may be prefixed or suffixed to them. The group of digits (and optional point) thus constructed may have an optional sign (`+` or `-`) which must come before any digits or decimal point.
  The string thus described may optionally be followed by an `E` (indicating an exponential part), an optional sign, and an integer following the sign that represents a power of ten that is to be applied. The `E` may be in uppercase or lowercase.
- If it describes a special value, it is one of the case-independent names `Infinity`, `Inf`, `NaN`, or `sNaN` (where the first two represent infinity and may be preceded by an optional sign, as for finite numbers, and the second two represent quiet NaN and signaling NaN respectively).

No blanks or other white space characters are permitted in a numeric string.

Formally:[2]

      sign           ::=  '+' | '-'
      digit          ::=  '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
      indicator      ::=  'e' | 'E'
      digits         ::=  digit [digit]...
      decimal-part   ::=  digits '.' [digits] | ['.'] digits
      exponent-part  ::=  indicator [sign] digits
      infinity       ::=  'Infinity' | 'Inf'
      nan            ::=  'NaN' | 'sNaN'
      numeric-value  ::=  decimal-part [exponent-part] | infinity
      numeric-string ::=  [sign] numeric-value | nan

where the characters in the strings accepted for `infinity` and `nan` may be in any case.

Examples:

Some numeric strings are:

           "0"         -- zero
          "12"         -- a whole number
         "-76"         -- a signed whole number
          "12.70"      -- some decimal places
          "+0.003"     -- a plus sign is allowed, too
         "017."        -- the same as 17
            ".5"       -- the same as 0.5
          "4E+9"       -- exponential notation
           "0.73e-7"   -- exponential notation, negative power
          "Inf"        -- the same as Infinity
          "-infinity"  -- the same as -Inf
          "NaN"        -- not-a-Number

Notes:

1. A single period alone or with a sign is not a valid numeric string.
2. A sign alone is not a valid numeric string.
3. Leading zeros are permitted.

### to-scientific-string conversion to numeric string

This operation converts a number to a string, using scientific notation if an exponent is needed. The operation is not affected by the context.

If the number is a finite number then:

- The coefficient is first converted to a string in base ten using the characters 0 through 9 with no leading zeros (except if its value is zero, in which case a single 0 character is used).
  Next, the adjusted exponent is calculated; this is the exponent, plus the number of characters in the converted coefficient, less one. That is, exponent`+`(`clength``-`1), where `clength` is the length of the coefficient in decimal digits.
  If the exponent is less than or equal to zero and the adjusted exponent is greater than or equal to `-`6, the number will be converted to a character form without using exponential notation. In this case, if the exponent is zero then no decimal point is added. Otherwise (the exponent will be negative), a decimal point will be inserted with the absolute value of the exponent specifying the number of characters to the right of the decimal point. 0 characters are added to the left of the converted coefficient as necessary. If no character precedes the decimal point after this insertion then a conventional 0 character is prefixed.
  Otherwise (that is, if the exponent is positive, or the adjusted exponent is less than `-`6), the number will be converted to a character form using exponential notation. In this case, if the converted coefficient has more than one digit a decimal point is inserted after the first digit. An exponent in character form is then suffixed to the converted coefficient (perhaps with inserted decimal point); this comprises the letter `E` followed immediately by the adjusted exponent converted to a character form. The latter is in base ten, using the characters 0 through 9 with no leading zeros, always prefixed by a sign character (`-` if the calculated exponent is negative, `+` otherwise).
  Finally, the entire string is prefixed by a minus sign character[3] (`-`) if sign is 1. No sign character is prefixed if sign is 0.

Otherwise (the number is a special value):

- If the special value is quiet NaN then the resulting string is `NaN`.
- If the special value is signaling NaN then the resulting string is `sNaN`.[4]
- If the special value is infinity then the resulting string is `Infinity`. In this case, if the sign of the number is 1 then the string is preceded by a character. Otherwise (the sign is is 0) no sign character is prefixed.

Examples:

For each abstract representation [sign, coefficient, exponent] or [sign, special-value] on the left, the resulting string is shown on the right.

      [0,123,0]       "123"
      [1,123,0]       "-123"
      [0,123,1]       "1.23E+3"
      [0,123,3]       "1.23E+5"
      [0,123,-1]      "12.3"
      [0,123,-5]      "0.00123"
      [0,123,-10]     "1.23E-8"
      [1,123,-12]     "-1.23E-10"
      [0,0,0]         "0"
      [0,0,-2]        "0.00"
      [0,0,2]         "0E+2"
      [1,0,0]         "-0"
      [0,inf]         "Infinity"
      [1,inf]         "-Infinity"
      [0,qNaN]        "NaN"
      [0,sNaN]        "sNaN"

Notes:

1. There is a one-to-one mapping between abstract representations and the result of this conversion. That is, every abstract representation has a unique to-scientific-string representation. Also, if that string representation is converted back to an abstract representation using to-number with sufficient precision, then the original abstract representation will be recovered.
   This one-to-one mapping guarantees that there is no hidden information in the internal representation of the numbers (what you see is exactly what you've got).
2. The values quiet NaN and signaling NaN are distinguished in string form in order to preserve the one-to-one mapping just described. The strings chosen are those currently under consideration by the IEEE 754 review committee.
3. The digits required for an exponent may be more than the number of digits required for Emax when a finite number is subnormal.
4. IEEE 854 allows additional information to be suffixed to the string representation of special values. Any such suffixes are not permitted by this specification (again, to preserve the one-to-one mapping). It is suggested that if additional information is held in a concrete representation then a separate mechanism or operation is provided for accessing that information.

### to-engineering-string conversion to numeric string

This operation converts a number to a string, using engineering notation if an exponent is needed.

The conversion exactly follows the rules for conversion to scientific numeric string except in the case of finite numbers where exponential notation is used. In this case, the converted exponent is adjusted to be a multiple of three (engineering notation) by positioning the decimal point with one, two, or three characters preceding it (that is, the part before the decimal point will range from `1` through `999`). This may require the addition of either one or two trailing zeros.

If after the adjustment the decimal point would not be followed by a digit then it is not added. If the final exponent is zero then no indicator letter and exponent is suffixed.

Examples:

For each abstract representation [sign, coefficient, exponent] on the left, the resulting string is shown on the right.

      [0,123,1]       "1.23E+3"
      [0,123,3]       "123E+3"
      [0,123,-10]     "12.3E-9"
      [1,123,-12]     "-123E-12"
      [0,7,-7]        "700E-9"
      [0,7,1]         "70"

### to-number conversion from numeric string

This operation converts a string to a number, as defined by its abstract representation. The string is expected to conform to the numeric string syntax.

Specifically, if the string represents a finite number then:

- If it has a leading sign, then the sign in the resulting abstract representation is set appropriately (1 for `-`, 0 for `+`). Otherwise the sign is set to 0.
  The decimal-part and exponent-part (if any) are then extracted from the string and the exponent-part (following the indicator) is converted to form the integer exponent which will be negative if the exponent-part began with a `-` sign. If there is no exponent-part, the exponent is set to 0.
  If the decimal-part included a decimal point the exponent is then reduced by the count of digits following the decimal point (which may be zero) and the decimal point is removed. The remaining string of digits has any leading zeros removed (except for the rightmost digit) and is then converted to form the coefficient which will be zero or positive.
  A numeric string to finite number conversion is always exact unless there is an underflow or overflow (see below) or the number of digits in the decimal-part of the string is greater than the precision in the context. In this latter case the coefficient will be rounded (shortened) to exactly precision digits, using the rounding algorithm, and the exponent is increased by the number of digits removed.
  If the value of the adjusted exponent is less than Emin, then the number is subnormal. In this case, the calculated coefficient and exponent form the result, unless the value of the exponent is less than Etiny, in which case the exponent will be set to Etiny, and the coefficient will be rounded (possibly to zero) to match the adjustment of the exponent, with the sign remaining as set above. If this rounding gives an inexact result then the Underflow Exceptional condition is raised.
  If (after any rounding of the coefficient) the value of the adjusted exponent is larger than Emax, then an exceptional condition (overflow) results. In this case, the result is as defined under the Overflow Exceptional condition, and may be infinite. It will have the sign as set above.

If the string represents a special value then:

- The string `NaN`, independent of case, is converted to quiet NaN, with sign 0.
- The string `sNaN`, independent of case, is converted to signaling NaN, with sign 0.
- The strings `Infinity` and `Inf`, optionally preceded by a sign character and independent of case, will be converted to infinity. In this case, the sign of the number is set to 1 if the string is preceded by a . Otherwise the sign is set to 0.

The result of attempting to convert a string which does not have the syntax of a numeric string is `[0,qNaN]`.

Examples:

For each string on the left, the resulting abstract representation [sign, coefficient, exponent] or [sign, special-value] is shown on the right. precision is at least 3.

      "0"            [0,0,0]
      "0.00"         [0,0,-2]
      "123"          [0,123,0]
      "-123"         [1,123,0]
      "1.23E3"       [0,123,1]
      "1.23E+3"      [0,123,1]
      "12.3E+7"      [0,123,6]
      "12.0"         [0,120,-1]
      "12.3"         [0,123,-1]
      "0.00123"      [0,123,-5]
      "-1.23E-12"    [1,123,-14]
      "1234.5E-4"    [0,12345,-5]
      "-0"           [1,0,0]
      "-0.00"        [1,0,-2]
      "0E+7"         [0,0,7]
      "-0E-7"        [1,0,-7]
      "inf"          [0,inf]
      "+inFiniTy"    [0,inf]
      "-Infinity"    [1,inf]
      "NAN"          [0,qNaN]
      "SNaN"         [0,sNaN]
      "Fred"         [0,qNaN]

Footnotes:

[1] | See also IEEE 854 §5.6.
[2] | Where quotes surround terminal characters, `::=` means is defined as, `|` means or, `[]` encloses an optional item, and `[]...` encloses an item which is repeated 0 or more times.
[3] | This specification defines only the glyph representing a minus sign character. Depending on the implementation, this will often correspond to a hyphen rather than to a distinguishable minus character.
[4] | This is a deviation from IEEE 854-1987 (see Notes).

[previous | contents | next]