# Division/math bug in perl?

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on

Why is this:

\$ perl -e 'print (int (-2.6), "\n")'
-2

Shouldn't it be -3? I thought converting from float to int is supposed
to give the integer part, which is -3, and not round towards zero, as it
seems to be doing, resulting in -2? For that matter, why does c/c++ do
this too?

Any hand calculator I've tried gives -3 for int (-2.6), like a texas
instruments graphing calc.

To it's credit, perl correctly does mod func correctly:

\$ perl -e 'print (-13 % 5, "\n")'
2

Where as in c/c++ you get -3, which is mathematically incorrect. (Any
hand calculator I've tried gives 2 for the above operation.)

## Re: Division/math bug in perl?

Snail wrote:
> Why is this:
>
> \$ perl -e 'print (int (-2.6), "\n")'
> -2

Because the docs say this:

stampes@flux[15] stampes > perldoc -f int
int EXPR
int     Returns the integer portion of EXPR.  If EXPR is omitted, uses
\$_.  You should not use this function for rounding: one because
it truncates towards 0, and two because machine representations
of floating point numbers can sometimes produce counterintu-
itive results.  For example, "int(-6.725/0.025)" produces -268
rather than the correct -269; that's because it's really more
"sprintf", "printf", or the "POSIX::floor" and "POSIX::ceil"
functions will serve you better than will int().

## Re: Division/math bug in perl?

Snail wrote:

> Why is this:
>
> \$ perl -e 'print (int (-2.6), "\n")'
> -2
>
> Shouldn't it be -3? I thought converting from float to int is supposed
> to give the integer part, which is -3,

Er, huh?  >>-2<<.6.  The integer part of that sure looks like -2 to me.
^^

> and not round towards zero, as it
> seems to be doing, resulting in -2? For that matter, why does c/c++ do
> this too?
>
> Any hand calculator I've tried gives -3 for int (-2.6), like a texas
> instruments graphing calc.
>
> To it's credit, perl correctly does mod func correctly:
>
> \$ perl -e 'print (-13 % 5, "\n")'
> 2
>
> Where as in c/c++ you get -3, which is mathematically incorrect. (Any
> hand calculator I've tried gives 2 for the above operation.)

--
Christopher Mattern

"Which one you figure tracked us?"
"The ugly one, sir."
"...Could you be more specific?"

## Re: Division/math bug in perl?

wrote:

> Why is this:
>
> \$ perl -e 'print (int (-2.6), "\n")'
> -2
>
> Shouldn't it be -3? I thought converting from float to int is supposed
> to give the integer part, which is -3, and not round towards zero,

The docs for int() specifically say that it truncates towards zero.
That works no matter which side of zero you are on.

In my mind, it doesn't think about number lines.  It just takes the
digits in the integer portion and discards anything after the
decimal place.  It's not that it's supposed to do anything, as long
as it does what the author said he wanted it to do. It's not
a bug if it's doing what it's documented to do.

If you need something else else, you can write it yourself.

--
brian d foy, comdog@panix.com
Subscribe to The Perl Review: http://www.theperlreview.com

## Re: Division/math bug in perl?

Snail wrote:
> Why is this:
>
> \$ perl -e 'print (int (-2.6), "\n")'
> -2
>
> Shouldn't it be -3? I thought converting from float to int is supposed
> to give the integer part, which is -3, and not round towards zero, as it
> seems to be doing, resulting in -2? For that matter, why does c/c++ do
> this too?
>
> Any hand calculator I've tried gives -3 for int (-2.6), like a texas
> instruments graphing calc.
>
> To it's credit, perl correctly does mod func correctly:
>
> \$ perl -e 'print (-13 % 5, "\n")'
> 2
>
> Where as in c/c++ you get -3, which is mathematically incorrect. (Any
> hand calculator I've tried gives 2 for the above operation.)

Actually, C doesn't define the results of / and % unless both arguments
are positive. It's up to the compiler writer (which typically means it's
up to the hardware architect's design for the "divide" opcode). So Perl
is better defined than C in this respect. (However, when under the
control of "use integer;", Perl works like C.)

There are a gazillion programming languages and dialects out there, and
nearly as many different ways of addressing the noninteger-to-integer
problem. Be glad that Perl at least defines what "int" means; some
languages in the past have regarded it as an "implementation detail".

---
John W. Kennedy
"Give up vows and dogmas, and fixed things, and you may grow like That.
....you may come to think a blow bad, because it hurts, and not because
it humiliates.  You may come to think murder wrong, because it is
violent, and not because it is unjust."
-- G. K. Chesterton.  "The Ball and the Cross"

## Div/Mod with negatives (Re: Division/math bug in perl?)

John W. Kennedy wrote:

> Actually, C doesn't define the results of / and % unless both
> arguments are positive. It's up to the compiler writer (which
> typically means it's up to the hardware architect's design for the
> "divide" opcode). So Perl is better defined than C in this respect.
> (However, when under the control of "use integer;", Perl works like
> C.)

Thank you for your response. So does this behavior stem from hardware?
Like how a CPU handles it? or? (when you said "hardware architect's
design" above.)

> There are a gazillion programming languages and dialects out there,
> and nearly as many different ways of addressing the
> noninteger-to-integer problem. Be glad that Perl at least defines
> what "int" means; some languages in the past have regarded it as an
> "implementation detail".

I did not realize that c (and c++?) do not define it themselves. If it
is related to hardware as I am now suspecting, it might explain why. But
even so, I don't think it would have been difficult to program the
conversion algorithms to work a certain way. It seem, from what I've
gathered so far in this thread, that that is what Perl does.

As a guess, could it have been for effientcy reasons? (Like in the case
of c.)

:> Snail

## Re: Div/Mod with negatives (Re: Division/math bug in perl?)

Snail wrote:
> John W. Kennedy wrote:
>
>
>>Actually, C doesn't define the results of / and % unless both
>>arguments are positive. It's up to the compiler writer (which
>>typically means it's up to the hardware architect's design for the
>>"divide" opcode). So Perl is better defined than C in this respect.
>>(However, when under the control of "use integer;", Perl works like
>>C.)
>
>
> Thank you for your response. So does this behavior stem from hardware?
> Like how a CPU handles it? or? (when you said "hardware architect's
> design" above.)

The design of C supposes that / and % for integers are mostly used with
positive numbers, and that object code should therefore be generated
that will run as fast as possible with positive numbers. The "divide"
instruction on most architectures will do this easily. But to force the
results for negative numbers to fit any particular pattern will take
extra instructions on some machines. Therefore, C gives the compiler
designer the freedom to create the fastest code for positive numbers, no
matter what the results are for negative numbers, and a well-thought-out
C compiler will normally do that. (Some compilers may include options to
force one philosophy or another.)

>>There are a gazillion programming languages and dialects out there,
>>and nearly as many different ways of addressing the
>>noninteger-to-integer problem. Be glad that Perl at least defines
>>what "int" means; some languages in the past have regarded it as an
>>"implementation detail".

> I did not realize that c (and c++?) do not define it themselves. If it
> is related to hardware as I am now suspecting, it might explain why. But
> even so, I don't think it would have been difficult to program the
> conversion algorithms to work a certain way. It seem, from what I've
> gathered so far in this thread, that that is what Perl does.

Perl does not compile to true object code, so forcing the decision has
only a very minor effect on speed. Forcing a rule on C might make divide
in Perl might make it expand from, say, about fifty to about fifty-four.
---
John W. Kennedy
"...if you had to fall in love with someone who was evil, I can see why
it was her."
-- "Alias"

## Re: Division/math bug in perl?

> Why is this:
>
> \$ perl -e 'print (int (-2.6), "\n")'
> -2
>
> Shouldn't it be -3? I thought converting from float to int is

int() isn't really converting, it's just returning the integer part
of the number. See the docs.

> supposed to give the integer part, which is -3, and not round

But the integer part of -2.6 is -2, not -3.

> towards zero, as it seems to be doing, resulting in -2? For that
> matter, why does c/c++ do this too?

I don't know about c/c++, but this behaviour is explicitly documented
for Perl's int():

<quote>

int EXPR
int

Returns the integer portion of EXPR. If EXPR is omitted, uses
\$_. You should not use this function for rounding: one because
it truncates towards 0, and two because machine representations
of floating point numbers can sometimes produce counterintuitive
results.

</quote>

## Re: Division/math bug in perl?

darkon wrote:
>
>> Why is this:
>>
>> \$ perl -e 'print (int (-2.6), "\n")'
>> -2
>>
>> Shouldn't it be -3? I thought converting from float to int is
>
> int() isn't really converting, it's just returning the integer part
> of the number. See the docs.
>
>> supposed to give the integer part, which is -3, and not round
>
> But the integer part of -2.6 is -2, not -3.

Not mathematically it isn't. I should be -3. Think of it like this. The
int part of 2.6 is 2, which is the /lowest/ number before the next
integer on the number line. Applying this to -2.6, the /lowest/ number
before the next integer is -3.

Maybe I can explain this better with an illustration:

Float:  1         .5        2         .5        3
2.6
| - - - - + - - - - | - - - - + * - - - |
Int:    |-----------------| |------------------|
1                   2

So in the other direction on the same number line:

Float: -3         .5       -2         .5       -1
-2.6
| - - - * + - - - - | - - - - + - - - - |
Int:    |-----------------| |-----------------|
-3                  -2

Or think of it like this: -2.6 is the same offset from -3 as +2.4 is
from 2. In other words, -2.6 and 2.4 are in the same realative postion
from the lower integral point. (Is there a better word for that?)

>> towards zero, as it seems to be doing, resulting in -2? For that
>> matter, why does c/c++ do this too?
>
> I don't know about c/c++, but this behaviour is explicitly documented
> for Perl's int():

Actually this behavior is present in C and C++. It's just the way
integer division works internally. It effectively rounds towards 0
instead of down to the lower end of the integer on the number line.

I've never quite understood why it's like it is, in C and C++, one of
side effects is the irregular (from a math perspective) behavior of the
modulus operator (%.)

I agree that it's nice that Perl's % operator does not suffer from this
mathematical short coming. ;-)

## Re: Division/math bug in perl?

comp.lang.perl.misc:
> darkon wrote:

> > But the integer part of -2.6 is -2, not -3.
>
> Not mathematically it isn't.

Mathematics is what mathematicians define it to be.

In particular, the int function is rarely used in mathematics (the
floor and ceiling functions are).  There is no binding convention
how it would have to be defined.

> I should be -3. Think of it like this. The
> int part of 2.6 is 2, which is the /lowest/ number before the next
^^^^^^^
highest

> integer on the number line. Applying this to -2.6, the /lowest/ number
> before the next integer is -3.

It is also the integer whose absolute value is maximal below or equal
to (the absolute value of) 2.6.  Apply that to -2.6, and the result is -3.

Anno

## Re: Division/math bug in perl?

> Subject: Division/math bug in perl?

Might arrogant coming from someone who is unable to read and understand
the documentation:

> Why is this:
>
> \$ perl -e 'print (int (-2.6), "\n")'
> -2

C:\> perldoc -f int
int EXPR
int     Returns the integer portion of EXPR. If EXPR is omitted, uses
\$_. You should not use this function for rounding: one because
it truncates towards 0, and two because machine
representations of floating point numbers can sometimes
produce counterintuitive results. For example,
"int(-6.725/0.025)" produces -268 ...

Sinan

## Re: Division/math bug in perl?

A. Sinan Unur wrote:

>
>
>>Subject: Division/math bug in perl?
>
>
> Might arrogant coming from someone who is unable to read and understand
> the documentation:

can be a bit harsh sometimes, and I agree with them. Your reply here
seems to me too condescending and uncalled for.

Personally, I value your contribution to clpmisc, but I urge you to
exercise more care before posting.

Just my two cents,
--Ala

## Re: Division/math bug in perl?

> A. Sinan Unur wrote:
>
>>
>>
>>>Subject: Division/math bug in perl?
>>
>>
>> Might arrogant coming from someone who is unable to read and
>> understand the documentation:
>
> can be a bit harsh sometimes, and I agree with them. Your reply here
> seems to me too condescending and uncalled for.

I don't know on this one. I think the "I don't need to read what a
function really does, if it does not do what I expect" attitude is quite
irritating. Incidentally, this is not a rare attitude. See Jill
Krugmann's post today.

On the other hand, I do value your opinion of me, so I'll have to figure
something out.

Thanks.

Sinan.

## Re: Division/math bug in perl?

A. Sinan Unur wrote:
>
>> A. Sinan Unur wrote:
>>
>>>
>>>
>>>> Subject: Division/math bug in perl?
>>>
>>>
>>> Might arrogant coming from someone who is unable to read and
>>> understand the documentation:
>>
>> can be a bit harsh sometimes, and I agree with them. Your reply here
>> seems to me too condescending and uncalled for.
>
> I don't know on this one. I think the "I don't need to read what a
> function really does, if it does not do what I expect" attitude is
> quite irritating. Incidentally, this is not a rare attitude. See Jill
> Krugmann's post today.

I think I was a little missleading then, and I'm sorry. I knew that int
does what it does. What I was really getting at was why laguages like
Perl, c, c++, etc, do this sort of division in the first place?

I merely posted out of curiosity, to make a healthy discussion and learn

I also remember reading math books in the past (I'll post if I can find
them) that agree with the notion I put forth, that int(-2.6) = -3, (not
I mean 'int' in a general context, not Perl's 'int()') which is what
should happen for a modulus to work correctly, for example, to yield 2
if mod(-13, 5). If you round towards 0, you get -3 from that. A negative
remainder doesn't seme to make any sence in math afaik.

:> Snail

## Re: Division/math bug in perl?

[A complimentary Cc of this posting was sent to
Snail

> I think I was a little missleading then, and I'm sorry. I knew that int
> does what it does. What I was really getting at was why laguages like
> Perl, c, c++, etc, do this sort of division in the first place?

I have no idea why C had chosen this (IMO, completely broken) semantic
of convert-to-integer.  But since C did it, so should have C++.

Now why Perl did it?  Before about v5.005, Perl was just a very
shallow wrapper about C w.r.t. numeric stuff.  And when I got bold
enough to change the semantic of numerics, the backward compatibility
stroke in.  One of arguments (IIRC, by tchrist) was that the code like

my \$digit = int random 10;

was a legitimate Perl, so it would not be very nice to suddently make
it produce 10 as a possible answer.

Hope this helps,
Ilya

## Re: Division/math bug in perl?

A. Sinan Unur wrote:

> On the other hand, I do value your opinion of me, so I'll have to figure
> something out.

Thanks. I'm glad you took it this way.
--Ala

PS. I have been accused of similar behavior in the past, so you're in
good company ;)

## Re: Division/math bug in perl?

On Thu, 24 Feb 2005, Ala Qumsieh wrote:

> A. Sinan Unur wrote:
>
> >
> > > Subject: Division/math bug in perl?
> >
> > Might arrogant coming from someone who is unable to read and
> > understand the documentation:

Was that typo supposed to be "mite" or "mighty" ?

> I have read earlier posts from others pointing out that your
> comments can be a bit harsh sometimes, and I agree with them. Your
> reply here seems to me too condescending and uncalled for.

Well, I feel motivated to support A.S.U here.  I find the tendency to
report every trivial problem as "bug in ..." - without apparent
reference to any documentation - to be extremely rude and
counterproductive.  I really would like to see an emphatic form of
words as a response to dissuade people from doing that, given that it
brings the whole business of bug reporting into disrepute.

And, by the way, makes it that much harder for the occasions when a
/real/ bug has been discovered, since it has habituated developers
into the belief that "bug report" almost certainly means "idiot who
can't be bothered to check the documentation".

IMHO and YMMV

## Re: Division/math bug in perl?

Alan J. Flavell wrote:
> On Thu, 24 Feb 2005, Ala Qumsieh wrote:
>
> > A. Sinan Unur wrote:
> >
> > >
> > > > Subject: Division/math bug in perl?
> > >
> > > Might arrogant coming from someone who is unable to read and
> > > understand the documentation:
>
> Was that typo supposed to be "mite" or "mighty" ?
>
> > I have read earlier posts from others pointing out that your
> > comments can be a bit harsh sometimes, and I agree with them. Your
> > reply here seems to me too condescending and uncalled for.
>
> Well, I feel motivated to support A.S.U here.  I find the tendency to
> report every trivial problem as "bug in ..." - without apparent
> reference to any documentation - to be extremely rude and
> counterproductive.

My aplogies. I realize my subject line was very poorly choosen. I did
not intend on coming out as rude. I only wanted to start a dicussion on
why langs like Perl, c, c++ (and java?) do this sort of division. I am
thinking there has to be some logical reason why languages to this.

:> Snail

## Re: Division/math bug in perl?

On Thu, 24 Feb 2005, Snail wrote:

> > Well, I feel motivated to support A.S.U here.  I find the tendency
> > to report every trivial problem as "bug in ..." - without apparent
> > reference to any documentation - to be extremely rude and
> > counterproductive.
>
> My aplogies. I realize my subject line was very poorly choosen. I
> did not intend on coming out as rude.

Thank you for this response.

> I only wanted to start a dicussion on why langs like Perl, c, c++
> (and java?) do this sort of division.

I personally would favour an unbiased algorithm, rather than one which
has twice the range of numbers yielding zero as yield any other
integer value.  But the important thing is to check the documentation.

all the best

## Re: Division/math bug in perl?

Alan J. Flavell wrote:
> On Thu, 24 Feb 2005, Snail wrote:
>
>>> Well, I feel motivated to support A.S.U here.  I find the tendency
>>> to report every trivial problem as "bug in ..." - without apparent
>>> reference to any documentation - to be extremely rude and
>>> counterproductive.
>>
>> My aplogies. I realize my subject line was very poorly choosen. I
>> did not intend on coming out as rude.
>
> Thank you for this response.

>> I only wanted to start a dicussion on why langs like Perl, c, c++
>> (and java?) do this sort of division.
>
> I personally would favour an unbiased algorithm, rather than one which
> has twice the range of numbers yielding zero as yield any other
> integer value.  But the important thing is to check the documentation.

Great point. I guess it's a matter of looking at it but this is a great
way of comparing the outcomes on the negative side of zero.

> all the best

You too.

:> Snail