# The Spacing of Decimal Floating-Point Numbers

In a computer, decimal floating-point numbers are converted to binary floating-point numbers for calculation, and binary floating-point numbers are converted to decimal floating-point numbers for display or storage. In general, these conversions are inexact; they are rounded, and rounding is governed by the spacing of numbers in each set.

Floating-point numbers are unevenly spaced, and the spacing varies with the base of the number system. Binary floating-point numbers have power of two sized gaps that change size at power of two boundaries. Decimal floating-point numbers are similarly spaced, but with power of ten sized gaps changing size at power of ten boundaries. In this article, I will discuss the spacing of decimal floating-point numbers.

## Decimal Floating-Point Numbers

A decimal floating-point number is a number written in normalized decimal scientific notation, a number like 4.87764 x 10-5. It is made up of a significand (4.87764) and a power of ten (10-5). The exponent of the power of ten shifts the decimal point to its appropriate place (0.0000487764). Numbers can be positive or negative. (I’ll consider only positive numbers; negative numbers are spaced the same, but as the mirror image.)

The significand contains a limited number of digits, called the precision. This results in gaps between consecutive numbers. Precision determines the number of gaps, and precision and exponent together determine the size of the gaps.

(I will use the phrase ‘decimal floating-point numbers’ but will be specifically talking about decimal floating-point strings. With regard to spacing there is no distinction, except that strings have no notion of subnormal numbers.)

## Spacing In a Toy Floating-Point Number System

To get a feel for spacing, let’s look at a toy decimal floating-point system with one digit of precision and three exponents, -1, 0, and 1. There are 9 1-digit significands: 1, 2, 3, 4, 5, 6, 7, 8, 9. Combined with the three exponents, this system describes 27 numbers (in decimal floating-point, the number of significands and the size of the gaps grows too quickly, making it difficult to show more than the simplest of examples):

One-Digit Decimal Floating-Point Numbers In [0.1,100)
Scientific Notation Decimal
1 x 10-1 0.1
2 x 10-1 0.2
3 x 10-1 0.3
4 x 10-1 0.4
5 x 10-1 0.5
6 x 10-1 0.6
7 x 10-1 0.7
8 x 10-1 0.8
9 x 10-1 0.9
1 x 100 1
2 x 100 2
3 x 100 3
4 x 100 4
5 x 100 5
6 x 100 6
7 x 100 7
8 x 100 8
9 x 100 9
1 x 101 10
2 x 101 20
3 x 101 30
4 x 101 40
5 x 101 50
6 x 101 60
7 x 101 70
8 x 101 80
9 x 101 90

You can see three ranges of spacing: gaps of size 0.1 in the interval [0.1,1), gaps of size 1 in the interval [1,10), and gaps of size 10 in the interval [10,100). Here’s how the spacing looks over [0.1,10):

## Gap Count

Gap count is determined by precision, so let’s start by counting the significands for each increment of precision:

• 1 digit of precision: There are 9 1-digit significands: 1, 2, 3, 4, 5, 6, 7, 8, 9
• 2 digits of precision: There are 90 2-digit significands: 1.0, 1.1, 1.2, … , 9.7, 9.8, 9.9
• 3 digits of precision: There are 900 3-digit significands: 1.00, 1.01, 1.02, … , 9.97, 9.98, 9.99
• 4 digits of precision: There are 9000 4-digit significands: 1.000, 1.001, 1.002, … , 9.997, 9.998, 9.999

From the pattern, you can see that there are 9·10p-1 p-digit significands. More formally, think of the significands as integers (disregard the decimal point). All p-digit integers lie in the interval [10p-1,10p), so there are 10p – 10p-1 = 9·10p-1 of them.

Another way to think of it is this: for each of the nine nonzero leading digits, there are p-1 digits left to vary, and thus 10p-1 combinations.

The number of significands is the same as the number of gaps, since there is a gap from the highest significand to the next power of ten.

```Gap count = 9·10p-1
```

If we go from precision p to precision p+1, we’ll have 9·10p gaps. That is, the number of gaps is multiplied by ten. For each increment of precision, we add 9·10p – 9·10p-1 = 81·10p-1 gaps.

## Gap Size

All decimal floating-point numbers with power of ten exponent e are in the interval [10e,10e+1). (The interval includes 10e but excludes 10e+1.) The length of this interval is 10e+1 – 10e = 9·10e.

Each interval has the same number of equal-sized gaps, which is determined by the precision p. The size of each gap in each interval is the length of the interval divided by the number of gaps: 9·10e/9·10p-1 = 10e-(p-1) = 10e+1-p.

```Gap size = 10e+1-p
```

Each gap is a power of ten in size, and depends on the exponent and precision. With each increment of exponent, gap size is multiplied by ten; with each increment of precision, gap size is divided by ten. So if you increment the exponent and precision at the same time (or if you decrement both at the same time), the gap size will remain the same.

You can think of the 1-p part of the formula as shifting the exponent from the highest digit of the significand to the lowest digit. The lowest digit represents one ULP, and its place value is the gap size.

## Spacing With Increased Precision and Range

Moving beyond our toy system, let’s look at the spacing with increased precision and range.

### Spacing Between Nonnegative Powers of Ten

This table shows the gap counts and gap sizes between nonnegative powers of ten, for various combinations of precision and exponent:

Spacing of Decimal Floating-Point Numbers
(Between Nonnegative Powers of Ten)
[1,10) [10,100) [1038,1039) [10308,10309)
Digits Count Size Size Size Size
1 9 1 10 1038 10308
2 90 0.1 1 1037 10307
3 900 0.01 0.1 1036 10306
4 9000 0.001 0.01 1035 10305
5 9·104 10-4 10-3 1034 10304
6 9·105 10-5 10-4 1033 10303
7 9·106 10-6 10-5 1032 10302
8 9·107 10-7 10-6 1031 10301
9 9·108 10-8 10-7 1030 10300
15 9·1014 10-14 10-13 1024 10294
16 9·1015 10-15 10-14 1023 10293
17 9·1016 10-16 10-15 1022 10292

### Spacing Between Nonpositive Powers of Ten

This table shows the same information for nonpositive powers of ten:

Spacing of Decimal Floating-Point Numbers
(Between Nonpositive Powers of Ten)
[10-308,10-307) [10-38,10-37) [0.01,0.1) [0.1,1)
Digits Count Size Size Size Size
1 9 10-308 10-38 0.01 0.1
2 90 10-309 10-39 0.001 0.01
3 900 10-310 10-40 10-4 10-3
4 9000 10-311 10-41 10-5 10-4
5 9·104 10-312 10-42 10-6 10-5
6 9·105 10-313 10-43 10-7 10-6
7 9·106 10-314 10-44 10-8 10-7
8 9·107 10-315 10-45 10-9 10-8
9 9·108 10-316 10-46 10-10 10-9
15 9·1014 10-322 10-52 10-16 10-15
16 9·1015 10-323 10-53 10-17 10-16
17 9·1016 10-324 10-54 10-18 10-17

#### Relationship to IEEE Binary Floating-Point

I’ve included precision and exponent values relevant to single-precision and double-precision IEEE binary floating-point. The decimal equivalents of single-precision numbers have exponents that range from -38 to 38, and the decimal equivalents of double-precision numbers have exponents that range from -308 to 308. (IEEE subnormal values would extend the decimal exponents down to -46 for single-precision and -324 for double-precision.) Precisions 6 and 9 are relevant to single-precision numbers, and precisions 15 and 17 are relevant to double-precision numbers; they are limits pertaining to round-trip conversions.

## Binary Vs. Decimal Floating-Point Summary

Binary floating-point numbers have a power of two number of power of two sized gaps between powers of two; decimal floating-point numbers have power of ten sized gaps between powers of ten, but there aren’t a power of ten number of them.  