From: Jeffrey R. Carter on
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
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
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
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
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
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7
Prev: What is your preferred VCS?
Next: GPS 2010 for AVR