Mail Archives: geda-user/2016/01/05/23:51:23
This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.
--0-950131089-1452056034=:9035
Content-Type: TEXT/PLAIN; charset=UTF-8; format=flowed
Content-Transfer-Encoding: QUOTED-PRINTABLE
On Tue, 5 Jan 2016, Britton Kerin (britton DOT kerin AT gmail DOT com) [via geda-user@=
delorie.com] wrote:
>
>Igor and I have been discussing pcb geometry kernel design, I'm ccing the
>list in case anyone has strong opinions.
>
>[snip]
>
> Question is: should a big geometry refactoring fix old bugs or
> questionalbe numeric conversions or just do the same thing with
> different code org?
>
> For all the time, I assumed the first.
>
>
>I agree, but we may have different ideas of what the fix would be.=C2=A0 I=
f you
>want to stop using floating point entirely, it's a huge effort, and ints
>won't do what you want either, you need rationals.=C2=A0 If by fix you mea=
n
Although later part of the mail had a list like this, that doesn't include=
=20
rationals so I'll repeat it for those who didn't have the chance=20
to follow our conversation. The options I currently see:
1. go for maximal precision, be theoretically/mathematically correct in=20
all situations, no rounding ever: rationals.
2. live with imperfection, and don't care too much where it lurks as long=
=20
as the code generally works (I believe this is how most of the code=20
worked in the past)
3. live with imperfection, but try to explicitly nail it down to make sure=
=20
it's under control
3.a. use integers: easier to use non-native wider types, less hidden=20
global states than with floats; but gets hard with very small numbers
3.b. use floats: they are native, small numbers are easy; it may take more=
=20
effort to explicitly control corner cases, and corners may sligtly break=20
on different arch
I think 1 is overkill. I also think long term 3 should be the goal. I=20
also think it is totally realistic that the path goes through 2: first=20
collect the calculations somehwere central reorganizing the code, then=20
deal with the corners.
So I don't think integer is the ultimate solution. I only say that=20
assuming doubles will just work leads to point 2., not point 3.b. I=20
remember your code made efforts to get rounding correctly, so it's clearly=
=20
not the case. And this leads to my next conjecture: I think doing 3.b.=20
properly is not substantially easier than getting 3.a. corrctly. Where=20
the rounding/conversion is implememented is orthogonal to this. So I=20
probably wouldn't close the door on 3.a.
>acknowlege intrinsic issues like https://bugs.launchpad.net/pcb/+bug/10133=
58
>and explain how users can avoid them, that's what I think would be good.=
=C2=A0 So
>then it just becomes a matter of where you actually put the=C2=A0
>conversions.=C2=A0 At the boundary of an all-floating point math kernel is=
one
>logical place...
I agree. Another logical place is an all-integer math API so that the=20
conversion/fix-for-3 is hidden behind the API. Both solutions could work,=
=20
I happen the prefer the latter.
<snip>
>Hmm.=C2=A0 I had intended the geometry.h as a sort of portable source libr=
ary,
>without any encapsulated pcb-specific decisions.=C2=A0 As it happens I alr=
eady
>have pcb_geometry.h as well which does some adaptation.=C2=A0 Perhaps the =
latter
>just needs to grow a bit, at which point our ideas of how to handle this a=
re
>probably about the same.
Sounds good. I'll start "drawing" because I am not sure I can follow the=20
details. Upper libs depend on lower libs.
A pcb
B pcb-specific-geo (often with complex pcb types)
C generic-geo
So you say C does everything in floating point, and B is responsible for=20
proper rounding/conversions? Or did I get the whole stack wrong?
<snip>
>Here's one attempt at a general approach to this problem:
>
>http://www.gnu.org/software/gsl/manual/html_node/Approximate-Comparison-of=
-
>Floating-Point-Numbers.html#Approximate-Comparison-of-Floating-Point-Numbe=
r
>s
Nice!
<snip>
>I'm not sure about this.=C2=A0 A wider float type can actually represent
>everything in a narrower int type.=C2=A0 Consider:
>
>=C2=A0 =C2=A0 =C2=A0#include <float.h>
>=C2=A0 =C2=A0 =C2=A0#include <stdint.h>
>=C2=A0 =C2=A0 =C2=A0#include <math.h>
>=C2=A0 =C2=A0 =C2=A0#include <stdio.h>
>=C2=A0=C2=A0
>=C2=A0 =C2=A0 =C2=A0int
>=C2=A0 =C2=A0 =C2=A0main (void)
>=C2=A0 =C2=A0 =C2=A0{
>=C2=A0 =C2=A0 =C2=A0 =C2=A0printf (
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "INT32_MAX: =C2=A0 =C2=A0 =C2=A0 =C2=A0=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0%i\n", INT32=
_MAX);
>=C2=A0 =C2=A0 =C2=A0 =C2=A0printf (
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"pow (FLT_RADIX, DBL_MANT_DIG) - =
1: =C2=A0%f\n",
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pow (FLT_RADIX, DBL_MANT_DIG) - 1=
);
>=C2=A0 =C2=A0 =C2=A0 =C2=A0printf (
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"pow (FLT_RADIX, DBL_MANT_DIG): =
=C2=A0 =C2=A0 =C2=A0%f\n",
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pow (FLT_RADIX, DBL_MANT_DIG) );
>=C2=A0 =C2=A0 =C2=A0 =C2=A0printf (
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"pow (FLT_RADIX, DBL_MANT_DIG) + =
1: =C2=A0%f\n",
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pow (FLT_RADIX, DBL_MANT_DIG) + 1=
);
>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;
>=C2=A0 =C2=A0 =C2=A0}
>
>which gives:
>
>=C2=A0 =C2=A0 =C2=A0 $ gcc --std=3Dc11 -Wall -Wextra -Werror text.c=C2=A0
>=C2=A0 =C2=A0 =C2=A0 $ ./a.out=C2=A0
>=C2=A0 =C2=A0 =C2=A0 INT32_MAX: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A02147483647
>=C2=A0 =C2=A0 =C2=A0pow (FLT_RADIX, DBL_MANT_DIG) - 1: =C2=A09007199254740=
991.000000
>=C2=A0 =C2=A0 =C2=A0pow (FLT_RADIX, DBL_MANT_DIG): =C2=A0 =C2=A0 =C2=A0900=
7199254740992.000000
>=C2=A0 =C2=A0 =C2=A0pow (FLT_RADIX, DBL_MANT_DIG) + 1: =C2=A09007199254740=
992.000000
>=C2=A0 =C2=A0 =C2=A0$=C2=A0
>
>The largest double to which you can count "by ones" is much greater than
>INT32_MAX.
<snip>
>Yes, the relationship must be such that e.g.=C2=A0pow (FLT_RADIX, DBL_MANT=
_DIG) >
>INT32_MAX (or whatever largest coord you want to handle), or else you have
>to worry about the exact consequences for every case (impractical).
Yup, this is generally true, and double has more bits than int32. However,=
=20
I think you should also cosinder the x^2 cases: what happens to an=20
sqrt(x^2), if x^2 was in the range of 2^31?
Note: on a PC, intermediate float/double calculations are often done usign=
=20
80 bits instead of 64 or 32. This can forge some of the "where floats=20
break" tests. There's a gcc switch (I can't remember this morning) to=20
force using the smaller types, or to use software emulated fp.
<snip>
>My claim on this is that if your float type entirely contains the set of
>your int type, there's no doubt about how the conversion in one direction
>should work.=C2=A0 I agree that when you round a result to snap back to th=
e int
>grid there's no escaping thinking about which way you should round given t=
he
>context, which is why a general rounding policy might not work.=C2=A0 On t=
he
>other hand giving up automatic rounding for correctness on that last 1 nm
>might be insane.=C2=A0 If your overall design depends on that you have pro=
blems
>anyway.=C2=A0 For example pcb, should probably be honest and somehow tell =
the
>user that setting DRC clearance, line width, and grid size all the same is
>more or less guaranteed to blow up, despite the theoretical correctness.
I agree, design depending on 1 nm is plain wrong.
However, I wouldn't like to see my pcb file showing a 10k diff because I=20
some innocent operation pused things around in the 1nm range as a side=20
effect. This why I am concerned about round trips of the calculations.
Regards,
Igor2
--0-950131089-1452056034=:9035--
- Raw text -