- Comparison to std::numeric_limits<double>::max() - 18 Updates
boltar@cylonHQ.com: May 08 08:49AM On Mon, 7 May 2018 19:45:42 +0200 >> Why not have it? >Because you can easily do it yourself, where "yourself" can be a 3rd >party library. Let's see: No! Really?? Wow, who knew? Congratulations on completely missing the point. >> I was talking about C too. Good luck writing a number class in that. >There is an easy solution, get a C++ compiler. They are free now. No, really?? Wow, who knew? Congra... etc etc |
boltar@cylonHQ.com: May 08 08:51AM On Mon, 07 May 2018 12:38:13 -0500 >multiplicative* operations on FP numbers of wildly differing >magnitudes does not lose accuracy. Additive operations *do*, which is >where the range limit mentioned for voltage comes from. Safety systems like exact values, not "within a reasonable distance of what we want" values. Get the flaps angle on an aircraft a fraction of a degree out and you could find yourself in a stall or a dive PDQ. But hey, its close enough, right? |
Reinhardt Behm <rbehm@hushmail.com>: May 08 04:59PM +0800 > what we want" values. Get the flaps angle on an aircraft a fraction of a > degree out and you could find yourself in a stall or a dive PDQ. But hey, > its close enough, right? You really expect an physical quantities to be exact to 10^-7? When the pilot sets the flaps he does this at best to about +/-10 degrees. You should better talk about things you know something about. -- Reinhardt |
David Brown <david.brown@hesbynett.no>: May 08 11:34AM +0200 > we want" values. Get the flaps angle on an aircraft a fraction of a degree out > and you could find yourself in a stall or a dive PDQ. But hey, its close > enough, right? Close enough is close enough - /that/ is what you aim for. The people who think you should be able to get exact results, or that you should even consider aiming for "as good as possible", are mostly found as hated PHB's. They are certainly not engineers. |
boltar@cylonHQ.com: May 08 09:53AM On Tue, 08 May 2018 16:59:14 +0800 >> degree out and you could find yourself in a stall or a dive PDQ. But hey, >> its close enough, right? >You really expect an physical quantities to be exact to 10^-7? No, but inaccuracies with floating point calcs soon add up. >When the pilot sets the flaps he does this at best to about +/-10 degrees. 10 degrees?? Are you serious?? >You should better talk about things you know something about. You should take your own advice mate! |
boltar@cylonHQ.com: May 08 09:58AM On Tue, 08 May 2018 11:34:29 +0200 >who think you should be able to get exact results, or that you should >even consider aiming for "as good as possible", are mostly found as >hated PHB's. They are certainly not engineers. Don't ever get a job in aerospace if you think aiming for as good as possible isn't something an engineer should be ever bothered with. Stick to designing lamp posts or washing machines or whetever the don't-give-a-toss industry it is you work in. |
David Brown <david.brown@hesbynett.no>: May 08 12:14PM +0200 > isn't something an engineer should be ever bothered with. Stick to designing > lamp posts or washing machines or whetever the don't-give-a-toss industry it is > you work in. I have done safety work. Not for aerospace - but other safety work. And a key point is to avoid over-engineering. If 0.1 degree accuracy is good enough for your aeroplane flaps, then making a system for 0.01 degree accuracy means a system that is bigger, more complex, and with a higher risk of failure. And someone who thinks that you should get it /exactly/ right should not be involved in the process at all. "Exact" is fine for mathematical number theory - it has no place in physical engineering. When prototyping and researching, then of course you will try to see how good you can get it - that will allow more possibilities in the design, or for future systems with tighter requirements. And of course you do not make things unnecessarily inexact. But your target for your design is to be within the specifications needed - if there were any point in going beyond that, the specifications are the problem, not the design. Simplicity, reliability, testability, repeatability - these are all far more important than getting a little closer to "perfect". |
David Brown <david.brown@hesbynett.no>: May 08 12:17PM +0200 >>> its close enough, right? >> You really expect an physical quantities to be exact to 10^-7? > No, but inaccuracies with floating point calcs soon add up. And that is why you have to /understand/ the inaccuracies and how they build up - so that you know the final answer is good enough to use. "Just do it exactly" or "as accurately as possible" are cover-ups for a failure to understand the situation and the mathematics. |
Reinhardt Behm <rbehm@hushmail.com>: May 08 09:20PM +0800 >>> hey, its close enough, right? >>You really expect an physical quantities to be exact to 10^-7? > No, but inaccuracies with floating point calcs soon add up. Only if you don't know how to do numerics. >>When the pilot sets the flaps he does this at best to about +/-10 degrees. > 10 degrees?? Are you serious?? Yes. I design avionics. >>You should better talk about things you know something about. > You should take your own advice mate! I do. -- Reinhardt |
jameskuyper@alumni.caltech.edu: May 08 07:22AM -0700 > >> its close enough, right? > >You really expect an physical quantities to be exact to 10^-7? > No, but inaccuracies with floating point calcs soon add up. Do they? Let's see. I haven't had any practical use of my knowledge of elementary particle physics since I was a research assistant in grad school, but I can look at that formula and realize that if it's related to acceleration of an electron across a voltage drop. If that experience had been only two decades more recent, I probably would even recognize that formula. Since I don't, I'm not sure what range of values are reasonable for voltage, and my knowledge of experimental physics was never sufficiently practical for me to be sure with what accuracy such voltages could be measured. Simple analysis indicates that any value for voltage between -2*m*c*c/e and 0.0 would cause a domain error for std::sqrt(). The heaviest elementary particle known so far is only about 172GeV, so I used an upper limit of 1 TV. To give your thesis it's best opportunity to be valid, I'll assume that the voltage is measured so accurately that double precision floating point limits the accuracy with which it can be represented - which is absurd - that would make it one of the most accurately measured physical quantities ever known. #include <cmath> #include <iomanip> #include <iostream> #include <limits> // <https://physics.nist.gov/cuu/Constants/index.html> const double h = 6.626070040e-34; const double hp = std::nextafter(h,1); const double hm = std::nextafter(h,0); const double hmin = h - 0.000000081e-34; const double hmax = h + 0.000000081e-34; const double e = 1.6021766208e-19; const double ep = std::nextafter(e,1); const double em = std::nextafter(e,0); const double emin = e-0.0000000098e-19; const double emax = e+0.0000000098e-19; const double m = 9.10938356e-31; const double mp = std::nextafter(m,1); const double mm = std::nextafter(m,0); const double mmin = m - 0.00000011e-31; const double mmax = m + 0.00000011e-31; // Note that none of the physical constants listed above even comes close // to being limited by the use of double precision floating point. // The modern metric system defines this value of c to be exact: const double c = 2.99792458e8; const double cp = std::nextafter(m,1); const double cm = std::nextafter(m,0); const double twom = nextafter(2.0, 1.0); const double twop = nextafter(2.0, 3.0); void func(double voltage) { const double vp = nextafter(voltage, std::numeric_limits<double>::max()); const double vm = nextafter(voltage, -std::numeric_limits<double>::max()); const double vs = voltage > 0 ? vm : vp; const double vl = voltage > 0 ? vp : vm; const double result = h/std::sqrt(e*voltage*m*(e*voltage/(m*c*c)+2.0)); const double low_physical = hmin/std::sqrt(emax*vl*mmax*(emax*vl/(mmin*c*c)+2.0)); const double high_physical = hmax/std::sqrt(emin*vs*mmin*(emin*vs/(mmax*c*c)+2.0)); const double low_fp = hm/std::sqrt(ep*vl*mp*(ep*vl/(mm*cm*cm)+twop)); const double high_fp = hp/std::sqrt(em*vs*mm*(em*vs/(mp*cp*cp)+twom)); std::cout << std::setw(11) << voltage << "\t" << result << "\t" << high_physical-low_physical << "\t" << high_fp-low_fp << "\n"; } int main(void) { const double vcrit = 2.0*m*c*c/e; const double vmax = 1e15; std::cout << "Voltage\t\tResult\t\tPhysical\tFP\n" << std::setw(11); for(double voltage = std::numeric_limits<double>::epsilon()*vcrit; voltage < vmax; voltage *= 2.0) func(voltage); for(double voltage = -vcrit; voltage > -vmax; voltage *= 2.0) func(voltage); return 0; } Do you see any cases where the floating point round-off error even comes close to the error due to the uncertainties in the values of the physical constants? Would you care to demonstrate how you could use a fixed point type with only 64 bits before and after the decimal point to perform such calculations with accuracy limited more by the accuracy of the physical constants than by the very limited precision of that format? |
boltar@cylonHQ.com: May 08 03:57PM On Tue, 08 May 2018 21:20:24 +0800 >>>When the pilot sets the flaps he does this at best to about +/-10 degrees. >> 10 degrees?? Are you serious?? >Yes. I design avionics. Of course you do, in between standing in for superman and updating Stephen Hawkings theories, right? |
boltar@cylonHQ.com: May 08 03:59PM On Tue, 8 May 2018 07:22:01 -0700 (PDT) >> >You really expect an physical quantities to be exact to 10^-7? >> No, but inaccuracies with floating point calcs soon add up. >Do they? Let's see. Yes they do, just keep dividing any non even number by 2 for starters. [rest of crap snipped, TL;DR] |
Paavo Helde <myfirstname@osa.pri.ee>: May 08 08:50PM +0300 >>> No, but inaccuracies with floating point calcs soon add up. >> Do they? Let's see. > Yes they do, just keep dividing any non even number by 2 for starters. I'll take the bait. I'm not quite sure what you mean by a non-even floating-point number but I guess 1.0 should qualify. Here is the test: #include <iostream> #include <iomanip> int main() { double x = 1.0; double y = x; int n = 1000; for (int i = 0; i < n; ++i) { y = y / 2.0; } std::cout << "Divided by 2 " << n << " times: " << std::setprecision(40) << y << "\n"; for (int i = 0; i < n; ++i) { y = y * 2.0; } std::cout << "Multiplied by 2 " << n << " times: " << std::fixed << std::setprecision(40) << y << "\n"; double diff = x - y; std::cout << "Accumulated error: " << std::fixed << std::setprecision(40) << diff << "\n"; // The dreaded equality test if (x == y) { std::cout << "The accumulated error is zilch\n"; } } And here is the output: Divided by 2 1000 times: 9.332636185032188789900895447238171696171e-302 Multiplied by 2 1000 times: 1.0000000000000000000000000000000000000000 Accumulated error: 0.0000000000000000000000000000000000000000 The accumulated error is zilch From here you can see that not only do the inaccuracies not accumulate, but there is no error at all! Now please demonstrate to us your fixed-point number design with comparable number of bits (64) where one can divide the number 1.0 1,000 times without losing precision. |
jameskuyper@alumni.caltech.edu: May 08 10:59AM -0700 > >Do they? Let's see. > Yes they do, just keep dividing any non even number by 2 for starters. > [rest of crap snipped, TL;DR] Do they add up enough to be important compared to the errors that are unavoidable when taking measurements? That "crap", as you call it, demonstrates that, in this particular case (which you expressed concern about), floating point inaccuracies never even come close to accumulating large enough to matter. That's not particularly unusual. If you're careful, and know what to look for, that's normally what happens. It's a waste of time, money, and programming skills to calculate with significantly more accuracy than is supported by the accuracy of your input data. A little more accuracy can be helpful for coping with floating point round-off errors. But insisting on getting the mathematically exact result, rather than the nearest representible value, is a sign of your lack of numerical sophistication. The biggest thing to look out for is subtracting two numbers that are very nearly equal - the formula shown has it's largest relative inaccuracies near the place where e*voltage/(m*c*c) is almost exactly -2.0. Avoiding such problems is reason for expm1(), which might otherwise seem like a very odd thing to put in the standard library; log1p() solves the reverse of that problem. The next biggest thing is to avoid evaluating transcendental functions near their singular points, because such evaluations inherently involve such subtractions. Worry about the loss of accuracy in a long train of multiplies and divides is usually misplaced - overflow and underflow usually become a concern long before such a train is long enough for loss of accuracy to become an issue. |
Paavo Helde <myfirstname@osa.pri.ee>: May 08 09:45PM +0300 On 8.05.2018 20:50, Paavo Helde wrote: > The accumulated error is zilch > From here you can see that not only do the inaccuracies not accumulate, > but there is no error at all! Maybe I should have mentioned that the absence of precision loss in the above example is because of the excellent choice of the divisor 2.0. I guess this might not be obvious to some... By using another divisor, e.g. 1.99 the accumulated error becomes non-zero: 1 divided by 1.99 1000 times: 1.402566915437632038350848034701129107735e-299 Multiplied by 1.99 1000 times: 0.9999999999999029665076477613183669745922 Accumulated error: 0.0000000000000970334923522386816330254078 The relative error is in range 1E-14 which is still readily acceptable for most engineering and scientific purposes. |
jameskuyper@alumni.caltech.edu: May 08 12:06PM -0700 On Tuesday, May 8, 2018 at 1:50:35 PM UTC-4, Paavo Helde wrote: > > Yes they do, just keep dividing any non even number by 2 for starters. > I'll take the bait. I'm not quite sure what you mean by a non-even > floating-point number but I guess 1.0 should qualify. Here is the test: I have no idea why he'd choose to call the relevant numbers "non-even", but there are numbers for which division by 2.0 does cause loss of accuracy. This only happens when the result of the division has a value less than DBL_MIN; you're only guaranteed to be able to divide such numbers by 2.0 multiple times without producing a value exactly equal to 0.0 if std::numeric_limits<double>::has_denorm == std::denorm_present. The case I could come up with that loses relative accuracy fastest is 0x1.5555555555555p-1022; a constant I can express using C, but not C++, so I did my testing with C code. But the actual loss of accuracy is the same using either language. |
Paavo Helde <myfirstname@osa.pri.ee>: May 08 10:28PM +0300 > 0x1.5555555555555p-1022; a constant I can express using C, but not C++, > so I did my testing with C code. But the actual loss of accuracy is the > same using either language. Sure, everything has limits. Even infinite precision libraries are limited by the available memory amount. The art of programming (and engineering in general) is to find a way to produce useful results even in the presence of all kind of limitations. That's what it makes it so different from maths. The floating-point number format is just one example of that. |
Vir Campestris <vir.campestris@invalid.invalid>: May 08 09:51PM +0100 On 08/05/2018 14:20, Reinhardt Behm wrote: >>> When the pilot sets the flaps he does this at best to about +/-10 degrees. >> 10 degrees?? Are you serious?? > Yes. I design avionics. That's a big surprise to me. I've seen painted flap position indicators on airliners, and they often have 5 degree increments. And I suspect I'd be seriously inconvenienced if there was a 10 degree discrepancy between the flap settings on the two wings. On the other hand, 1 degree sort of feels as if it should be OK. Given the max flap settings are under 90 degrees storing the position in a byte should do just fine. Feel free to toss in a reference disproving this. Andy |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment