Division/math bug in perl?

S

Snail

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.)
 
D

darkon

Snail said:
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>
 
J

Jeff Stampes

Snail said:
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
like -268.99999999999994315658 instead. Usually, the
"sprintf", "printf", or the "POSIX::floor" and "POSIX::ceil"
functions will serve you better than will int().
 
A

A. Sinan Unur

Snail said:
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
 
C

Chris Mattern

Snail said:
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?"
 
A

Anno Siegel

Snail said:
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

There is no universal definition of the modulo operation for negative
(or zero) operands. Mathematicians (and implementors) are free to define
it in any way they please.
hand calculator I've tried gives 2 for the above operation.)

Oh.

Anno
 
A

Ala Qumsieh

A. Sinan Unur said:
Might arrogant coming from someone who is unable to read and understand
the documentation:

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.

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

Just my two cents,
--Ala
 
A

A. Sinan Unur

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.

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.
 
A

Alan J. Flavell

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
 
A

Alfred Z. Newmane

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


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?)

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. ;-)
 
S

Snail

A. Sinan Unur said:
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
something I didn't know about this subject.

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
 
S

Snail

Alan said:
Was that typo supposed to be "mite" or "mighty" ?


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
 
A

Ala Qumsieh

A. Sinan Unur said:
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 ;)
 
A

Alan J. Flavell

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
 
B

brian d foy

Snail <[email protected]> said:
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.
 
J

John W. Kennedy

Snail said:
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"
 
A

A. Sinan Unur

Snail said:
My aplogies. I realize my subject line was very poorly choosen.

I want to join Alan in thanking you for this response. I did misinterpret
your intentions based on previous experience, and I apologize for that
response.

Sinan
 
S

Snail

Alan said:
Thank you for this response.

Your very welcome.
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
 
S

Snail

A. Sinan Unur said:
I want to join Alan in thanking you for this response. I did
misinterpret your intentions based on previous experience, and I
apologize for that response.

No problem, may segfault really, with the subject line (which could
easily cause that implication.) I am thankful there are some
understanding people like yourself and Alan in this group.

:> Snail
 
S

Snail

John said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top