delorie.com/archives/browse.cgi   search  
Mail Archives: geda-user/2016/01/05/16:45:38

X-Authentication-Warning: delorie.com: mail set sender to geda-user-bounces using -f
X-Recipient: geda-user AT delorie DOT com
X-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=20120113;
h=mime-version:in-reply-to:references:date:message-id:subject:from:to
:cc:content-type;
bh=OIvK6dIuo/IPLe1O4HrMONdm90StgfkjS3alqFx0VQ0=;
b=Nc7JUHXkwYnTTrVkunCd0UscJ2/LqqqAnfSCiCUMdYwnMa0OvCI2aWdTea3Jd0lvIv
pQQ8JBLDWewTX9Z3Z/NCOE7UKk4Q0vGQ1XN5DXRgY8t9WONtdouu/WuXzaI/ZybqgQnj
ReKS04dWvPgcF4x1Yc7ooeHBLS61p5wymJUDnT/oyA3sTEGJ0QR0RVJuD0TZyyK/ZD9p
HgDNKHm25st86QHG9unE3YiwKJWQVXv5k6paQkZ2eJpKXDbLsaP72noMAFC5wkAZSHyR
q0SwZKqO69MXGxb58oi7TUHe2hBsBojD/E7bJakwfBulixLXBavwI0v+grnou464mKI9
konQ==
MIME-Version: 1.0
X-Received: by 10.194.6.98 with SMTP id z2mr102379053wjz.101.1452030316217;
Tue, 05 Jan 2016 13:45:16 -0800 (PST)
In-Reply-To: <alpine.DEB.2.00.1512310512510.9035@igor2priv>
References: <CAC4O8c-n4cHWum2MUzgDw=NLuKPK395xp_F24cSyoXhnADRskw AT mail DOT gmail DOT com>
<alpine DOT DEB DOT 2 DOT 00 DOT 1512230503390 DOT 9035 AT igor2priv>
<CAC4O8c8A271d5unQWRV=PoaEsJECgZt33Wy16uCnK6D+4LCzww AT mail DOT gmail DOT com>
<alpine DOT DEB DOT 2 DOT 00 DOT 1512260402081 DOT 9035 AT igor2priv>
<CAC4O8c-49Fn191KT-p0hXi1jXW=OeTSaNUh11pLmBQYHeGtyoA AT mail DOT gmail DOT com>
<alpine DOT DEB DOT 2 DOT 00 DOT 1512310512510 DOT 9035 AT igor2priv>
Date: Tue, 5 Jan 2016 12:45:16 -0900
Message-ID: <CAC4O8c8Or1FS=x18C7Zv5uu+dUOXX2My4K+njsoufNeotm_CBQ@mail.gmail.com>
Subject: [geda-user] Re: some more geometry module tweaks (sorry, wall of text)
From: "Britton Kerin (britton DOT kerin AT gmail DOT com) [via geda-user AT delorie DOT com]" <geda-user AT delorie DOT com>
To: gedau AT igor2 DOT repo DOT hu
Cc: geda-user AT delorie DOT com
Reply-To: geda-user AT delorie DOT com
Errors-To: nobody AT delorie DOT com
X-Mailing-List: geda-user AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

--047d7b5d3e643391b005289d2728
Content-Type: text/plain; charset=UTF-8

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.  If 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.  If by fix you mean
acknowlege intrinsic issues like https://bugs.launchpad.net/pcb/+bug/1013358
and explain how users can avoid them, that's what I think would be good.
So then it just becomes a matter of where you actually put the
conversions.  At the boundary of an all-floating point math kernel is one
logical place...

>
> I use pcb-rnd, which I forked from an older PCB code. That code already
> had support for 32 and 64 bit coords and had the nanometer conversion. The
> maximum board size the preferences window permits is about 1073*1073 mm. I
> just made a board of 1000*1000 mm. Zoom went crazy: can't draw on the sheet
> at all.
>
> I suspect this one is already fxed in later versions of mainline, but to
> me, this suggests the original easy approach on floats and ints is just not

good enough. Question is whether you want a lib that attempts to centralize
> the fix for such bugs, or you want a lib that does the low level


It still does it.  This is probably related to the widget and/or window
coordinates (type int IIRC), which is a different layer from the coordinate
grid.
Probably the conversion calculation overflows at some intermediate point,
which could be fixed.  In the meantime we could limit board size to 400mm
square (which works, 500mm doesn't).

calculations and fix these sort of errors everywhere in the code after
> switching over to the lib. If it was me, I'd go for centralizing the fix.
>
> <snip>
>
>      Btw, what's the case where detectig identical centers is
>>      impossible in geometry.[ch] because of the API?
>>
>>
>> Well if you use floating point, comparing the center coordinates for
>> equality is something of a no-no.  You would want an epsilon value
>> instead.
>>
>
> And tha't sthe tricky part: what's a good epsilon? See later.
>
> It makes sense besides the taboo factor, since almost-identical centers are
>> likely to lead to underflow in the subsequent arc intersection
>> calculations.  Epsilon values and handling are another example of
>> something
>>
>
> Note: we do the same with integer coords: you simply can't put somethin in
> between two nanometers, and we say epsilon is 1 nanometer (no matter how
> big your board is).


> you could put into geometry.h, or not, depending on how aggressive you want
>> to be about encapsulating things in there.  But note that in the case of
>> pcb, it would be useless to put them in, because you probably just want to
>> check for identical coordinates in integer-land instead.  In trying to
>> allow
>>
>
> And this was exactly my point: if the lib knows the coord format is
> integer, an "are_these_points_the_same()" can do the right thing: compare
> integers.  Yes, this is a bunch of #ifdefs. This makes the library look
> ugly. I have a many such libraries in other domains, where my explicit goal
> is to collect all such ugliness in a module and hide it behind an API.
>
> Rationale: there are two problmes here. One is the low level problem, the
> "how": e.g. how do we calculate intersection of two objects. The other one
> is the high level problem, the "why": e.g. the drc decides which objects to
> bloat and compare for intersection (== why to run the low level function to
> calculate the intersection of two objects). My experience is that the real
> hard part in long term maintaining a complex project is in the high level
> part. Thus I tend to prefer moving the ugliness into the low level part
> that is much easer to take away to a test bench and make tests on.
>

Hmm.  I had intended the geometry.h as a sort of portable source library,
without any encapsulated pcb-specific decisions.  As it happens I already
have pcb_geometry.h as well which does some adaptation.  Perhaps the latter
just needs to grow a bit, at which point our ideas of how to handle this
are probably about the same.

[snip]

Well, I think it's possible to do:
>
>  - consistent integer-only high and low level
>
>  - consistent float-only high and low level
>
>  - integer high level with consistent conversions to a float low level
>

This is in effect what we have now, and changing it seems unrealistic.  The
question is how to do it.


>  - and mixed integer and float levels with careless conversions (which
>    was, I believe, the case with pcb before geometry.h)


> However, before you decide, there is a fine-print about floats. (You
> probably well aware of this, so sorry if I repeat the obvious.)
>
> Floats may look better than ints because they seemingly solve all these
> unpleasant problems about rounding and being precise with the "just use an
> epsilon and don't trust LSB bits too much". However, if we step back and
> look at integers and floats from a more theoretical perspective... What's
> ur problem with fixed point integers (like the nanometers PCB has now)?
> That calculations go nasty with small values, because we can not represent
> intermediate results that fall between two numbers we have ion our set,
> that is, between two integers.
>
> So let's go float! But wait: float has the very same problem: it has a
> finite stepping between its numbers as well. What's worse, unlike with
> (fixed point) integers, this stepping keep on changing with the magnitue of
> the value! Try this in C: float f = 100000000; printf with %.12f; then
> f=f+1.0; printf again. This trick works with 1000000 and +0.1, 100000+0.01,
> etc. (Actually shouldn't do it in decimal).
>

I believe I know what you mean here.  If you had to summarize the
consequences, you might say that although ints may get inaccurate for small
numbers, floats (at least of the same size) will do so for big ones, and
you can't say which is worse in general.  As it happens, for pcb screwing
up the big numbers is probably worse.


> This has many consequences. I claim: as many as fixed point int's "what
> happens with small numbers" has. An obvious one is that you can't always go
> with a single fixed epsilon for coords, but epsilon needs to be scaled with
> the magnitude of the coord. This is not obvious for coord


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-Numbers


> comparison (there a small epsilon works for the large cases). But if you
> ever want to make a coord loop  or want to find the "next valid coord to
> the right" (for bloating or whatever), you can't avoid this nasty quesiton.
> This even means if your board is large enough, DRC will miss errors because
> bloating things by 10 units there result in the same object you started
> from!
>
> Just using doubles or long doubles or "something even wider" doesn't solve
> this. What solves this is careful programming - and this, I believe, can
> not be avoided, whichever type combination you pick.
>

I'm not sure about this.  A wider float type can actually represent
everything in a narrower int type.  Consider:

     #include <float.h>
     #include <stdint.h>
     #include <math.h>
     #include <stdio.h>

     int
     main (void)
     {
       printf (
          "INT32_MAX:                          %i\n", INT32_MAX);
       printf (
           "pow (FLT_RADIX, DBL_MANT_DIG) - 1:  %f\n",
           pow (FLT_RADIX, DBL_MANT_DIG) - 1 );
       printf (
           "pow (FLT_RADIX, DBL_MANT_DIG):      %f\n",
           pow (FLT_RADIX, DBL_MANT_DIG) );
       printf (
           "pow (FLT_RADIX, DBL_MANT_DIG) + 1:  %f\n",
           pow (FLT_RADIX, DBL_MANT_DIG) + 1 );

       return 0;
     }

which gives:

      $ gcc --std=c11 -Wall -Wextra -Werror text.c
      $ ./a.out
      INT32_MAX:                          2147483647
     pow (FLT_RADIX, DBL_MANT_DIG) - 1:  9007199254740991.000000
     pow (FLT_RADIX, DBL_MANT_DIG):      9007199254740992.000000
     pow (FLT_RADIX, DBL_MANT_DIG) + 1:  9007199254740992.000000
     $

The largest double to which you can count "by ones" is much greater than
INT32_MAX.

>
> My conclusion:
>
> 00. all the below problems will be present. You absolutely can not
> suppress or overcome or work around them. The only questions are where you
> deal with them (caller or callee) and which pain you choose.
>
> 0. in any case you need to be careful how to pick the widths of the
> internal calculation type and the API type (or alternatively, how you scale
> between the two).
>

Yes, the relationship must be such that e.g. pow (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).


> 1. if you do an int-int, you have to be very careful what to do with small
> numbers; have to detect the cases and do extra moves to make it work. If
> you make a mistake, it's likely to be recognized with real-life sized
> boards and real-life requirements on precision/resolution
>

Yes.


> 2. if you do an int-float, you have to be very careful how you make the
> conversion forth and back, each time you need to do the conversion. If you
> make a mistake, it's likely to be detected only in corners (== harder to
> find the bugs than in 1.)
>

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.  I agree that when you round a result to snap back to the int
grid there's no escaping thinking about which way you should round given
the context, which is why a general rounding policy might not work.  On the
other hand giving up automatic rounding for correctness on that last 1 nm
might be insane.  If your overall design depends on that you have problems
anyway.  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.


> 3. you do a float-float, so there's no conversion; due to the stepping
> mentioned above, your code will very soon work on small boords and common
> precision. If you made mistakes, they will be very hard to detect as not
> only corner cases you need, but also very big and/or very small values too.
> To me, this means bugs are much harder to find here than in 2.


>
> In short: using floats won't solve your problem, just hide them. Been
> there, done that. This why we designed so many gemoetric tasks to be
> specified with integers at challenge24 (http://ch24.org): we figured
> carefully using integers yield much less hard-to-handle special cases than
> just using scaled up ints. I suspect PCB programmers had a similar
> conclusion when settling with integers.
>
> Thus I am not saying PCB must use integers. I merely claim that whichever
> way you chose will require about the same amount of cruft, and that chosing
> floats _in order to_ avoid the cruft totally might be a mistake.


You could very well be right.  If we had some math library that avoided
floats entirely it might be good.  But the reality is we're using them, one
way or another, and it's a question of how to handle the conversions
involved.  I'm fairly certain now that mixing ints and floats in the kernel
itself is a mistake.  What I'm not sure about is whether it's worth adding
a layer that implements a general rounding and comparison policy for pcb,
or if individual points that call into the kernel need to decide this for
themselves on a case-by-case basis.

Britton

--047d7b5d3e643391b005289d2728
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><br></div><div style=3D"">Igor and I have been discus=
sing pcb geometry kernel design, I&#39;m ccing the list in case anyone has =
strong opinions.</div><div><br></div><div style=3D"">[snip]</div><div><br><=
/div><div class=3D"gmail_extra"><div class=3D"gmail_quote"><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;b=
order-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"=
>
Question is: should a big geometry refactoring fix old bugs or questionalbe=
 numeric conversions or just do the same thing with different code org?<br>
<br>
For all the time, I assumed the first.<br></blockquote><div><br></div><div>=
I agree, but we may have different ideas of what the fix would be.=C2=A0 If=
 you want to stop using floating point entirely, it&#39;s a huge effort, an=
d ints won&#39;t do what you want either, you need rationals.=C2=A0 If by f=
ix you mean acknowlege intrinsic issues like <a href=3D"https://bugs.launch=
pad.net/pcb/+bug/1013358" target=3D"_blank">https://bugs.launchpad.net/pcb/=
+bug/1013358</a></div><div>and explain how users can avoid them, that&#39;s=
 what I think would be good.=C2=A0 So then it just becomes a matter of wher=
e you actually put the=C2=A0</div><div>conversions.=C2=A0 At the boundary o=
f an all-floating point math kernel is one logical place...</div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width=
:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-lef=
t:1ex"><br>
I use pcb-rnd, which I forked from an older PCB code. That code already had=
 support for 32 and 64 bit coords and had the nanometer conversion. The max=
imum board size the preferences window permits is about 1073*1073 mm. I jus=
t made a board of 1000*1000 mm. Zoom went crazy: can&#39;t draw on the shee=
t at all.<br>
<br>
I suspect this one is already fxed in later versions of mainline, but to me=
, this suggests the original easy approach on floats and ints is just not=
=C2=A0</blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0px 0p=
x 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border=
-left-style:solid;padding-left:1ex"> good enough. Question is whether you w=
ant a lib that attempts to centralize the fix for such bugs, or you want a =
lib that does the low level</blockquote><div><br></div><div style=3D"">It s=
till does it.=C2=A0 This is probably related to the widget and/or window co=
ordinates (type int IIRC), which is a different layer from the coordinate g=
rid.</div><div style=3D"">Probably the conversion calculation overflows at =
some intermediate point, which could be fixed.=C2=A0 In the meantime we cou=
ld limit board size to 400mm square (which works, 500mm doesn&#39;t).=C2=A0=
</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px =
0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);bord=
er-left-style:solid;padding-left:1ex"> calculations and fix these sort of e=
rrors everywhere in the code after switching over to the lib. If it was me,=
 I&#39;d go for centralizing the fix.<br>
<br>
&lt;snip&gt;<br>
<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;p=
adding-left:1ex">
=C2=A0 =C2=A0 =C2=A0Btw, what&#39;s the case where detectig identical cente=
rs is<br>
=C2=A0 =C2=A0 =C2=A0impossible in geometry.[ch] because of the API?<br>
<br>
<br>
Well if you use floating point, comparing the center coordinates for<br>
equality is something of a no-no.=C2=A0 You would want an epsilon value ins=
tead.<br>
</blockquote>
<br>
And tha&#39;t sthe tricky part: what&#39;s a good epsilon? See later.<br>
<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;p=
adding-left:1ex">
It makes sense besides the taboo factor, since almost-identical centers are=
<br>
likely to lead to underflow in the subsequent arc intersection<br>
calculations.=C2=A0 Epsilon values and handling are another example of some=
thing<br>
</blockquote>
<br>
Note: we do the same with integer coords: you simply can&#39;t put somethin=
 in between two nanometers, and we say epsilon is 1 nanometer (no matter ho=
w big your board is).=C2=A0</blockquote><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rg=
b(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;p=
adding-left:1ex">
you could put into geometry.h, or not, depending on how aggressive you want=
<br>
to be about encapsulating things in there.=C2=A0 But note that in the case =
of<br>
pcb, it would be useless to put them in, because you probably just want to<=
br>
check for identical coordinates in integer-land instead.=C2=A0 In trying to=
 allow<br>
</blockquote>
<br>
And this was exactly my point: if the lib knows the coord format is integer=
, an &quot;are_these_points_the_same()&quot; can do the right thing: compar=
e integers.=C2=A0 Yes, this is a bunch of #ifdefs. This makes the library l=
ook ugly. I have a many such libraries in other domains, where my explicit =
goal is to collect all such ugliness in a module and hide it behind an API.=
<br>
<br>
Rationale: there are two problmes here. One is the low level problem, the &=
quot;how&quot;: e.g. how do we calculate intersection of two objects. The o=
ther one is the high level problem, the &quot;why&quot;: e.g. the drc decid=
es which objects to bloat and compare for intersection (=3D=3D why to run t=
he low level function to calculate the intersection of two objects). My exp=
erience is that the real hard part in long term maintaining a complex proje=
ct is in the high level part. Thus I tend to prefer moving the ugliness int=
o the low level part that is much easer to take away to a test bench and ma=
ke tests on.<br></blockquote><div><br></div><div>Hmm.=C2=A0 I had intended =
the geometry.h as a sort of portable source library, without any encapsulat=
ed pcb-specific decisions.=C2=A0 As it happens I already have pcb_geometry.=
h as well which does some adaptation.=C2=A0 Perhaps the latter just needs t=
o grow a bit, at which point our ideas of how to handle this are probably a=
bout the same.</div><div>=C2=A0</div><div style=3D"">[snip]</div><div><br><=
/div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bo=
rder-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:so=
lid;padding-left:1ex">
Well, I think it&#39;s possible to do:<br>
<br>
=C2=A0- consistent integer-only high and low level<br>
<br>
=C2=A0- consistent float-only high and low level<br>
<br>
=C2=A0- integer high level with consistent conversions to a float low level=
<br></blockquote><div><br></div><div style=3D"">This is in effect what we h=
ave now, and changing it seems unrealistic.=C2=A0 The question is how to do=
 it.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204=
);border-left-style:solid;padding-left:1ex">
=C2=A0- and mixed integer and float levels with careless conversions (which=
<br>
=C2=A0 =C2=A0was, I believe, the case with pcb before geometry.h)=C2=A0</bl=
ockquote><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-styl=
e:solid;padding-left:1ex">
<br>
However, before you decide, there is a fine-print about floats. (You probab=
ly well aware of this, so sorry if I repeat the obvious.)<br>
<br>
Floats may look better than ints because they seemingly solve all these unp=
leasant problems about rounding and being precise with the &quot;just use a=
n epsilon and don&#39;t trust LSB bits too much&quot;. However, if we step =
back and look at integers and floats from a more theoretical perspective...=
 What&#39;s ur problem with fixed point integers (like the nanometers PCB h=
as now)? That calculations go nasty with small values, because we can not r=
epresent intermediate results that fall between two numbers we have ion our=
 set, that is, between two integers.<br>
<br>
So let&#39;s go float! But wait: float has the very same problem: it has a =
finite stepping between its numbers as well. What&#39;s worse, unlike with =
(fixed point) integers, this stepping keep on changing with the magnitue of=
 the value! Try this in C: float f =3D 100000000; printf with %.12f; then f=
=3Df+1.0; printf again. This trick works with 1000000 and +0.1, 100000+0.01=
, etc. (Actually shouldn&#39;t do it in decimal).<br></blockquote><div><br>=
</div><div style=3D"">I believe I know what you mean here.=C2=A0 If you had=
 to summarize the consequences, you might say that although ints may get in=
accurate for small numbers, floats (at least of the same size) will do so f=
or big ones, and you can&#39;t say which is worse in general.=C2=A0 As it h=
appens, for pcb screwing up the big numbers is probably worse.</div><div>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-s=
tyle:solid;padding-left:1ex">
This has many consequences. I claim: as many as fixed point int&#39;s &quot=
;what happens with small numbers&quot; has. An obvious one is that you can&=
#39;t always go with a single fixed epsilon for coords, but epsilon needs t=
o be scaled with the magnitude of the coord. This is not obvious for coord =
</blockquote><div><br></div><div style=3D"">Here&#39;s one attempt at a gen=
eral approach to this problem:</div><div style=3D""><br></div><div style=3D=
""><a href=3D"http://www.gnu.org/software/gsl/manual/html_node/Approximate-=
Comparison-of-Floating-Point-Numbers.html#Approximate-Comparison-of-Floatin=
g-Point-Numbers">http://www.gnu.org/software/gsl/manual/html_node/Approxima=
te-Comparison-of-Floating-Point-Numbers.html#Approximate-Comparison-of-Floa=
ting-Point-Numbers</a><br></div><div>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left=
-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">compariso=
n (there a small epsilon works for the large cases). But if you ever want t=
o make a coord loop=C2=A0 or want to find the &quot;next valid coord to the=
 right&quot; (for bloating or whatever), you can&#39;t avoid this nasty que=
siton. This even means if your board is large enough, DRC will miss errors =
because bloating things by 10 units there result in the same object you sta=
rted from!<br>
<br>
Just using doubles or long doubles or &quot;something even wider&quot; does=
n&#39;t solve this. What solves this is careful programming - and this, I b=
elieve, can not be avoided, whichever type combination you pick.<br></block=
quote><div><br></div><div style=3D"">I&#39;m not sure about this.=C2=A0 A w=
ider float type can actually represent everything in a narrower int type.=
=C2=A0 Consider:</div><div style=3D""><br></div><div>=C2=A0 =C2=A0 =C2=A0#i=
nclude &lt;float.h&gt;</div><div>=C2=A0 =C2=A0 =C2=A0#include &lt;stdint.h&=
gt;</div><div>=C2=A0 =C2=A0 =C2=A0#include &lt;math.h&gt;</div><div>=C2=A0 =
=C2=A0 =C2=A0#include &lt;stdio.h&gt;</div><div>=C2=A0=C2=A0</div><div>=C2=
=A0 =C2=A0 =C2=A0int</div><div>=C2=A0 =C2=A0 =C2=A0main (void)</div><div>=
=C2=A0 =C2=A0 =C2=A0{</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0printf (</div><d=
iv>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &quot;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&=
quot;, INT32_MAX);</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0printf (</div><div>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&quot;pow (FLT_RADIX, DBL_MANT_DIG=
) - 1: =C2=A0%f\n&quot;,</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0pow (FLT_RADIX, DBL_MANT_DIG) - 1 );</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0printf (</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&quot;pow (F=
LT_RADIX, DBL_MANT_DIG): =C2=A0 =C2=A0 =C2=A0%f\n&quot;,</div><div>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pow (FLT_RADIX, DBL_MANT_DIG) );</div><di=
v>=C2=A0 =C2=A0 =C2=A0 =C2=A0printf (</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0&quot;pow (FLT_RADIX, DBL_MANT_DIG) + 1: =C2=A0%f\n&quot;,</d=
iv><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pow (FLT_RADIX, DBL_MANT_D=
IG) + 1 );</div><div><br></div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;</d=
iv><div>=C2=A0 =C2=A0 =C2=A0}<br></div><div><br></div><div>which gives:<br>=
</div><div style=3D""><br></div><div style=3D""><div>=C2=A0 =C2=A0 =C2=A0 $=
 gcc --std=3Dc11 -Wall -Wextra -Werror text.c=C2=A0</div><div>=C2=A0 =C2=A0=
 =C2=A0 $ ./a.out=C2=A0<br></div></div><div style=3D""><div>=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</div><div>=C2=A0 =C2=A0 =C2=A0=
pow (FLT_RADIX, DBL_MANT_DIG) - 1: =C2=A09007199254740991.000000</div><div>=
=C2=A0 =C2=A0 =C2=A0pow (FLT_RADIX, DBL_MANT_DIG): =C2=A0 =C2=A0 =C2=A09007=
199254740992.000000</div><div>=C2=A0 =C2=A0 =C2=A0pow (FLT_RADIX, DBL_MANT_=
DIG) + 1: =C2=A09007199254740992.000000</div><div>=C2=A0 =C2=A0 =C2=A0$=C2=
=A0</div><div><br></div></div><div style=3D"">The largest double to which y=
ou can count &quot;by ones&quot; is much greater than INT32_MAX.</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-=
width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;paddin=
g-left:1ex"><br>
My conclusion:<br>
<br>
00. all the below problems will be present. You absolutely can not suppress=
 or overcome or work around them. The only questions are where you deal wit=
h them (caller or callee) and which pain you choose.<br>
<br>
0. in any case you need to be careful how to pick the widths of the interna=
l calculation type and the API type (or alternatively, how you scale betwee=
n the two).<br></blockquote><div><br></div><div style=3D"">Yes, the relatio=
nship must be such that e.g.=C2=A0pow (FLT_RADIX, DBL_MANT_DIG) &gt; INT32_=
MAX (or whatever largest coord you want to handle), or else you have to wor=
ry about the exact consequences for every case (impractical).</div><div>=C2=
=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-styl=
e:solid;padding-left:1ex">
1. if you do an int-int, you have to be very careful what to do with small =
numbers; have to detect the cases and do extra moves to make it work. If yo=
u make a mistake, it&#39;s likely to be recognized with real-life sized boa=
rds and real-life requirements on precision/resolution<br></blockquote><div=
><br></div><div style=3D"">Yes.</div><div>=C2=A0</div><blockquote class=3D"=
gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border=
-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
2. if you do an int-float, you have to be very careful how you make the con=
version forth and back, each time you need to do the conversion. If you mak=
e a mistake, it&#39;s likely to be detected only in corners (=3D=3D harder =
to find the bugs than in 1.)<br></blockquote><div><br></div><div style=3D""=
>My claim on this is that if your float type entirely contains the set of y=
our int type, there&#39;s no doubt about how the conversion in one directio=
n should work.=C2=A0 I agree that when you round a result to snap back to t=
he int grid there&#39;s no escaping thinking about which way you should rou=
nd given the context, which is why a general rounding policy might not work=
.=C2=A0 On the other hand giving up automatic rounding for correctness on t=
hat last 1 nm might be insane.=C2=A0 If your overall design depends on that=
 you have problems 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 theor=
etical correctness.</div><div style=3D"">=C2=A0<br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;bo=
rder-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
3. you do a float-float, so there&#39;s no conversion; due to the stepping =
mentioned above, your code will very soon work on small boords and common p=
recision. If you made mistakes, they will be very hard to detect as not onl=
y corner cases you need, but also very big and/or very small values too. To=
 me, this means bugs are much harder to find here than in 2.</blockquote><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;pad=
ding-left:1ex">
<br>
<br>
In short: using floats won&#39;t solve your problem, just hide them. Been t=
here, done that. This why we designed so many gemoetric tasks to be specifi=
ed with integers at challenge24 (<a href=3D"http://ch24.org" rel=3D"norefer=
rer" target=3D"_blank">http://ch24.org</a>): we figured carefully using int=
egers yield much less hard-to-handle special cases than just using scaled u=
p ints. I suspect PCB programmers had a similar conclusion when settling wi=
th integers.<br>
<br>
Thus I am not saying PCB must use integers. I merely claim that whichever w=
ay you chose will require about the same amount of cruft, and that chosing =
floats _in order to_ avoid the cruft totally might be a mistake.</blockquot=
e><div><br></div><div style=3D"">You could very well be right.=C2=A0 If we =
had some math library that avoided floats entirely it might be good.=C2=A0 =
But the reality is we&#39;re using them, one way or another, and it&#39;s a=
 question of how to handle the conversions involved.=C2=A0 I&#39;m fairly c=
ertain now that mixing ints and floats in the kernel itself is a mistake.=
=C2=A0 What I&#39;m not sure about is whether it&#39;s worth adding a layer=
 that implements a general rounding and comparison policy for pcb, or if in=
dividual points that call into the kernel need to decide this for themselve=
s on a case-by-case basis.</div><div>=C2=A0</div></div>Britton</div></div>

--047d7b5d3e643391b005289d2728--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019