← Back to team overview

kicad-developers team mailing list archive

Re: Rationale for rounding BIUs

 

Le 25/06/2012 08:32, Lorenzo Marcantonio a écrit :
On Sun, Jun 24, 2012 at 06:23:46PM +0200, jean-pierre charras wrote:
I am afraid I do not really understand your question.
In float to integer conversions, rounding creates a smaller error than truncating.
And truncating fval<  0 ? fval - 0.5 : fval + 0.5 is the right way to round a value that must be converted to integer BIU.

Right, I was asking before in other circumstances (i.e. motion control)
truncation or rounding is often (I can't say always, but almost)
replaced by floor()ing, to avoid a discontinuity issue around zero
(reason: the default rounding minimized biasing, flooring minimizes
discontinuities, more or less; I don't know the proper math terms...)
I generally simply avoid floating point if possible using fixed point
instead, if dynamic range is not needed; there is also the issue of the
rounding mode in use and so on (wikipedia treats everything in
details...).

In short I asked because I have simply never seen that construction (but
in fact maybe it's simply equivalent to floor(x+0.5) :P). Just to know
better the code.
It is.
However in debug mode, KiROUND print a warning if the rounding cannot be made.

By the way, your recent issue when reading your board file in kicad nanometer version is a truncating issue,
when scaling float values read in files to integer internal units.
When using rounding conversion instead of truncating, it happens no more.

Wasn't that a precision issue caused by internal rounding of
printf/scanf using doubles instead of long doubles? (I would have simply
saved the nanos as integer...) If that was the case changing precision
shouldn't have changed the result!

This is not a printf/scanf issue using doubles, this is a scaling issue.
Here is an example ( in decimal, with one digit mantissa ) that shows can happen:
If I use a scaling factor FILE2IU= 3, and I want to save the IU integer value = 1000
The saved value is 333.3 (with truncation)
after reading the file you get 333.3 * 3 = 999.9
With truncation, new IU = 999
With rounding, new IU = 1000

regardless the size of the float number, i.e. the number of digits after the decimal separator.

For this kind of issue, the fix is easy (however find the reason was tricky)
(It was just a read function where the call to the rounding conversion was forgotten)

And saving values using the internal values "as is" is a very bad idea.
Values in files *must* be independent of the internal representation,
that can be modified without breaking the file format



Anyway, this is my view about float to int conversion: if possible,
avoid it; otherwise just do whatever works (not very scientific,
I know...)


If possible, yes.
However, there is a lot of case where it is not possible, or even bad,
mainly in trigonometric calculations:
rotations, moving a line and keep slope, distance between items...
Fortunately rounding errors are not always an issue, but sometimes they are.

And remember using ints *does not* avoid truncation errors in calculations.


--
Jean-Pierre CHARRAS
KiCad Developers team.
KiCad Developers <kicad-developers@xxxxxxxxxxxxxxxxxxx>


Follow ups

References