comp.lang.ada
 help / color / mirror / Atom feed
* evaluation of named numbers
@ 2010-10-17 15:01 Rolf
  2010-10-17 15:28 ` Vinzent Hoefler
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Rolf @ 2010-10-17 15:01 UTC (permalink / raw)


I always thought that named numbers are fully evaluated with (almost)
unlimited precision at compile time. I was quite astonished to see

  Ticks : constant := 20 / 1000 * 16_000_000 / 8; -- 40_000 ticks

evaluated to 0 and not to the expected 40.000. It seems that the
compiler uses integer numbers also for intermediate results and 20 /
1000 ends up to be 0 instead of 0.02. Any decent pocket calculator
gets that right.

The workaround is simple once I understood the problem:

   Ticks : constant := 20 * 16_000_000 / 8 / 1000; --  40_000 ticks

Are expressions for named numbers always evaluated left to right? I
think I'll add an item to the review check list to always put
multiplications on the left before any divisions.

   Rolf



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: evaluation of named numbers
  2010-10-17 15:01 evaluation of named numbers Rolf
@ 2010-10-17 15:28 ` Vinzent Hoefler
  2010-10-17 16:05 ` Robert A Duff
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Vinzent Hoefler @ 2010-10-17 15:28 UTC (permalink / raw)


On Sun, 17 Oct 2010 17:01:25 +0200, Rolf <rolf.ebert_nospam_@gmx.net> wrote:

> I always thought that named numbers are fully evaluated with (almost)
> unlimited precision at compile time. I was quite astonished to see
>
>   Ticks : constant := 20 / 1000 * 16_000_000 / 8; -- 40_000 ticks
>
> evaluated to 0 and not to the expected 40.000. It seems that the
> compiler uses integer numbers also for intermediate results and 20 /
> 1000 ends up to be 0 instead of 0.02.

Well, after all it's an integer expression. I wouldn't expect a real
result when doing that - not even as an intermediate result.

> Any decent pocket calculator gets that right.

Because it uses real numbers.

> Are expressions for named numbers always evaluated left to right?

According to ARM 4.5(8), yes.


Vinzent.

-- 
There is no signature.



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: evaluation of named numbers
  2010-10-17 15:01 evaluation of named numbers Rolf
  2010-10-17 15:28 ` Vinzent Hoefler
@ 2010-10-17 16:05 ` Robert A Duff
  2010-10-17 18:32   ` Georg Bauhaus
  2010-10-17 18:57 ` Nasser M. Abbasi
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 7+ messages in thread
From: Robert A Duff @ 2010-10-17 16:05 UTC (permalink / raw)


Rolf <rolf.ebert_nospam_@gmx.net> writes:

> I always thought that named numbers are fully evaluated with (almost)
> unlimited precision at compile time.

Static expressions are always evaluated exactly.  There's no "almost"
about it -- if the compiler runs out of memory trying, then it should
print an error message rather than producing an inexact result.

Named numbers are always static, so that applies to them.

>... I was quite astonished to see
>
>   Ticks : constant := 20 / 1000 * 16_000_000 / 8; -- 40_000 ticks

However, the "/" operator on integer types throws away the remainder
(whether static or at run time).  That's the "/" operator for
root_integer in this case.  20/1000 is exactly 0 in Ada, and that's what
the compiler is calculating.  That's "wrong" in the maths sense, where
20/1000 is "one fiftieth" or "zero with a remainder of 20", or various
other definitions, but never "exactly 0".

If you write it like this:

Ticks : constant := 20.0 / 1000.0 * 16_000_000.0 / 8.0;

then it will use the "/" for root_real, which will
calculate a mathematically correct answer.

It's annoying that Ada (and lots of other languages) use
a mathematically wrong definition of division, but that's
the way it is.  It's also annoying that the type of
a literal is determined by the mere presence or absence
of ".0".

By the way, if you write "-- 40_000 ticks" like this:

    pragma Assert(Ticks = 40_000);

you will be notified if it's wrong.  ;-)

> evaluated to 0 and not to the expected 40.000. It seems that the
> compiler uses integer numbers also for intermediate results and 20 /
> 1000 ends up to be 0 instead of 0.02. Any decent pocket calculator
> gets that right.

I'm no expert in pocket calculators, but I think most of them
use floating point (possibly decimal floating point?),
so they do not always calculate exactly-correct results
with arbitrary precision.  And they tend to have less
memory than is available to an Ada compiler.  ;-)

- Bob



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: evaluation of named numbers
  2010-10-17 16:05 ` Robert A Duff
@ 2010-10-17 18:32   ` Georg Bauhaus
  0 siblings, 0 replies; 7+ messages in thread
From: Georg Bauhaus @ 2010-10-17 18:32 UTC (permalink / raw)


On 10/17/10 6:05 PM, Robert A Duff wrote:

> It's annoying that Ada (and lots of other languages) use
> a mathematically wrong definition of division, but that's
> the way it is.

It annoys me no end when language designers refuse to think
of the computer number as a mathematical entity in its
own right! :-) These numbers have their own rules and their own
glory.  Computable entities of the kind are used every day,
everywhere.  They make rockets explode or deliver satellites.
They are important.

So they are well worth their special mathematical structure
awareness, both during language design and when the programs
are written.  Our brains connect "/" etc. to notions we
have  about a very different kind of number.  Alas, the result
of thinking "school math style" about computer numbers
is a bag of problems, as we see.

Therefore, I prefer adapting programming expressions to the
rules of computer numbers, moving focus away from the
"math numbers fallacy".

It won't hurt you.


(Playing with syntax rules, I'd not use "/" for integers,
since it invites thinking of "/" as division "as we know it".
I believe that Pascal's "div" operator has made many aware
of "division with truncation" not being the same as "division".
    Along with this, however, I'd force the use of parentheses
with "mathematical" operators, simply because these little changes
will make many math related problems disappear. That's because
they appear more visibly in source text, as a reminder that
you are requesting computer number mathematics.)



Georg



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: evaluation of named numbers
  2010-10-17 15:01 evaluation of named numbers Rolf
  2010-10-17 15:28 ` Vinzent Hoefler
  2010-10-17 16:05 ` Robert A Duff
@ 2010-10-17 18:57 ` Nasser M. Abbasi
  2010-10-17 22:30 ` anon
  2010-10-17 22:32 ` anon
  4 siblings, 0 replies; 7+ messages in thread
From: Nasser M. Abbasi @ 2010-10-17 18:57 UTC (permalink / raw)


On 10/17/2010 8:01 AM, Rolf wrote:
> I always thought that named numbers are fully evaluated with (almost)
> unlimited precision at compile time. I was quite astonished to see
>
>    Ticks : constant := 20 / 1000 * 16_000_000 / 8; -- 40_000 ticks
>
> evaluated to 0 and not to the expected 40.000. It seems that the
> compiler uses integer numbers also for intermediate results and 20 /
> 1000 ends up to be 0 instead of 0.02. Any decent pocket calculator
> gets that right.
>

Lets see:

-------------------------
matlab:

20/1000
ans =
     0.0200

int8(20)/int8(1000)
ans =
     0
-------------------

Pyhton
IDLE 2.6.5
 >>> 20/1000
0

 >>> 20.0/1000
0.02
 >>>
------------------

Fortran:

PROGRAM Main
  implicit none

  PRINT *, 2/1000
  PRINT *, 2.0/1000.0
END PROGRAM Main

$ gfortran t1.f90
$ ./a.exe

            0
   2.00000009E-03

--------------------------------

So, if Ada is wrong, then so all these other systems, right?

--Nasser



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: evaluation of named numbers
  2010-10-17 15:01 evaluation of named numbers Rolf
                   ` (2 preceding siblings ...)
  2010-10-17 18:57 ` Nasser M. Abbasi
@ 2010-10-17 22:30 ` anon
  2010-10-17 22:32 ` anon
  4 siblings, 0 replies; 7+ messages in thread
From: anon @ 2010-10-17 22:30 UTC (permalink / raw)


In <2304722c-027d-42f6-a45d-5a7646c35cf6@t8g2000yqk.googlegroups.com>, Rolf <rolf.ebert_nospam_@gmx.net> writes:
>I always thought that named numbers are fully evaluated with (almost)
>unlimited precision at compile time. I was quite astonished to see
>
>  Ticks : constant := 20 / 1000 * 16_000_000 / 8; -- 40_000 ticks
>
>evaluated to 0 and not to the expected 40.000. It seems that the
>compiler uses integer numbers also for intermediate results and 20 /
>1000 ends up to be 0 instead of 0.02. Any decent pocket calculator
>gets that right.
>
>The workaround is simple once I understood the problem:
>
>   Ticks : constant := 20 * 16_000_000 / 8 / 1000; --  40_000 ticks
>
>Are expressions for named numbers always evaluated left to right? I
>think I'll add an item to the review check list to always put
>multiplications on the left before any divisions.
>
>   Rolf

Since, RM 4.5(8) states the Ada's answer to this problem but it 
solution in using parentheses will not corrent the problem so 
rewrite the equation may be needed.


  Ticks : constant := 20 * 16_000_000 / 8 / 1000 ; -- 40_000 ticks






^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: evaluation of named numbers
  2010-10-17 15:01 evaluation of named numbers Rolf
                   ` (3 preceding siblings ...)
  2010-10-17 22:30 ` anon
@ 2010-10-17 22:32 ` anon
  4 siblings, 0 replies; 7+ messages in thread
From: anon @ 2010-10-17 22:32 UTC (permalink / raw)


In <2304722c-027d-42f6-a45d-5a7646c35cf6@t8g2000yqk.googlegroups.com>, Rolf <rolf.ebert_nospam_@gmx.net> writes:
>I always thought that named numbers are fully evaluated with (almost)
>unlimited precision at compile time. I was quite astonished to see
>
>  Ticks : constant := 20 / 1000 * 16_000_000 / 8; -- 40_000 ticks
>
>evaluated to 0 and not to the expected 40.000. It seems that the
>compiler uses integer numbers also for intermediate results and 20 /
>1000 ends up to be 0 instead of 0.02. Any decent pocket calculator
>gets that right.
>
>The workaround is simple once I understood the problem:
>
>   Ticks : constant := 20 * 16_000_000 / 8 / 1000; --  40_000 ticks
>
>Are expressions for named numbers always evaluated left to right? I
>think I'll add an item to the review check list to always put
>multiplications on the left before any divisions.
>
>   Rolf


Since, Rm 4.5(8) states the Ada's answer to this problem but it 
solution in using parentheses will not corrent the problem so 
rewrite the equation may be needed.


  Ticks : constant := 20 * 16_000_000 / 8 / 1000 ; -- 40_000 ticks






^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-10-17 22:32 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-17 15:01 evaluation of named numbers Rolf
2010-10-17 15:28 ` Vinzent Hoefler
2010-10-17 16:05 ` Robert A Duff
2010-10-17 18:32   ` Georg Bauhaus
2010-10-17 18:57 ` Nasser M. Abbasi
2010-10-17 22:30 ` anon
2010-10-17 22:32 ` anon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox