Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

why does a fraction less than one = zero???

6 views
Skip to first unread message

Ben

unread,
Jan 27, 2005, 1:29:41 AM1/27/05
to
I am fairly new to programming languages although I have been playing
with expect/tcl for 6 months.

In my script I have to convert a number to a multiple of 1024. I have
run into a problem whereby tcl seems to think any number below 1 is the
integer zero.

Example, if $x = 1043, my formula is:

[1] set $y [expr $x / 53 * 48 /1000 ] = 0.9446~, but returns zero

I then want to go on to:

[2] set $z [expr round($y)] = 1
[3] set $newx [expr $z * 1024] = 1024

(I am sure these steps can be condensed but just to illustrate what I
have to do)

How can I get tcl to return the value 1 for step [1]?

cheers,

Ben

p.s. I can actually see now that ANY number less than the integer gets
rounded DOWN, i.e 2.944 = 2, 3.123 = 3 etc.
Can I get around this?


Ben

unread,
Jan 27, 2005, 1:33:47 AM1/27/05
to
Just figured out if you make one of the number a decimal (e.g. 1000.0)
then it gives you the correct answer.

Arjen Markus

unread,
Jan 27, 2005, 4:29:12 AM1/27/05
to
Ben wrote:
>
> Ben wrote:
> > I am fairly new to programming languages although I have been playing
> > with expect/tcl for 6 months.
> >

> >


> > p.s. I can actually see now that ANY number less than the integer gets
> > rounded DOWN, i.e 2.944 = 2, 3.123 = 3 etc.
> > Can I get around this?
> >
> >
> Just figured out if you make one of the number a decimal (e.g. 1000.0)
> then it gives you the correct answer.

Yes, the problem is that integers divided by another integer come out
as integers again. This is a very deliberate design choice - it is
consistent with most programming languages, but it can be a surprise
to someone new to programming (*).

The Wiki (<http://wiki.tcl.tk>) has a lot of information on dealing
with numbers (both integer and real), but it is a wee bit scattered
(**)

To summarise:
- integer divides are truncated
- Use the double() and round() functions to achieve other modes
of operation.

For instance:

set tcl_precision 17 ;# Expressly: to show imperfections with real
numbers!
expr {4/3} ==> 1
expr {4/-3} ==> -1
expr {double(4)/3} ==> 1.3333333333333333
expr {3*(double(4)/30) } ==> 0.40000000000000002 ;# 0.4 can not be
represented exactly

Welcome to the wonderful world of computer arithmetic :)

Regards,

Arjen

(*) I have been dealing with integers and reals for some two decades
now, but even
I stumble into this trap at times ;)
(**) Mental note: how about a concise explanation on the Wiki and in the
tutorial

Jonathan Bromley

unread,
Jan 27, 2005, 5:08:42 AM1/27/05
to
On Thu, 27 Jan 2005 06:33:47 GMT, Ben <l3...@hax0r.com> wrote:

>> p.s. I can actually see now that ANY number less than the integer gets
>> rounded DOWN, i.e 2.944 = 2, 3.123 = 3 etc.
>> Can I get around this?

>Just figured out if you make one of the number a decimal (e.g. 1000.0)
>then it gives you the correct answer.

Just for the record: You can get integer division to do
round-to-nearest instead of round-towards-minus-infinity, by
this simple trick:

To get round-to-nearest you need to add 0.5 to the result. For
the division calculation Q=N/M we can get the same effect thus:

Q(rounded) = (N+M/2)/M
= (2*N+M)/(2*M)

This final version of the calculation can be done entirely in
integer arithmetic, and will successfully yield the nearest integer
to the required quotient. The multiplications by 2 are, of course,
simply left shifts - which makes them very cheap if you are trying
to do this in hand-coded assembler on a nasty little 8-bit micro,
as I have done for my sins very many times in the past :-(
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail:jonathan...@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.

Robert Heller

unread,
Jan 27, 2005, 6:52:50 AM1/27/05
to
Ben <l3...@hax0r.com>,
In a message on Thu, 27 Jan 2005 06:33:47 GMT, wrote :

B> Ben wrote:
B> > I am fairly new to programming languages although I have been playing
B> > with expect/tcl for 6 months.
B> >
B> > In my script I have to convert a number to a multiple of 1024. I have
B> > run into a problem whereby tcl seems to think any number below 1 is the
B> > integer zero.
B> >
B> > Example, if $x = 1043, my formula is:
B> >
B> > [1] set $y [expr $x / 53 * 48 /1000 ] = 0.9446~, but returns zero
B> >
B> > I then want to go on to:
B> >
B> > [2] set $z [expr round($y)] = 1
B> > [3] set $newx [expr $z * 1024] = 1024
B> >
B> > (I am sure these steps can be condensed but just to illustrate what I
B> > have to do)
B> >
B> > How can I get tcl to return the value 1 for step [1]?
B> >
B> > cheers,
B> >
B> > Ben
B> >
B> > p.s. I can actually see now that ANY number less than the integer gets
B> > rounded DOWN, i.e 2.944 = 2, 3.123 = 3 etc.
B> > Can I get around this?
B> >
B> >
B> Just figured out if you make one of the number a decimal (e.g. 1000.0)
B> then it gives you the correct answer.

This forces the math to use floating pointing numbers. You can also use
the double() function to do this also:

set $y [expr double($x / double(53 * 48)) / double(1000) ]

B>

\/
Robert Heller ||InterNet: hel...@cs.umass.edu
http://vis-www.cs.umass.edu/~heller || hel...@deepsoft.com
http://www.deepsoft.com /\FidoNet: 1:321/153



Shin The Gin

unread,
Jan 27, 2005, 11:52:59 AM1/27/05
to
Ben wrote:

> Example, if $x = 1043, my formula is:
>
> [1] set $y [expr $x / 53 * 48 /1000 ] = 0.9446~, but returns zero
>

Just make one number a "Real" number:
"set $y [expr $x / 53.0 * 48 /1000 ]" will do the trick ;-)

Shin - A.k.a. Thomas Braun


Ben

unread,
Jan 27, 2005, 6:08:57 PM1/27/05
to
One thing I am starting to appreciate about programming is the number of
ways of solving a problem :)
thanks for the help
Ben
0 new messages