Re: sprintf rounding behavior



In article <eskaud$e1s$1@xxxxxxxxxxxxxxx>, Roland Perko <roli@xxxxxxxxx> wrote:

hi,

i am somehow confused of Matlab's behavior with rounding within the
"sprintf" function:

i=3:0.05:4; sprintf('%5.1f ', i)
gives
3.0 3.0 3.1 3.1 3.2 3.3 3.3 3.4 3.4 3.5 3.5
3.5 3.6 3.6 3.7 3.8 3.8 3.9 3.9 4.0 4.0

while

i=4:0.05:5; sprintf('%5.1f ', i)
gives
4.0 4.0 4.1 4.2 4.2 4.3 4.3 4.3 4.4 4.5 4.5
4.5 4.6 4.7 4.7 4.8 4.8 4.8 4.9 5.0 5.0

the sequence of the first position after the komma should be "0 0 1 1 2
2 3 3" etc. which is NOT the case and it is different for different
input ranges.

first i guessed that this is an inherent problem due to the binary
representation of float numbers, however coding the same loop in c++
yield correct values.

so my question again is: is this a bug or feature :)

thank you, Roland Perko

ps: Version 7.2.0.232 (R2006a)
------------------------------
You are correct that the behavior you describe is inherent in the binary
representation of numbers. The problem here is due to the fact that odd
multiples of 0.05, when multiplied by 10 (which is a necessary step in
conversion to a decimal fraction,) would be integers plus .5 if there had
been no round-off errors at all, and this would place them exactly at the
half way points when it comes to rounding. For example, 10*3.45 would be
34.5 which is half way between 34 and 35. So 'sprintf' could go either
way: to 3.4 or to 3.5 for the '%5.1f' format. Therefore when you state
that, "the sequence of the first position after the komma should be "0 0 1
1 2 2 3 3" etc", this is not necessarily true. It depends on what one's
convention is with regard to half-way points. According to IEEE 754 rules
of unbiased round-to-nearest, an exact 3.45 (if such a thing were
possible) ought, in a sense, to go to 3.4 and 3.55 to 3.6. However, this
overlooks the fact that there will necessarily have been round-off errors
in computing the quantities 3.45 and 3.55 themselves, and this may have
caused these values after multiplication by 10 to no longer be at exact
half-way points. Which way they would go would depend on the round-off
errors in originally calculating the odd multiples of .05. If you obtain
different results with c++, then it is probably using different methods of
calculating the successive multiples of 0.05, but it cannot be regarded as
being any more correct than matlab's results are. The differences simply
reflect the differences in generating the original sequences, 3:0.05:4 and
4:0.05:5 .

Note: You might try starting with the sequences (300:5:400)/100 and
(400:5:500)/100 to see if these would make a difference. If it does, part
of your troubles could be ascribed to matlab's algorithm for generating
the original sequences.

Roger Stafford
.



Relevant Pages

  • Re: sprintf rounding behavior
    ... been no round-off errors at all, and this would place them exactly at the ... caused these values after multiplication by 10 to no longer be at exact ... errors in originally calculating the odd multiples of .05. ...
    (comp.soft-sys.matlab)
  • Re: Rounding error when converting from double to int
    ... 8.875% of it (suppose it's a sales tax calculation), ... are always multiples of 0.0001%). ... so there is no rounding. ... The multiplication should be done in mathematics, ...
    (comp.lang.c)
  • Re: rounding
    ... Rounding .5625 to two places should result in .57 and rounding ... It seems to me that he wants the rounding to round to multiples of 0.05. ... return Math.Round(num * scale) / scale; ... wind up wind rounding error. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Rounding error when converting from double to int
    ... if you have $9.51 (represented as 951 cents) and you need to take ... 8.875% of it (suppose it's a sales tax calculation), ... are always multiples of 0.0001%). ... so there is no rounding. ...
    (comp.lang.c)
  • Re: ROUNDING IN EXCEL
    ... (multiples of 10) ... VBA Round function does not handle slight discrepancies in the binary ... does anyone have evidence that ASTM rounding has ...
    (microsoft.public.excel.misc)

Loading