Prev: What is your preferred VCS?
Next: GPS 2010 for AVR
From: Jeffrey R. Carter on 29 Jul 2010 15:08 On 07/29/2010 11:21 AM, Henrique wrote: > > As I declared the type with 6 digits, I expected that it would make > the comparison only for these digits (this would gave var4 = var1). "digits N" means the compiler will use at least Ceiling (N * log2 (10) ) bits for the mantissa, 'Image will produce a string with N digits, and an instantiation of Ada.Text_IO.Float_IO will output N digits by default. There was an effect on the minimum size of the exponent in Ada 83, but I don't think that applies any more. (There are probably other cases as well where the "digits" value has an effect that I can't think of at the moment.) But all operations, including comparisons, take place in the underlying implementation or with greater precision. Most x86-type processors have HW floating-point types that correspond to digits 7, 15, and 18 (IIRC), so on such a machine you should expect your compiler to choose one of those. All computations are done using the digits-18 representation, so there doesn't seem to be much reason to choose another representation. -- Jeff Carter "Well, a gala day is enough for me. I don't think I can handle any more." Duck Soup 93
From: Dmitry A. Kazakov on 29 Jul 2010 15:15 On Thu, 29 Jul 2010 11:21:52 -0700 (PDT), Henrique wrote: > On Jul 29, 12:35�pm, "Dmitry A. Kazakov" <mail...(a)dmitry-kazakov.de> > wrote: >> ------------------------ >> var1 9.99900024414063E+02 >> var4 9.99900085449219E+02 >> >> When rounded to 6 decimal digits both are same. But the underlying base >> binary type is longer than 6 digits. >> >> P.S. It is always useful to think of floating point numbers as intervals >> (which they are) rather than numbers. >> >> -- >> Regards, >> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de > > As I declared the type with 6 digits, I expected that it would make > the comparison only for these digits (this would gave var4 = var1). No, the underlying base type is more or less free compiler choice. There are certain rules, which in essence guarantee you accuracy of the basic operations within the precision specified. > Do I always need to manually truncate the float number to the number > of desired digits before making a comparison of them?? You should never use equality or inequality for floating-point types. They do not have "physical" sense. As I said, floating-point numbers are intervals. Two non-zero length [independent] intervals are *always* unequal, even if their bounds are equal. > So what is the advantage of declaring it as "digits 6"? That the compiler guarantees you 6 decimal digits accuracy independently on whatever hardware you have. The idea behind of Ada numeric types is machine independence. You specify your requirements on the precision and range and the compiler either gives you what you wanted or else rejects the program. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de
From: Phil Clayton on 29 Jul 2010 21:30 On Jul 29, 8:15 pm, "Dmitry A. Kazakov" <mail...(a)dmitry-kazakov.de> wrote: > You should never use equality or inequality for floating-point types. Inequalities (<, <=, >, >=) are ok - I think you meant don't use 'not equals' (which is still an equality operator). However, just because equality between floating point numbers is a dubious concept and should be avoided, it does not mean e.g. "<" and "<=" are simply interchangeable. Far from it. Phil
From: Dmitry A. Kazakov on 30 Jul 2010 04:43 On Thu, 29 Jul 2010 18:30:06 -0700 (PDT), Phil Clayton wrote: > On Jul 29, 8:15�pm, "Dmitry A. Kazakov" <mail...(a)dmitry-kazakov.de> > wrote: >> You should never use equality or inequality for floating-point types. > > Inequalities (<, <=, >, >=) are ok - I think you meant don't use 'not > equals' (which is still an equality operator). Yes I did, thanks for correction. > However, just because equality between floating point numbers is a > dubious concept and should be avoided, it does not mean e.g. "<" and > "<=" are simply interchangeable. Far from it. They are almost same. According to the extension principle: I1<=I2 T (true) if forall x in I1, forall y in I2 x<=y F (false) if forall x in I1, forall y in I2 not x<=y _|_ (undefined) otherwise I1<I2 T if forall x in I1, forall y in I2 x<y F if forall x in I1, forall y in I2 not x<y _|_ otherwise The difference comes from _|_ being rendered T for "<=" and F for "<" when I1 and I2 are equal as sets. It would be ill-advised to exploit this difference without care. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de
From: Phil Clayton on 30 Jul 2010 09:14
On Jul 30, 9:43 am, "Dmitry A. Kazakov" <mail...(a)dmitry-kazakov.de> wrote: > On Thu, 29 Jul 2010 18:30:06 -0700 (PDT), Phil Clayton wrote: > > However, just because equality between floating point numbers is a > > dubious concept and should be avoided, it does not mean e.g. "<" and > > "<=" are simply interchangeable. Far from it. > > They are almost same. According to the extension principle: > > I1<=I2 > > T (true) if forall x in I1, forall y in I2 x<=y > F (false) if forall x in I1, forall y in I2 not x<=y > _|_ (undefined) otherwise > > I1<I2 > > T if forall x in I1, forall y in I2 x<y > F if forall x in I1, forall y in I2 not x<y > _|_ otherwise > > The difference comes from _|_ being rendered T for "<=" and F for "<" when > I1 and I2 are equal as sets. It would be ill-advised to exploit this > difference without care. Certainly ill-advised, but it can be difficult to know when this difference matters. This gives me the perfect excuse to wheel out one of my favourite examples. It's a great example that I keep coming back to for many reasons. We want a 3-way min function (for integers or reals) that gives Y = min {A, B, C} and we are given if A < B and A < C then Y := A; elsif B < C and B < A then Y := B; else Y := C; end if; The justification given is if A is smallest, set Y to A else if B is smallest, set Y to B else C is smallest so set Y to C Unfortunately, the program doesn't work. If you haven't spotted why, it is well worth trying to work it out, perhaps with a few test cases. In fact, this particular error came to various people's attention because it made its way though all stages of a safety-critical software development process. (Fortunately the consequences were not too serious, though intriguing.) The program fails exactly when A = B < C because it returns C, which is not the minimum. I often bring this example up to motivate the use of formal methods as it is particularly difficult to find the error through testing, especially when A, B and C are real types. What are the chances of having A equal to B? Furthermore, the program works when e.g. B = C < A. (The issue occurred predictably on the real system however, because A and B were set to 0 under certain conditions.) Where does the original justification go wrong? Well, when talking about 'the smallest' there is an implicit assumption being made that it is unique. The justification never considers the case when A or B is the non-unique smallest. Of course, the correct program just uses "<=" instead of "<", which is why this example is relevant here: this goes to show that you can't simply interchange "<" and "<=" for real types. Furthermore, "<" and "<=" should be chosen carefully to avoid inadvertent equality conditions: in this example, using "<" has introduced an equality test in the condition for taking the final else branch: not (A < B and A < C) and not (B < C and B < A) is equivalent to A = B or (C <= A and C <= B) ^^^^^ Finally, this example goes to show that issues resulting from implicit equality conditions can be really hard to spot! Of course, I could have pointed out that e.g. not (A < B or B < A) and not (A <= B or B <= A) are not the same but nobody is going to make that mistake - I thought a real example would be more valuable. Sorry for the mild digression, hope that was of interest! Phil |