C
Cai Bing Lin
ROUND(((2226-123.36-39.34-303)-1600)*0.05, 2) == 8.01
But when I use VBA. It will be 8.02? why?
To 13 decimal places without the Round function
(((2226-123.36-39.34-303)-1600)*0.05) is 8.0150000000000
joeu2004 said:The short answer: it appears that VBA reorders the computation, which
results in a small difference in the binary result.
I think you are mistaken about VBA reordering the computation.
VBA results are consistent with VBA using 10-byte register arithmetic
when performing in-line 4-function calculations involving only explicitly
Double values.
In the two small sub's below, the only difference is whether the
variables are explicitly Double, or are Variants that contain Double values.
If VBA attempted to optimize calculations by reordering, wouldn't it treat
the expression the same in both sub's?
The first sub produces a result that agrees both with Excel and with 8-byte
binary evaluation in the order given. The second sub produces a result that
agrees with both VBA without variables and with 8-byte reporting of 10-byte
binary evaluation (in the order given) from 8-byte inputs.
I know that the Itanium FPU has a 128-bit register file.
My point was: I was sure if the present-day Intel PC CPUs (Pentium
family, etc) still use 80-bit register files.
The first sub produces a result that agrees both with Excel and with 8-byte
binary evaluation in the order given. The second sub produces a result that
agrees with both VBA without variables and with 8-byte reporting of 10-byte
binary evaluation (in the order given) from 8-byte inputs.
joeu2004 said:I tend to agree, as I noted in my previous response. And just to
solidify Jerry's conclusion, here is a VBA counter-example using
Double, whose result matches the OP's Excel result.
The difference is: this example forces the FPU result (80-bit or
whatever) from each binary operation to be truncated to a 64-bit
intermediate value, as Jerry asserts that Excel does. (Fortunately,
VBA does not optimize the intermediate assignments out of existence ;-
Sorry for the misdirection regarding reordering. But I hope it might
be instructive for other questions about binary arithmetic results.
Initially, I was surprised by the difference between the two
reordering examples: a-(b+c) v. a-b-c. The difference in scale
factors between operands of intermediate results is not that great --
or so I thought at first.
Function dtestit3(arg) As Double
If arg Then
dtestit3 = dtestit4(2226#, 123.36, 39.34, 303#, 1600#, 0.05)
Else
dtestit3 = dtestit5(2226#, 123.36, 39.34, 303#, 1600#, 0.05)
End If
End Function
' let VBA optimize 80-bit(?) FP register usage for intermediate
results
Private Function dtestit4(a As Double, b As Double, _
c As Double, d As Double, e As Double, f As Double) As Double
dtestit4 = ((a - b - c - d) - e) * f
End Function
' force VBA to truncate intermediate results in 80-bit(?) FP registers
' into 64-bit values
Private Function dtestit5(a As Double, b As Double, _
c As Double, d As Double, e As Double, f As Double) As Double
Dim temp As Double
temp = a - b
temp = temp - c
temp = temp - d
temp = temp - e
temp = temp * f
dtestit5 = temp
End Function