Spurred on by Armada's excellent videos, I decided to try and figure out the full attack speed formula.
Result
WAPS = (Base_APS * (1 + WIAS) + WBonus_APS)
WAPS = Weapon Attacks Per Second (the value displayed on the weapon itself) Base_APS = base APS of the weapon before any modifiers WIAS = Weapon Increased Attack Speed (+% attack speed on the weapon itself) WBonus_APS = Weapon Bonus APS (flat +attacks per second on the weapon itself)
APS = (WAPS + OBonus_APS) * (1 + OIAS)
APS = Attacks Per Second (final value) OBonus_APS = Other Bonus APS (flat +attacks per second from other gear *including the other weapon*) OIAS = Other Increased Attack Speed (+% attack speed from non-weapon gear)
The final numbers are rounded to the nearest hundredth for display with decimals ending in "5" rounding down rather than up.
Giving the stats simpler names results in the formulas at the top of the post.
I did some additional in-game testing to determine if the dual wielding bonus was additive or multiplicative with other sources of IAS, and it definitely looks to be additive. In addition, decimals were being rounded to the nearest hundredth except for those ending in a 5 being rounded down rather than up. This is almost certainly due to binary floating point values representing these numbers as ending in 49999 instead of 5.
I didn't test frenzy shrines or IAS from skills like Frenzy, but I would imagine that these values are also added into the OIAS value rather than applies multiplicatively.
Just to clarify - based on the theorycraft that we know, the DW bonus is additive with OIAS (not WIAS).
For total composite DPS when dual wielding, total damage must be averaged over one swing of each weapon. Let's call each weapon's stats MH_WDPS, MH_WDAM, MH_WAPS, OH_WDPS, OH_WDAM, and OH_WAPS:
Result
WAPS = (Base_APS * (1 + WIAS) + WBonus_APS)
WAPS = Weapon Attacks Per Second (the value displayed on the weapon itself)
Base_APS = base APS of the weapon before any modifiers
WIAS = Weapon Increased Attack Speed (+% attack speed on the weapon itself)
WBonus_APS = Weapon Bonus APS (flat +attacks per second on the weapon itself)
APS = (WAPS + OBonus_APS) * (1 + OIAS)
APS = Attacks Per Second (final value)
OBonus_APS = Other Bonus APS (flat +attacks per second from other gear *including the other weapon*)
OIAS = Other Increased Attack Speed (+% attack speed from non-weapon gear)
The final numbers are rounded to the nearest hundredth for display with decimals ending in "5" rounding down rather than up.
Derivation
Most of the formulas can actually be found in the game's attribute formulas: http://www.d3inferno.../attributes.xml Specifically:
Attacks_Per_Second_Item_Subtotal = Attacks_Per_Second_Item * (1 + Attacks_Per_Second_Item_Percent)
and
Attacks_Per_Second_Total = Max(0.01, (((Attacks_Per_Second_Item_CurrentHand > 0.0) ? Attacks_Per_Second_Item_CurrentHand : Attacks_Per_Second) + Attacks_Per_Second_Bonus + Attacks_Per_Second_Item_Bonus) * Max(0.1, (1 + Attacks_Per_Second_Percent)))
which simplifies to (Attacks_Per_Second_Item_CurrentHand is just the Attacks_Per_Second_Item_Subtotal of the next weapon to attack with):
Attacks_Per_Second_Total = (Attacks_Per_Second_Item_Subtotal + Attacks_Per_Second_Bonus + Attacks_Per_Second_Item_Bonus) * (1 + Attacks_Per_Second_Percent)
combining gives us:
Attacks_Per_Second_Total = (Attacks_Per_Second_Item * (1 + Attacks_Per_Second_Item_Percent) + Attacks_Per_Second_Bonus + Attacks_Per_Second_Item_Bonus) * (1 + Attacks_Per_Second_Percent)
Giving the stats simpler names results in the formulas at the top of the post.
I did some additional in-game testing to determine if the dual wielding bonus was additive or multiplicative with other sources of IAS, and it definitely looks to be additive. In addition, decimals were being rounded to the nearest hundredth except for those ending in a 5 being rounded down rather than up. This is almost certainly due to binary floating point values representing these numbers as ending in 49999 instead of 5.
I didn't test frenzy shrines or IAS from skills like Frenzy, but I would imagine that these values are also added into the OIAS value rather than applies multiplicatively.
For total composite DPS when dual wielding, total damage must be averaged over one swing of each weapon. Let's call each weapon's stats MH_WDPS, MH_WDAM, MH_WAPS, OH_WDPS, OH_WDAM, and OH_WAPS:
MH character screen DPS = MH_WDAM * ( MH_WAPS + OBonus_APS) * (1 + OIAS + 15%)
MH Damage = MH_WDAM
MH APS = (MH_WAPS + OBonus_APS) * (1 + OIAS + 15%)
MH Swing Time = 1 / MH_APS
OH character screen DPS = OH_WDAM * ( OH_WAPS + OBonus_APS) * (1 + OIAS + 15%)
OH Damage = OH_WDAM
OH APS = (OH_WAPS + OBonus_APS) * (1 + OIAS + 15%)
OH Swing Time = 1 / OH_APS
============
For 1 swing of each weapon:
Total Damage = MH_WDAM + OH_WDAM
Total Swing Time = (1 / MH_APS) + (1 / OH_APS) = (MH_APS + OH_APS) / (MH_APS * OH_APS)
Total DPS = Total Damage / Total Swing Time = ( (MH_WDAM + OH_WDAM) * MH_APS * OH_APS ) / (MH_APS + OH_APS)