Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

TCL(Tool Command Language) Scripting

Integer arithmetic problem


I am not sure if it is me or our bellowed "expr" command, but I need
someone to set me straight.

In C the command:
printf("%d\n", -4/3);
gives: -1

I searched c.l.tcl and found a post from 1/27 2005 which said:

> set tcl_precision 17 ;# Expressly: to show imperfections with real numbers!
> expr {4/3} ==> 1
> expr {4/-3} ==> -1

BUT, when I do it in tclsh itself:
expr {-4/3} or expr {4/-3} gives -2 ???

Has someone messed up with integer arithmetic in recent
versions of tcl (I am running 8.4.14)
Just tried on the older version 8.4p1 on different OS/CPU type and got
the same.

Now this is not an academic pursuit.
I was coding a data translator and documentation was
giving a particular expresion to be calculated as
integer arithmetic and I was getting wrong answers.

Anyone has a clue as to what is going on.
I haven't looked at the src yet, but it may get there :-) .

Thanks,
Nikola

On May 31, 9:03 pm, n@alumni.princeton.edu wrote:

When using integer division which results in a remainder, there is no
'correct' answer. The correct answer would be -1.333..

So then whether you round up to -1 or down to -2 is left to
definition. Most scripting languages (at least Python and Ruby) will
round down as Tcl does.

In C < C99 it was not defined what the answer would be (it was
impkementation defined), but on intel HW at least it was -1. In C99 it
was defined to have the value of -1 (e.g. round towards zero, which is
unfortunately different from the rest of the world).

As to why rounding towards zero or down would be better I don't know,
but there are no doubt very good reasons for one and the other.

See http://praisecurseandrecurse.blogspot.com/2006/12/division-bell-tolls...
for some nice background.

Mark

On May 31, 3:24 pm, Mark Janssen <mpc.jans@gmail.com> wrote:

While I understand that integer arithmetic is not perfect
or even consistent, this is still a problem.
[ side bar: IA cannot be consistent with negation and addition
  at the same time. For example -IA(xyz) == IA(-xyz)
  and IA(xyz+2) == IA(xyz)+2 cannot both be right if xyz is -4/3 ]

Nowhere in the documentation is there a mention (that I could find)
about a decission to implement things in this way.

The code is in C so at least it could be consistent with the
underlaying language.

Also how come the 2 year old post has different result
then the one produced by current tcl?

I personally would never use integer arithmetic for anything
but apparently people do and publish formulas based on it.

Anyone knows the inside story abut tcl's handling of such
expressions?

Thanks,
Nikola

n@alumni.princeton.edu schreef:

Oops, I missed the part that it was different in older releases. I
expect that in that older release the C API was used directly leading
to -1 on some platforms and -2 on some others. It might very well be
possible that this was changed when the bytecode engine was introduced
(somewhere around Tcl8.0)

Regardig the fact if this is documented, on the expr manual page it
states (http://www.tcl.tk/man/tcl8.4/TclCmd/expr.htm#M7):
 The remainder will always have the same sign as the divisor and an
absolute value smaller than the divisor.

In case of downwards rounding

expr {-4/3}  == -2
-2 * 3 == -6
therefore  the remainder == 2  (-6 + 2==-4)

2 has the same sign as the divisor 3

In case of rounding towards zero

expr {-4/3} == -1
-1*3 = =-3
therefore the remainder == -1  (-3 + -1 ==-4)

-1 does not have the same sign as the divisor 3

So if rounding was towards 0 the expr manpage would be violated and
hence it can be concluded that the current behaviour is documented
(although it could arguably have been stated more clearly)

Mark

On May 31, 11:39 pm, Mark Janssen <mpc.jans@gmail.com> wrote:

Note that the reply in http://groups.google.com/group/comp.lang.tcl/msg/b9daa050d8747126
suggests that the rounding towards -infinity was already normal
behaviour at this point in time. Apparently Arjen made mental
calculations.
It also provides a alternative that rounds to zero instead:

proc div {n m} {
  expr (2*$n+$m)/(2*$m)

}

% div -4 3
-1
% div 4 -3
-1
% div 4 3
1

Mark

On May 31, 11:59 pm, Mark Janssen <mpc.jans@gmail.com> wrote:

Sorry that proc is round-to-nearest.

% div -5 3
-2

Mark

n@alumni.princeton.edu wrote:
>>> I searched c.l.tcl and found a post from 1/27 2005 which said:
>>>> set tcl_precision 17 ;# Expressly: to show imperfections with real numbers!
>>>> expr {4/3} ==> 1
>>>> expr {4/-3} ==> -1
>>> BUT, when I do it in tclsh itself:
>>> expr {-4/3} or expr {4/-3} gives -2 ???

...

> Nowhere in the documentation is there a mention (that I could find)
> about a decission to implement things in this way.

The documentation is quite explicit about the rules for
the remainder, or modulus, operator "%".  From
http://tmml.sourceforge.net/doc/tcl/expr.html:

"The remainder will always have the same sign as the divisor and an
absolute value smaller than the divisor."

And sure enough, we test...

% expr {4%-3}
-2

And the remainder, -2, has the same sign as the divisor, -3, and
  -2 has an absolute value smaller than that of -3.

I suppose it's a defect that this isn't spelled out explicitly in
the documentation, but the rules for integer division are such that
they are consistent with the rules for remainder.  That is, the
rules are such that:

   expr {($n*($m/$n) + ($m%$n)) == $m}

is always true for integers $m and $n.  I can't imagine anyone wanting
this not to be the case.

The integer division result you cite,

% expr {4/-3}
-2

is consistent with that policy:

% expr {(-3*(4/-3) + (4%-3)) == 4}
1

> The code is in C so at least it could be consistent with the
> underlaying language.

As I understand it, at the time the rules for [expr]'s operators
were established, there was no consistent policy for C.  Each
compiler was free to define the rules as it liked.

> Also how come the 2 year old post has different result
> then the one produced by current tcl?

Because the 2 year old post contained false information.

DGP

Don Porter wrote:
> n@alumni.princeton.edu wrote:
>>...
>> Also how come the 2 year old post has different result
>> then the one produced by current tcl?

> Because the 2 year old post contained false information.

Beware -- not everything published on the Web or in a newsgroup is always
100% correct.  (e.g. the 2 year old post)

--
+--------------------------------+---------------------------------------+
| Gerald W. Lester                                                       |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+

On Jun 1, 10:04 am, "Gerald W. Lester" <Gerald.Les@cox.net> wrote:

I agree, I've been on usenet for almost 20 years and its
getting worse :-) , c.l.tcl excluded .
On the other hand, it didn't seem that any one complained
at that time, so I gave it more relevance.

Thanks to all,
Nikola

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc