Note: In the interest of making this somewhat self-contained, I am using terminology from the most recent versions of the IEEE-754 standard. Prior to 2008, "subnormal numbers" were called "denormal numbers", and "binary32" was called "single precision". Some textbooks/papers/etc may use the old terms.
The representation that you are talking about here is called, in IEEE-754, normal numbers. A normal number is one which has a single nonzero digit on the left-hand side of the radix point (i.e. decimal point or binary point) of its mantissa.
The representation for zero uses a slightly different representation, namely, subnormal numbers.
Taking binary32 as our example, there are three fields:
- The sign bit, which is 1 bit in size.
- The exponent field, which is 8 bits in size.
- The significand field, which is 23 bits in size.
The sign bit is 0
if the number is positive, and 1
if it is negative.
There are 8 bits reserved for the exponent field, so we can store a number between 0 and 255. We encode the exponent with with a bias of 127, using only the range of -126 to 127 for normal exponents.
The significand field is used to store the mantissa. In binary, the only nonzero digit is 1, so it is not stored explicitly in the IEEE-754 representation of normal numbers. So, for example, to represent the number $3$, we first express it in normal form:
$$+1.1_2 \times 2^1$$
The sign bit is 0
(because the number is positive). The exponent field is $1 + 127$, the true exponent plus the bias, which is 10000000
stored as a bit field.
The mantissa is $1.10000000000000000000000_2$. In normal form, the digit before the binary point is always $1$, so we don't store it, giving 10000000000000000000000
for the significand field.
The reason for the distinction between "mantissa" and "significand" is because the mantissa is the true mathematical mantissa of the number, but the "significand" is only the bits that we need to store.
Using this biased representation for the exponent gives us two bit patterns that we didn't use: 00000000
and 11111111
.
The "all ones" pattern is used for values that are not finite numbers: infinity and NaN ("not a number"). I won't talk further about these here.
The "all zeroes" pattern is used for subnormal numbers. What it means is that the mantissa is the significand field with an implicit zero before the binary point, and the exponent is fixed to be -126. So, for example, if the sign bit is zero (positive), the exponent field is all zeroes, and the significand field is 10000000000000000000000
, then this represents the number:
$$+ 0.10000000000000000000000_2 \times 2^{-126} = 2^{-127}$$
By setting the sign bit, the exponent field and the significand field to all zeroes, this gives us a representation for zero. Plus, it's the most desirable representation as far as programmers are concerned: if you have zeroed-out memory (all of the bits are set to zero) and read it as a floating-point number, it means zero.
There is also a representation here for negative zero. This is by design, but the reasoning behind it is beyond the scope.
Now this is all binary, and you are asking about decimal. IEEE-754 also defines a decimal floating point format, with two different binary encodings. While the exponent is always base-10, the mantissa/significand field can be either binary or densely packed decimal. The idea is still the same. One exponent value is reserved, and zero is represented using that special value.