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

## Re: Rounding up in perl

Tim Greer

Very true; unfortunately, on Usenet one must expect that only

negligible percentage of readers would do it. (Especially of you

expect them to disregard what is written explicitly, and somehow read

the meaning between the lines. ;-)

This is why many people jumped in to fix it. Your postings remain

available for googling; if they remain unfixed, they would forever add

"insult by confirming" the permanent injury which is the current Perl docs...

Hmm, it looks like you support the school of "programming by voodoo".

"Try several random chunks of code, and leave the one which gives

results most similar to the target of the exercise." :-(

From my point of view, there are only two types of solutions: correct

ones, and incorrect ones. [Of course, all the Perl stuff in the first

category may still be made unusable by bugs in perl; the additional

complication is that as practice shows, the first category is empty.

;-) :-(]

It looks like you advocate "reading", but are still guilty of the

opposite. Have not it been beaten to death yet that

the intent of int() is to round to zero (often called "truncation");

rounding to zero is one of the forms of rounding?

Probably a linguistic problem: you may just think that "rounding" is a

much less rich notion than it is in reality. There are MANY different

context where rounding is called for, and each context requires its

own semantic; but 5 different semantics (with 2..3 subflavors) are the

most often used...

Yours,

Ilya

## Re: Rounding up in perl

If you mean "between the lines" as in when I followed up and

specifically clarified not being taken into account, because it

wouldn't justify continuing marking snide remarks, yes.

I think just you (and sln).

Yes.

Not really.

Not really.

Saying one thing is intended for another thing than it actually is,

because you can use it for that other thing, isn't correct logic in my

view. I honestly don't care, it was when sln insisted it is intended

***for***rounding. It is to truncate, it can be used to round, it is a

method of doing so. I've been very clear, so you know by now what I

meant, even if you misunderstood. That should really be the end of it,

unless you enjoy arguing. I don't, and you mentioned yourself that it

could be brought back up again. I have no desire to. I'm not even

seeing where the disagreement was if we both agree it can be used to

round. Who cares what the technical terms we disagree about its

intended purpose is, or how we word it or use it to mean one thing or

the other. I don't. Surely you don't either, so let's end it (either

way, I'm done, since there's nothing more to say)...

--

Tim Greer, CEO/Founder/CTO, BurlyHost.com, Inc.

Shared Hosting, Reseller Hosting, Dedicated & Semi-Dedicated servers

and Custom Hosting. 24/7 support, 30 day guarantee, secure servers.

Industry's most experienced staff! -- Web Hosting With Muscle!

## Re: Rounding up in perl

We may have a language problem here. I wouldn't say "truncating is a

method used for rounding", but "truncating is a method of rounding". The

former implies that there is only one way of rounding, and truncating is

not rounding, but can be used to implement rounding. The latter implies

that there are many ways of rounding, and trucating is one of them.

Again, we may have a language problem. If I say a method is "not

dependable" I mean that it does give the expected result most of the

time, but sometimes it gives the wrong result, and the problem isn't

immediately apparent.

To borrow an example from a recent thread, replacing a symlink with

unlink($link) if -e $link;

symlink($target, $link);

is not dependable. It works almost all of the time, but there is a

possibility that another process creates $link between the time your

process has removed it and tries to recreate it - and unless you are

used to thinking about race conditions, you may not see that.

OTOH, if you do something like

$y = int($x) # round to nearest int

that's not a question of dependability. That will produce the wrong

answer for 50% of all possible values, and it is immediately apparent

from the definition of the int function, that it is the wrong function

to use in this case. (floor and ceil are of course, just as wrong).

Let's assume you want a function which rounds the way you learned in

primary school: Round to nearest integer, and break ties away from zero.

sub common

___round___i { my ($x) = @_; return int($x); }

sub common

___round___f { my ($x) = @_; return floor($x); }

sub common

___round___c { my ($x) = @_; return ceil($x); }

sub common

___round___s { my ($x) = @_; return sprintf("%.0f", $x); }

It is immediately clear that the first three implementations don't do

what you want. The first two round 0.9 down (instead of up) and

common

___round___c rounds 0.1 up (instead of down).

common

___round___s seems to do the right thing at the first glance:

It rounds 0.1 down, it rounds 0.9 up, it rounds 1.5 up. But it rounds

0.5 down (instead of up), and that is probably not immediately apparent

to someone who hasn't learned a bit about numerical methods. So you

could say that using sprintf is "not dependable" (for the problem you

want to solve - there are good reasons for sprintf working the way it

does and at that point you should probably consider the possibility that

"rounding the way you learned in primary school" may not be what you

really need), while the other ways are not only "not dependable", they

are clearly und utterly wrong.

However, you can use the int, floor, and ceil functions to implement

your rounding function:

sub common

___round___i2 {

my ($x) = @_;

return int($x + ($x >= 0 ? 0.5 : -0.5));

}

sub common

___round___f2 {

my ($x) = @_;

return $x >= 0 ? floor($x + 0.5) : -floor(-$x + 0.5);

}

sub common

___round___c2 {

my ($x) = @_;

return $x >= 0 ? -ceil(-$x - 0.5) : ceil($x - 0.5);

}

All of these are correct (as per specification), and there is no

mathematical reason to prefer one over the others. But common

___round___i2

is slightly shorter and doen't need any modules, so I'd prefer that from

a Perl programmer's view.

The warning in the documentation is highly confusing. Not really wrong,

but very misleading if you don't already know about these things (and

then you don't need the warning).

hp

## Re: Rounding up in perl

Um, yeah. It says DON'T use it for rounding. Isn't that evidence

that is doesn't round? If it rounded, it would say you COULD use

it for rounding.

--

Christopher Mattern

NOTICE

Thank you for noticing this new notice

Your noticing it has been noted

And will be reported to the authorities

## Re: Rounding up in perl

You've confused posts here bud. Your clipping

what the docs? Not my words.

Does it truncate? What does it truncate?

How exactly do you truncate? Please tell us all.

While your at it, tell us what is rounding up and

down and how it relates to Perl.

Then tell us what Perl's int() is good for.

Thanks!

sln

## Re: Rounding up in perl

This is the last comment I am going to make on this

subject.

The documentation is misleading. This truncating towards 0 is

bull. There is no such thing. Truncating is truncating, period.

It may look like truncating but its not so.

int() rounds DOWN when a positive number and rounds UP when a

negative number. It can't be interpreted in any other fashion.

End of discussion !!

sln

## Re: Rounding up in perl

Good luck with that proof. The set of all numbers x such that

2.0 <= x <= 2.9 is uncountable.

Actually...why don't you stop posting till you complete the proof.

--keith

--

kkeller-usenet@wombat.san-francisco.ca.us

(try just my userid to email me)

AOLSFAQ=http://www.therockgarden.ca/aolsfaq.txt

see X- headers for PGP signature information

## Re: Rounding up in perl

On Fri, 19 Dec 2008 05:26:20 GMT, sln@netherlands.com wrote:

Although, margins should be considered a factot in hyperbolic

design considerations, takr it with a grain of salt, add .000000000\

00000000000000000000000000000000000000000000000000000001 and see

how it plays out.

You just never know, you could discover the asteroid that perishes the

earth.

sln

Although, margins should be considered a factot in hyperbolic

design considerations, takr it with a grain of salt, add .000000000\

00000000000000000000000000000000000000000000000000000001 and see

how it plays out.

You just never know, you could discover the asteroid that perishes the

earth.

sln

## Re: Rounding up in perl

Yes, true its wrong, I see why now. I'm working on it now, testing

(+-) 2.0 - 3.0.

(+-) 1.0 appears to work except on whole number boundries. I will hopefully have

a

solution shortly. If its too verbose in its operation overhead, then POSIX will

have

to do.

I don't think its a big deal though.

sln

## Re: Rounding up in perl

On Thu, 18 Dec 2008 21:28:34 GMT, sln@netherlands.com wrote:

This is amended code and a full proof using standard C ceil/floor

as a comparison. This output is the perl code equavelent.

The previous versions is erroneous and can't use +- .5 as int()

rounds to the nearest whole number.

As it is now +- 1.0 is used as well as taking boundry conditions

into consideration.

The

speedy code if thats possible.

Thanks Peter J. Holzer for pointing out the error.

The good thing about this code is it works the same way every time.

Now, back to the show...

sln

==================================================

# ===========================================

# A Perl based Ceil/floor equavelent

# This floor takes the sign into acount

# when rounding.

# - - - - - - - -

use strict;

use warnings;

## test ceil-floor around 0 and between (+-) 2.0 - 3.0

## in .1 increments

my @Test = qw(

0.0 0.1 0.6

2.0 2.1 2.3 2.4 2.5

2.6 2.7 2.8 2.9 3.0

);

my ($y,$z);

for $y (@Test)

{

$z = _ceil( $y );

printf( "The ceil of %s is %f\n", $y, $z );

$z = _ceil( -$y );

printf( "The ceil of -%s is %f\n\n", $y, $z );

}

for $y (@Test)

{

$z = _floor( $y );

printf( "The floor of %s is %f\n", $y, $z );

$z = _floor( -$y );

printf( "The floor of -%s is %f\n\n", $y, $z );

}

sub _ceil {

my $z = int($_[0]);

return $z if ($

return int($_[0]+1.0);

}

sub _floor {

my $z = int($_[0]);

return $z if ($

return int($_[0]-1.0);

}

The ceil of 0.0 is 0.000000

The ceil of -0.0 is 0.000000

The ceil of 0.1 is 1.000000

The ceil of -0.1 is 0.000000

The ceil of 0.6 is 1.000000

The ceil of -0.6 is 0.000000

The ceil of 2.0 is 2.000000

The ceil of -2.0 is -2.000000

The ceil of 2.1 is 3.000000

The ceil of -2.1 is -2.000000

The ceil of 2.3 is 3.000000

The ceil of -2.3 is -2.000000

The ceil of 2.4 is 3.000000

The ceil of -2.4 is -2.000000

The ceil of 2.5 is 3.000000

The ceil of -2.5 is -2.000000

The ceil of 2.6 is 3.000000

The ceil of -2.6 is -2.000000

The ceil of 2.7 is 3.000000

The ceil of -2.7 is -2.000000

The ceil of 2.8 is 3.000000

The ceil of -2.8 is -2.000000

The ceil of 2.9 is 3.000000

The ceil of -2.9 is -2.000000

The ceil of 3.0 is 3.000000

The ceil of -3.0 is -3.000000

The floor of 0.0 is 0.000000

The floor of -0.0 is 0.000000

The floor of 0.1 is 0.000000

The floor of -0.1 is -1.000000

The floor of 0.6 is 0.000000

The floor of -0.6 is -1.000000

The floor of 2.0 is 2.000000

The floor of -2.0 is -2.000000

The floor of 2.1 is 2.000000

The floor of -2.1 is -3.000000

The floor of 2.3 is 2.000000

The floor of -2.3 is -3.000000

The floor of 2.4 is 2.000000

The floor of -2.4 is -3.000000

The floor of 2.5 is 2.000000

The floor of -2.5 is -3.000000

The floor of 2.6 is 2.000000

The floor of -2.6 is -3.000000

The floor of 2.7 is 2.000000

The floor of -2.7 is -3.000000

The floor of 2.8 is 2.000000

The floor of -2.8 is -3.000000

The floor of 2.9 is 2.000000

The floor of -2.9 is -3.000000

The floor of 3.0 is 3.000000

The floor of -3.0 is -3.000000

This is amended code and a full proof using standard C ceil/floor

as a comparison. This output is the perl code equavelent.

The previous versions is erroneous and can't use +- .5 as int()

rounds to the nearest whole number.

As it is now +- 1.0 is used as well as taking boundry conditions

into consideration.

The

___ceil()/___floor() are eqavelent now. An effort was made towardsspeedy code if thats possible.

Thanks Peter J. Holzer for pointing out the error.

The good thing about this code is it works the same way every time.

Now, back to the show...

sln

==================================================

# ===========================================

# A Perl based Ceil/floor equavelent

# This floor takes the sign into acount

# when rounding.

# - - - - - - - -

use strict;

use warnings;

## test ceil-floor around 0 and between (+-) 2.0 - 3.0

## in .1 increments

my @Test = qw(

0.0 0.1 0.6

2.0 2.1 2.3 2.4 2.5

2.6 2.7 2.8 2.9 3.0

);

my ($y,$z);

for $y (@Test)

{

$z = _ceil( $y );

printf( "The ceil of %s is %f\n", $y, $z );

$z = _ceil( -$y );

printf( "The ceil of -%s is %f\n\n", $y, $z );

}

for $y (@Test)

{

$z = _floor( $y );

printf( "The floor of %s is %f\n", $y, $z );

$z = _floor( -$y );

printf( "The floor of -%s is %f\n\n", $y, $z );

}

sub _ceil {

my $z = int($_[0]);

return $z if ($

___[0] == $z || $___[0]<0);return int($_[0]+1.0);

}

sub _floor {

my $z = int($_[0]);

return $z if ($

___[0] == $z || $___[0]>=0);return int($_[0]-1.0);

}

______END______The ceil of 0.0 is 0.000000

The ceil of -0.0 is 0.000000

The ceil of 0.1 is 1.000000

The ceil of -0.1 is 0.000000

The ceil of 0.6 is 1.000000

The ceil of -0.6 is 0.000000

The ceil of 2.0 is 2.000000

The ceil of -2.0 is -2.000000

The ceil of 2.1 is 3.000000

The ceil of -2.1 is -2.000000

The ceil of 2.3 is 3.000000

The ceil of -2.3 is -2.000000

The ceil of 2.4 is 3.000000

The ceil of -2.4 is -2.000000

The ceil of 2.5 is 3.000000

The ceil of -2.5 is -2.000000

The ceil of 2.6 is 3.000000

The ceil of -2.6 is -2.000000

The ceil of 2.7 is 3.000000

The ceil of -2.7 is -2.000000

The ceil of 2.8 is 3.000000

The ceil of -2.8 is -2.000000

The ceil of 2.9 is 3.000000

The ceil of -2.9 is -2.000000

The ceil of 3.0 is 3.000000

The ceil of -3.0 is -3.000000

The floor of 0.0 is 0.000000

The floor of -0.0 is 0.000000

The floor of 0.1 is 0.000000

The floor of -0.1 is -1.000000

The floor of 0.6 is 0.000000

The floor of -0.6 is -1.000000

The floor of 2.0 is 2.000000

The floor of -2.0 is -2.000000

The floor of 2.1 is 2.000000

The floor of -2.1 is -3.000000

The floor of 2.3 is 2.000000

The floor of -2.3 is -3.000000

The floor of 2.4 is 2.000000

The floor of -2.4 is -3.000000

The floor of 2.5 is 2.000000

The floor of -2.5 is -3.000000

The floor of 2.6 is 2.000000

The floor of -2.6 is -3.000000

The floor of 2.7 is 2.000000

The floor of -2.7 is -3.000000

The floor of 2.8 is 2.000000

The floor of -2.8 is -3.000000

The floor of 2.9 is 2.000000

The floor of -2.9 is -3.000000

The floor of 3.0 is 3.000000

The floor of -3.0 is -3.000000

## Re: Rounding up in perl

On Sun, 21 Dec 2008 22:42:39 GMT, sln@netherlands.com wrote:

[snip]

[snip]

not needed ^^^

not needed ^^^

There is no need for a double call to int().

The last int() is not necessary. So it's speedier,

if there is such a thing.

sln

## -----------------------

## ceil/floor equavelent

## -----------------------

use strict;

use warnings;

## test ceil-floor around 0 and between (+-) 2.0 - 3.0

my @Test = qw(

0.0 0.1 0.6

2.0 2.1 2.3 2.4 2.5

2.6 2.7 2.8 2.9 3.0

);

my $y;

for $y (@Test)

{

printf( "The ceil of %s is %f\n", $y, _ceil( $y ) );

printf( "The ceil of -%s is %f\n\n", $y, _ceil( -$y ) );

}

for $y (@Test)

{

printf( "The floor of %s is %f\n", $y, _floor( $y ) );

printf( "The floor of -%s is %f\n\n", $y, _floor( -$y ) );

}

sub _ceil {

my $z = int($_[0]);

return $z if ($

return $z+1.0;

}

sub _floor {

my $z = int($_[0]);

return $z if ($

return $z-1.0;

}

[snip]

[snip]

not needed ^^^

not needed ^^^

There is no need for a double call to int().

The last int() is not necessary. So it's speedier,

if there is such a thing.

sln

## -----------------------

## ceil/floor equavelent

## -----------------------

use strict;

use warnings;

## test ceil-floor around 0 and between (+-) 2.0 - 3.0

my @Test = qw(

0.0 0.1 0.6

2.0 2.1 2.3 2.4 2.5

2.6 2.7 2.8 2.9 3.0

);

my $y;

for $y (@Test)

{

printf( "The ceil of %s is %f\n", $y, _ceil( $y ) );

printf( "The ceil of -%s is %f\n\n", $y, _ceil( -$y ) );

}

for $y (@Test)

{

printf( "The floor of %s is %f\n", $y, _floor( $y ) );

printf( "The floor of -%s is %f\n\n", $y, _floor( -$y ) );

}

sub _ceil {

my $z = int($_[0]);

return $z if ($

___[0] == $z || $___[0] < 0.0);return $z+1.0;

}

sub _floor {

my $z = int($_[0]);

return $z if ($

___[0] == $z || $___[0] >= 0.0);return $z-1.0;

}

______END______## Re: Rounding up in perl

On Mon, 22 Dec 2008 18:17:17 GMT, sln@netherlands.com wrote:

[snip]

Even better. Random statistics suggests ceil/floor will

not be called on boundries more than otherwise.

Therefore, the speediest solution possible is to check for

otherwise first. This will eliminate unecesarry boundry checks

in conditions that statistically predict other wise.

Speedier still, if there is such a thing.

sub _ceil {

my $z = int($_[0]);

return $z if ($

return $z+1.0;

}

sub _floor {

my $z = int($_[0]);

return $z if ($

return $z-1.0;

}

Typically, this is the least common denominator conditional

logic that would be used in the C library if its not of

a mathematical nature in its assembly derivation.

sln

[snip]

Even better. Random statistics suggests ceil/floor will

not be called on boundries more than otherwise.

Therefore, the speediest solution possible is to check for

otherwise first. This will eliminate unecesarry boundry checks

in conditions that statistically predict other wise.

Speedier still, if there is such a thing.

sub _ceil {

my $z = int($_[0]);

return $z if ($

___[0] < 0.0 || $___[0] == $z);return $z+1.0;

}

sub _floor {

my $z = int($_[0]);

return $z if ($

___[0] >= 0.0 || $___[0] == $z);return $z-1.0;

}

Typically, this is the least common denominator conditional

logic that would be used in the C library if its not of

a mathematical nature in its assembly derivation.

sln

#### Site Timeline

- » Max Execution Time for mod_perl
- — Next thread in » PERL Discussions

- » FAQ 1.2 Who supports Perl? Who develops it? Why is it free?
- — Previous thread in » PERL Discussions

- » s suffix question
- — Newest thread in » PERL Discussions

- » Adblock Testscript problem
- — The site's Newest Thread. Posted in » HTML Markup Language