The crucial point is that N@Sum is not NSum.
What N@Sum is
N@Sum will first try to evaluate the sum symbolically and then approximate it numerically. Only if Sum cannot perform the first task, and then returns (at least partially) unevaluated, N will resort to using NSum. In case of a finite sum, Sum will always return an evaluated result, consisting possibly of a sum (Plus) of all the terms.
In this example you can see the first situation described: the sum is simplified to \[Pi]^2/6 and then N approximates it:
N@Sum[1/n^2, {n, 1, \[Infinity]}] // Trace In the following example instead, Sum is not able to find an explicit formula, and in the trace you can see that N is called with the unchanged sum as the argument:
N@Sum[Log[n]/(1 + n^2), {n, 1, \[Infinity]}] // Trace You can even check that NSum is called by blocking it (I thank L. B. Shifrin for the inspiration):
Block[{NSum}, Hold@Evaluate@N@Sum[Log[n]/(1 + n^2), {n, 1, \[Infinity]}] ] What NSum is
As the Documentation Center clearly states, NSum tries to approximate the result by various summation methods (listed under More Information).
The guide also states that:
You should realize that with sufficiently pathological summands, the algorithms used by
NSumcan give wrong answers. In most cases, you can test the answer by looking at its sensitivity to changes in the setting of options forNSum.
To get a better sense of this distinction, I think it's useful to check the evaluation
Experimenting
This code shows you at which points f is called:
f[x_] := (Sow[x, "f"]; Cos[x]) a = 0; b = 2; n = 578; Reap[NSum[f[a + (i - (1/2))*((b - a)/n)], {i, 1, n}, EvaluationMonitor :> (Sow[i, "i"])], {"f", "i"}][[2]]; Print["f[] has been called at: ", %[[1, 1]]] ListPlot[%%[[2, 1]], PlotRange -> All, PlotLabel -> "Evaluation points"] As you can see, f has been called 8 times and NSum performed 39 evaluation cycles. This clearly indicates that not all 578 points have been taken in consideration.
On the other hand, if you write
f[x_] := (Sow[x, "f"]; Cos[x]) a = 0; b = 2; n = 578; Reap[Sum[N@f[a + (i - (1/2))*((b - a)/n)], {i, 1, n}], "f"][[2, 1]] // Short % // Length you can see that a long list of exactly 578 evaluation is generated.
Conclusion
What you really need to do is
Sum[N@f[a + (i - (1/2))*((b - a)/n)], {i, 1, n}]