The attenuation of beer styles listed in the BJCP style guide range from 63% for a 9E Strong Scotch Ale up to 97% for the 1A Light American Lager!
Having control over your attenuation is necessary for these styles and actually fairly simple.
There are three main contributing factors to attenuation during fermentation. These are the yeast's attenuation range, mash temperature, and fermenability of added sugars.
Attenuation of a given yeast is essentially it's ability to ferment more complex sugars. Today's brewing yeast provides a range from about 65% for the English Ale Yeasts to 80% for Belgian Sasion strains. This alone give the brewer almost enough room to over the whole spectrum. However, these numbers can be a little misleading. If you took almost any brewing yeast and made a wort of nothing but corn sugar and sucrose the result would be complete attenuation. Therefore, this attenuation factor should be only applied to the gravity provided from the malt. In my experience crystal malt adds very little to the final gravity of the beer. Especially when it is added to the mash as the enzymes will convert some of the complex sugars that would have otherwise be left unconverted in the event that they were steeped.
The mash temperature has one of the largest impacts on fermenability of the wort. Higher temperatures will break down the beta enzymes and also speeds the rate at which the alpha enzymes work. Higher temperatures leave more complex sugar in the wort which are less fermentable. Mash times longer than 60 minutes will also lead to more attenuation of the sugar during fermentation. The results of fairly extensive experiments, as well as my own experience, indicate that each degree above 151 will yield 1% less attenuation.
Fermentability of the sugar, in some ways, trumps mash temperature and attenuation. Sucrose will ferment out completely dry regardless of mash temperature or yeast strain. Conversely lactose will is just about completely unfermentable.
From these three factors the final gravity can be calculated. Let's use a simplified recipe for a poorly designed milk stout as an example.
This is not a recipe you would want to brew.
5 gallon batch.
7 lbs 2-row.
1 lb sucrose.
1 lb lactose.
WLP004 (72% attenuation)
154 mash temperature
75% mash efficiency
The OG contribution of the 2-row is:
7lbs * 37pppg * 75% / 5 gallons = 38.85 gravity points
The OG contribution from the sucrose is:
1lbs * 46pppg / 5 gallons = 9.2 gravity points
The OG contribution from the lactose is:
1lb * 43pppg / 5 gallons = 8.6
The original gravity is therefor:
38.85 + 9.2 + 8.6 = 56.65 gravity points, or a specific gravity of 1.057
The final gravity of the two row is effected by both the yeast and the mash temperature. The temperature is 2 degrees about 152, so that means the malt will be 4% less fermentable.
72% - 4% = 68% attenuation of the malt contribution.
The FG contribution of the two row is:
38.85 * (1 - 68%) = 12.4
The FG contribution of the sucrose is zero because it will ferment out dry
The FG contribution of the lactose is 8.6 because it will not ferment at all.
The final gravity is therefor:
12.4 + 0 + 8.6 = 21 gravity points, or 1.021 specific gravity.
The apparent attenuation is much lower than what is specified for the yeast alone.
1 - (21/57) = 63%
Even with the sucrose in the recipe to dry it out, the final gravity may be high from some people. To fix this a higher attenuating yeast could be selected, the mash temperature could be lowered, or the lactose could be reduced. Any of these would work, but the most appropriate solution for the style would be to lower the mash temperature.
This is a very nice grain chart that I refer to often: