Converting milliseconds to seconds

Converting milliseconds to seconds

am 11.01.2008 09:11:51 von Ilya Zakharevich

I was stupid enough to write the following subroutine:

sub truncate_ms_to_sec ($) {int(0.001 * shift)}

It was supposed to be used with integer values. All was fine. A
couple of days ago I got a bug report.

My current conjecture is that it is an unfortunate property of 0.001
with 64-bit IEEE numbers. You see: these are results of rounding
0.001 to the machine precision with different length of mantissa:

52 => 0.0010000000000000000208166817117216851329
53 => 0.0010000000000000000208166817117216851329 <== 64-bit IEEE
54 => 0.0010000000000000000208166817117216851329
....
63 => 0.0010000000000000000000643745039913268258
64 => 0.00099999999999999999995849538558453928338 <== 80-bit IEEE
65 => 0.0010000000000000000000114349447879330546

As a result, if you perl is configured to use 64-bit floats, the
result of 0.001 * $n is going to be a tiny bit above the "exact
result". int() would shave the error (since it truncates down).

But with 80-bit IEEE, the result of 0.001 * $n is a tiny bit SMALLER
than the "exact result"; hence if exact value of 0.001 * $n happens to
be an integer, the exact value with machine-precision-0.001 is
slightly smaller than an integer; by IEEE semantic, this exact value
should be rounded to a closest machine-precision value to get the
machine-precision value.

I expect that for some values of $n (obviously, divisible by 1000),
the result of this rounding is "one tick below" an integer; then int()
would shave 1 of this value, so the subroutine returns 1-smaller
value.

In short: the subroutine is buggy, but one would not discover this
with 64-bit IEEE numbers.

Hope this would help somebody, ;-)
Ilya

P.S. in GP/PARI: f(n) = n=n+9; floor(0.001*2^n+0.5)*1./2^n

Re: Converting milliseconds to seconds

am 11.01.2008 14:40:12 von Paul Lalli

On Jan 11, 3:11=A0am, Ilya Zakharevich wrote:
> I was stupid enough to write the following subroutine:
>
> =A0 sub truncate_ms_to_sec ($) {int(0.001 * shift)}
>
> It was supposed to be used with integer values. =A0All was fine. =A0A
> couple of days ago I got a bug report.

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.


perldoc -q round
Does Perl have a round() function? What about ceil() and
floor()? Trig functions?

Remember that int() merely truncates toward 0. For rounding
to a certain number of digits, sprintf() or printf() is
usually the easiest route.


Paul Lalli

Re: Converting milliseconds to seconds

am 12.01.2008 01:20:18 von Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Paul Lalli
], who wrote in article <42484581-f7d1-4e75-b92f-c9ddcfe675c0@m34g2000hsf.googlegroups.com>:
> 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.

This is just a reflection of a sorry state of Perl documentation.
There is NO OTHER WAY to round-to-0 but to use int(). Yes, this may
produce counterintuitive results; NO, there is no better way.

Hope this helps,
Ilya

Re: Converting milliseconds to seconds

am 12.01.2008 01:54:57 von jurgenex

Ilya Zakharevich wrote:
>[A complimentary Cc of this posting was sent to
>Paul Lalli
>], who wrote in article <42484581-f7d1-4e75-b92f-c9ddcfe675c0@m34g2000hsf.googlegroups.com>:
>> 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.
>
>This is just a reflection of a sorry state of Perl documentation.
>There is NO OTHER WAY to round-to-0 but to use int().

Your statement is non sequitur. int() does not an never was supposed to
round a number. If you expect int() to round a number then you are mistaken
about the semantic of this function.

> Yes, this may
>produce counterintuitive results; NO, there is no better way.

Well, there _are_ ways how to round a number in Perl, and because int()
doesn't round in the first place all of them are "better" than int().

>Hope this helps,

Hardly

jue

Re: Converting milliseconds to seconds

am 13.01.2008 00:15:07 von Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Jürgen Exner
], who wrote in article :
> >This is just a reflection of a sorry state of Perl documentation.
> >There is NO OTHER WAY to round-to-0 but to use int().
>
> Your statement is non sequitur. int() does not an never was supposed to
> round a number. If you expect int() to round a number then you are mistaken
> about the semantic of this function.

I assure you that int() does nothing else but rounding-to-0.

Hope this helps,
Ilya

Re: Converting milliseconds to seconds

am 13.01.2008 02:13:24 von someone

Ilya Zakharevich wrote:
> [A complimentary Cc of this posting was sent to
> Jürgen Exner=20
> ], who wrote in article prkke0ktt7@4ax.com>:
>>> This is just a reflection of a sorry state of Perl documentation.
>>> There is NO OTHER WAY to round-to-0 but to use int(). =20
>> Your statement is non sequitur. int() does not an never was supposed t=
o
>> round a number. If you expect int() to round a number then you are mis=
taken
>> about the semantic of this function.
>=20
> I assure you that int() does nothing else but rounding-to-0.

Then why does the documentation say:

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 rather than the correct
-269; that=92s because it=92s 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().


John
--=20
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall

Re: Converting milliseconds to seconds

am 13.01.2008 03:32:32 von jurgenex

Ilya Zakharevich wrote:
>[A complimentary Cc of this posting was sent to
>Jürgen Exner

Please don't do that. I happen to read the NGs in which I am posting.

>], who wrote in article :
>> >This is just a reflection of a sorry state of Perl documentation.
>> >There is NO OTHER WAY to round-to-0 but to use int().
>>
>> Your statement is non sequitur. int() does not an never was supposed to
>> round a number. If you expect int() to round a number then you are mistaken
>> about the semantic of this function.
>
>I assure you that int() does nothing else but rounding-to-0.

As I said: you are greatly mistaken about the intended semantic of int().
You may want to read the documentation for clarification.

jue

Re: Converting milliseconds to seconds

am 13.01.2008 09:36:30 von Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Jürgen Exner
], who wrote in article :
> I happen to read the NGs in which I am posting.

If you think this is enough, you know little about Usenet propagation
semantic. (By definition: unreliable.)

> >I assure you that int() does nothing else but rounding-to-0.

> As I said: you are greatly mistaken about the intended semantic of int().
> You may want to read the documentation for clarification.

As I said, the existing state of documentation of Perl is, at most,
pitiful. (If you still do not realize this, I wrote some
[significant?] part of implementation of Perl's int(). *This* is why
I feel so hurt by this bug of mine. ;-)

Hope this helps,
Ilya

Re: Converting milliseconds to seconds

am 14.01.2008 00:10:17 von t.x.michaels

Ilya,

Thank you for sharing your hard-won information.

It is much appreciated by myself and certainly by others who may not
explicitly say so.

It is still amazing to me to hear of round-off errors and is a
reminder to all to be on guard
when computing numeric results. Experts as well as novices can be
bitten by these evil bugs when
they least expect it.

Thanks again for sharing your knowledge with the rest of us.

T. Michaels

Re: Converting milliseconds to seconds

am 14.01.2008 01:40:36 von Joost Diepenmaat

magoo writes:

> Ilya,
>
> Thank you for sharing your hard-won information.
>
> It is much appreciated by myself and certainly by others who may not
> explicitly say so.
>
> It is still amazing to me to hear of round-off errors and is a
> reminder to all to be on guard
> when computing numeric results. Experts as well as novices can be
> bitten by these evil bugs when
> they least expect it.

While I suspect your post is sarcastic, I do think it's wise to point
out that many people - some even experienced programmers - have a
simplistic (which is to say *wrong*) view of what happens when floating
point numbers are represented in binary (which is what's used by
default in most if not all commerically available computers today).

The basic point is: there are many fractional numbers that can be
notated without errors in decimal (like 0.1) which *cannot* be represented
correctly in the finite binary floating point notation used by most
CPUs, in the same way that 1/3 cannot be notated in a finite decimal
floating point (i.e. 1.3333333..., which by the way can't be correctly
represented in binary either).

This means that some floating point numbers that we tend to think of as
"easy and finite" because of our familiarity with the decimal notation
are not in fact finite to the processor that happens to run the
calculation. Which leads to errors in the result where you may not
expect to find any.

Most languages that go for performance see this as an acceptable
trade-off, at least by default, and perl is one of those languages.

Anyway, all this means that blindly truncating floats (i.e, using int())
to "round down" *will* result in errors. In fact, all rounding
will. We just have a more acute sense of the error when 0.999999999
gets rounded down to 0. To avoid that, use (s)printf to use a more
appropriate rounding rule.

Also note that on my machine at least, sprintf uses "banker's rounding",
which IMHO is a good choice, but can also confuse matters even further.

See also:
http://en.wikipedia.org/wiki/Floating_point
http://en.wikipedia.org/wiki/Banker%27s_rounding

Hope this helps someone at least,
Joost.

Re: Converting milliseconds to seconds

am 14.01.2008 01:42:54 von Joost Diepenmaat

Joost Diepenmaat writes:


> CPUs, in the same way that 1/3 cannot be notated in a finite decimal
> floating point (i.e. 1.3333333..., which by the way can't be correctly
> represented in binary either).

I meant 0.33333333....

Man, these numbers are confusing!

Joost

Re: Converting milliseconds to seconds

am 14.01.2008 02:24:49 von t.x.michaels

Joost,

My post was in no way intended to be sarcastic.

It was my intention only to thank Ilya (for whom I have nothing
but admiration and respect)
for sharing with us the information he did.

How many of us could have written about our own mistakes in a
public forum, with the good
intention of helping others? Not many I suspect, I for one do not
like to publicize my mistakes.

Your post was informative as well, and added more information to
the discussion which is a good
thing. The earlier discussion seemed to be getting bogged down and
headed nowhere.

As you say, numbers and especially their computer representation,
can get confusing!

Best regards,

T. Michaels

On Jan 13, 7:42 pm, Joost Diepenmaat wrote:
> Joost Diepenmaat writes:
> > CPUs, in the same way that 1/3 cannot be notated in a finite decimal
> > floating point (i.e. 1.3333333..., which by the way can't be correctly
> > represented in binary either).
>
> I meant 0.33333333....
>
> Man, these numbers are confusing!
>
> Joost

Re: Converting milliseconds to seconds

am 14.01.2008 04:13:05 von Joost Diepenmaat

magoo writes:

> Joost,
>
> My post was in no way intended to be sarcastic.
>
> It was my intention only to thank Ilya (for whom I have nothing
> but admiration and respect)
> for sharing with us the information he did.

I think he was taking an obviously wrong-headed view of what it was that
was causing the problem, though maybe it could have been explained a bit
clearer to him in this thread.

Anyway, as I said, confusion with regards to floats are common and I don't
blame him or anyone else who makes that mistake.

I also think that perl's documentation could at least include a few (more?)
pointers to explain the issues with floating point representation.

Where I do have a problem is when Ilya claims, quite vehemently, that
this is some sort of bug in perl, while it is purely due to the
inherent inaccuracies in the processor and/or C library that happens to
implement floating point semantics, which you will *have* to learn to
deal with when programming with floats in most any language. In other
words: unless the language you're using is explicitly documented to use
decimal notation for floating points on the platform you're using you
should assume it cannot represent all finite decimal floats, and could
be off in any direction by some amount. Because that is the case for most
languages and processors in use today.

Joost.

Re: Converting milliseconds to seconds

am 14.01.2008 04:22:01 von Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Ilya Zakharevich
], who wrote in article :
> > As I said: you are greatly mistaken about the intended semantic of int().
> > You may want to read the documentation for clarification.

> As I said, the existing state of documentation of Perl is, at most,
> pitiful. (If you still do not realize this, I wrote some
> [significant?] part of implementation of Perl's int(). *This* is why
> I feel so hurt by this bug of mine. ;-)

Thinking about it more, this illusion of grandeur may be a piece of my
imagination ;-). I remember a lot of struggle to make int() and "%"
conformant to `perldoc perlnumber'; I definitely implemented at least
one of these - but I do not remember which.

Sorry,
Ilya

Re: Converting milliseconds to seconds

am 14.01.2008 15:38:43 von jurgenex

Jürgen Exner wrote:
>Ilya Zakharevich wrote:
>>], who wrote in article :
>>> >This is just a reflection of a sorry state of Perl documentation.
>>> >There is NO OTHER WAY to round-to-0 but to use int().
>>>
>>> Your statement is non sequitur. int() does not an never was supposed to
>>> round a number. If you expect int() to round a number then you are mistaken
>>> about the semantic of this function.
>>
>>I assure you that int() does nothing else but rounding-to-0.
>
>As I said: you are greatly mistaken about the intended semantic of int().
>You may want to read the documentation for clarification.

Ilya, you are right.
It would never have occured to me that the term "to round" could be used to
mean truncation of trailing digits without balancing. But according to
friends and Wikipedia this is quite common.
Please accept the appologies of a non-native English speaker.

jue

Re: Converting milliseconds to seconds

am 14.01.2008 21:23:24 von Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Jürgen Exner
], who wrote in article :
> It would never have occured to me that the term "to round" could be used to
> mean truncation of trailing digits without balancing. But according to
> friends and Wikipedia this is quite common.

There are 9 (vairably useful) semantics of finding an integer nearby:

going in direction of -infty (=down)
going in direction of +infty (=up)
going in direction to 0
going in direction away from 0;
going to closest (if ambiguous, one of 4 variants listed above);
going to closest (if ambiguous, to even).

It is very convenient to be able to use one verb to describe them all;
"to round" comes quite handy.

[(The last way is the IEEE way (used in any "serious context"),
"to-closest-or-away-from-0" is the "naive way" (one which they teach
in schools - and not used anywhere else).]

Hope this helps,
Ilya

Re: Converting milliseconds to seconds

am 15.01.2008 15:34:31 von hjp-usenet2

On 2008-01-13 02:32, Jürgen Exner wrote:
> Ilya Zakharevich wrote:
>>[A complimentary Cc of this posting was sent to
>>Jürgen Exner
>
> Please don't do that. I happen to read the NGs in which I am posting.
>
>>], who wrote in article :

[ perldoc -f int: You should not use this function for rounding]

>>> >This is just a reflection of a sorry state of Perl documentation.
>>> >There is NO OTHER WAY to round-to-0 but to use int().
>>>
>>> Your statement is non sequitur. int() does not an never was supposed to
>>> round a number. If you expect int() to round a number then you are mistaken
>>> about the semantic of this function.
>>
>>I assure you that int() does nothing else but rounding-to-0.
>
> As I said: you are greatly mistaken about the intended semantic of int().
> You may want to read the documentation for clarification.

Saying that to Ilya is a bit humorous.

Ilya is completely correct that int does round to 0 (repeat: round to
zero - not round to nearest!). And that is the intended semantics -
perldoc -f int says so: "Returns the integer portion of EXPR".

But I think Ilya is a barking up the wrong tree here:

>>> >This is just a reflection of a sorry state of Perl documentation.
>>> >There is NO OTHER WAY to round-to-0 but to use int().

Of course there is no other way to round-to-0, but the manual is talking
about "rounding" here: And "rounding" without any qualifiers usually
means "round to nearest", not "round to 0".

The entry is still confusing: The hint to use sprintf instead is ok, but
in what way are floor and ceil supposed to be better than int? And the
caveat about decimal/binary confusions isn't really a reason for "don't
use int for rounding" - any rounding method has the same problem.

hp

Re: Converting milliseconds to seconds

am 15.01.2008 15:51:52 von it_says_BALLS_on_your forehead

On Jan 15, 9:34=A0am, "Peter J. Holzer" wrote:
> On 2008-01-13 02:32, Jürgen Exner wrote:
>
> > Ilya Zakharevich wrote:
> >>[A complimentary Cc of this posting was sent to
> >>Jürgen Exner
>
> > Please don't do that. I happen to read the NGs in which I am posting.
>
> >>], who wrote in article rkke0k...@4ax.com>:
>
> [ perldoc -f int: You should not use this function for rounding]
>
> >>> >This is just a reflection of a sorry state of Perl documentation.
> >>> >There is NO OTHER WAY to round-to-0 but to use int(). =A0
>
> >>> Your statement is non sequitur. int() does not an never was supposed t=
o
> >>> round a number. If you expect int() to round a number then you are mis=
taken
> >>> about the semantic of this function.
>
> >>I assure you that int() does nothing else but rounding-to-0.
>
> > As I said: you are greatly mistaken about the intended semantic of int()=
..
> > You may want to read the documentation for clarification.
>
> Saying that to Ilya is a bit humorous.
>
> Ilya is completely correct that int does round to 0 (repeat: round to
> zero - not round to nearest!). And that is the intended semantics -
> perldoc -f int says so: "Returns the integer portion of EXPR".
>
> But I think Ilya is a barking up the wrong tree here:
>
> >>> >This is just a reflection of a sorry state of Perl documentation.
> >>> >There is NO OTHER WAY to round-to-0 but to use int(). =A0
>
> Of course there is no other way to round-to-0, but the manual is talking
> about "rounding" here: And "rounding" without any qualifiers usually
> means "round to nearest", not "round to 0".
>
> The entry is still confusing: The hint to use sprintf instead is ok, but
> in what way are floor and ceil supposed to be better than int? And the
> caveat about decimal/binary confusions isn't really a reason for "don't
> use int for rounding" - any rounding method has the same problem.
>

Ok, so this is a stupid question. What's wrong with the following?

sub round {
my $number =3D shift;
return int($number + .5);
}

Re: Converting milliseconds to seconds

am 15.01.2008 15:56:17 von Abigail

_
Peter J. Holzer (hjp-usenet2@hjp.at) wrote on VCCL September MCMXCIII in
:
}}
}} Of course there is no other way to round-to-0, but the manual is talking
}} about "rounding" here: And "rounding" without any qualifiers usually
}} means "round to nearest", not "round to 0".
}}
}} The entry is still confusing: The hint to use sprintf instead is ok, but
}} in what way are floor and ceil supposed to be better than int? And the
}} caveat about decimal/binary confusions isn't really a reason for "don't
}} use int for rounding" - any rounding method has the same problem.


Neither floor, nor ceil does the same as int.


int: round to 0.
floor: round to -inf.
ceil: round to +inf.
sprintf: round to nearest.


+-------------------------+
| $x |
+-----+------+-----+------+
| 1.2 | -1.2 | 1.7 | -1.7 |
+------------------+-----+------+-----+------+
| int $x | 1 | -1 | 1 | -1 |
+------------------+-----+------+-----+------+
| floor $x | 1 | -2 | 1 | -2 |
+------------------+-----+------+-----+------+
| ceil $x | 2 | -1 | 2 | -1 |
+------------------+-----+------+-----+------+
| sprintf "%d", $x | 1 | -1 | 2 | -2 |
+------------------+-----+------+-----+------+



Abigail
--
$_ = "\nrekcaH lreP rehtona tsuJ"; my $chop; $chop = sub {print chop; $chop};
$chop -> () -> () -> () -> () -> () -> () -> () -> () -> () -> () -> () -> ()
-> () -> () -> () -> () -> () -> () -> () -> () -> () -> () -> () -> () -> ()

Re: Converting milliseconds to seconds

am 15.01.2008 16:06:34 von it_says_BALLS_on_your forehead

On Jan 15, 9:51=A0am, nolo contendere wrote:
> On Jan 15, 9:34=A0am, "Peter J. Holzer" wrote:
>
>
>
> > On 2008-01-13 02:32, Jürgen Exner wrote:
>
> > > Ilya Zakharevich wrote:
> > >>[A complimentary Cc of this posting was sent to
> > >>Jürgen Exner
>
> > > Please don't do that. I happen to read the NGs in which I am posting.
>
> > >>], who wrote in article 2prkke0k...@4ax.com>:
>
> > [ perldoc -f int: You should not use this function for rounding]
>
> > >>> >This is just a reflection of a sorry state of Perl documentation.
> > >>> >There is NO OTHER WAY to round-to-0 but to use int(). =A0
>
> > >>> Your statement is non sequitur. int() does not an never was supposed=
to
> > >>> round a number. If you expect int() to round a number then you are m=
istaken
> > >>> about the semantic of this function.
>
> > >>I assure you that int() does nothing else but rounding-to-0.
>
> > > As I said: you are greatly mistaken about the intended semantic of int=
().
> > > You may want to read the documentation for clarification.
>
> > Saying that to Ilya is a bit humorous.
>
> > Ilya is completely correct that int does round to 0 (repeat: round to
> > zero - not round to nearest!). And that is the intended semantics -
> > perldoc -f int says so: "Returns the integer portion of EXPR".
>
> > But I think Ilya is a barking up the wrong tree here:
>
> > >>> >This is just a reflection of a sorry state of Perl documentation.
> > >>> >There is NO OTHER WAY to round-to-0 but to use int(). =A0
>
> > Of course there is no other way to round-to-0, but the manual is talking=

> > about "rounding" here: And "rounding" without any qualifiers usually
> > means "round to nearest", not "round to 0".
>
> > The entry is still confusing: The hint to use sprintf instead is ok, but=

> > in what way are floor and ceil supposed to be better than int? And the
> > caveat about decimal/binary confusions isn't really a reason for "don't
> > use int for rounding" - any rounding method has the same problem.
>
> Ok, so this is a stupid question. What's wrong with the following?
>
> sub round {
> =A0 =A0 my $number =3D shift;
> =A0 =A0 return int($number + .5);
>
> }
>
>

Well, for positive numbers, I mean.

Re: Converting milliseconds to seconds

am 15.01.2008 17:36:17 von Joost Diepenmaat

nolo contendere writes:
> On Jan 15, 9:51 am, nolo contendere wrote:
>> Ok, so this is a stupid question. What's wrong with the following?
>>
>> sub round {
>>     my $number = shift;
>>     return int($number + .5);
>>
>> }
>>
>>
>
> Well, for positive numbers, I mean.

It does a naive round to nearest: it rounds x + 0.5 to x+1 for *all
integers* x. In other words, it's biased: round(0) + round(0.5) +
round(1) + round(1.5) == 4. while you would really rather want it to be
2. That sort of bias can really affect your statistical or financial
calculations.

Generally this is "solved" by rounding to the nearest even number in
the (int+0.5) case. Which is what sprintf does on my system. Note that
this is only really a working strategy when the numbers you're rounding
have a reasonable range (i.e. it's still biased when your numbers are
in range 0 .. 1 for example).

See:
http://en.wikipedia.org/wiki/Banker%27s_rounding#Round-to-ev en_method

Joost.

Re: Converting milliseconds to seconds

am 15.01.2008 18:51:40 von hjp-usenet2

On 2008-01-15 14:56, Abigail wrote:
> Peter J. Holzer (hjp-usenet2@hjp.at) wrote on VCCL September MCMXCIII in
>:
> }}
> }} Of course there is no other way to round-to-0, but the manual is talking
> }} about "rounding" here: And "rounding" without any qualifiers usually
> }} means "round to nearest", not "round to 0".
> }}
> }} The entry is still confusing: The hint to use sprintf instead is ok, but
> }} in what way are floor and ceil supposed to be better than int? And the
> }} caveat about decimal/binary confusions isn't really a reason for "don't
> }} use int for rounding" - any rounding method has the same problem.
>
>
> Neither floor, nor ceil does the same as int.

True. But what does that have to do with anything I wrote?

hp

Re: Converting milliseconds to seconds

am 15.01.2008 19:16:47 von Jim Gibson

In article , Abigail
wrote:

> _
> Peter J. Holzer (hjp-usenet2@hjp.at) wrote on VCCL September MCMXCIII in
> :
> }}
> }} Of course there is no other way to round-to-0, but the manual is talking
> }} about "rounding" here: And "rounding" without any qualifiers usually
> }} means "round to nearest", not "round to 0".
> }}
> }} The entry is still confusing: The hint to use sprintf instead is ok, but
> }} in what way are floor and ceil supposed to be better than int? And the
> }} caveat about decimal/binary confusions isn't really a reason for "don't
> }} use int for rounding" - any rounding method has the same problem.
>
>
> Neither floor, nor ceil does the same as int.
>
>
> int: round to 0.
> floor: round to -inf.
> ceil: round to +inf.
> sprintf: round to nearest.


What would be a good round() function that "rounds-to-nearest-even"?
Would using sprintf in this function slow it down? Is there any chance
such a function could be included as a built-in function in a future
Perl?

Inquiring (but too lazy to do the work themselves) minds want to know.

--
Jim Gibson

Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com

Re: Converting milliseconds to seconds

am 15.01.2008 19:38:26 von Joost Diepenmaat

Jim Gibson writes:

> In article , Abigail
> wrote:
>
>> _
>> Peter J. Holzer (hjp-usenet2@hjp.at) wrote on VCCL September MCMXCIII in
>> :
>> }}
>> }} Of course there is no other way to round-to-0, but the manual is talking
>> }} about "rounding" here: And "rounding" without any qualifiers usually
>> }} means "round to nearest", not "round to 0".
>> }}
>> }} The entry is still confusing: The hint to use sprintf instead is ok, but
>> }} in what way are floor and ceil supposed to be better than int? And the
>> }} caveat about decimal/binary confusions isn't really a reason for "don't
>> }} use int for rounding" - any rounding method has the same problem.
>>
>>
>> Neither floor, nor ceil does the same as int.
>>
>>
>> int: round to 0.
>> floor: round to -inf.
>> ceil: round to +inf.
>> sprintf: round to nearest.
>
>
> What would be a good round() function that "rounds-to-nearest-even"?

sprintf would work, but I'm not 100% sure it rounds to even on every
platform (it uses C's sprintf()). It works on my debian/x86 system though.

> Would using sprintf in this function slow it down?

Probably, but sprintf is more generic than a plain round anyway, since
it rounds to arbitrary decimal positions, and you can't use floats for
that so you'd have to use strings (since perl doesn't have native
rational numbers).

> Is there any chance
> such a function could be included as a built-in function in a future
> Perl?

Haven't heard of any plans (but that doesn't mean much). I'm still kind
of surprised that perl doesn't have round/floor/ceil in the base
language, but I suspect adding them now (before perl 6) would clash with
existing code.

Math::Round is on CPAN though :)

Joost.

Re: Converting milliseconds to seconds

am 15.01.2008 20:16:50 von Ted Zlatanov

On 15 Jan 2008 14:56:17 GMT Abigail wrote:

A> int: round to 0.
A> floor: round to -inf.
A> ceil: round to +inf.
A> sprintf: round to nearest.


A> +-------------------------+
A> | $x |
A> +-----+------+-----+------+
A> | 1.2 | -1.2 | 1.7 | -1.7 |
A> +------------------+-----+------+-----+------+
A> | int $x | 1 | -1 | 1 | -1 |
A> +------------------+-----+------+-----+------+
A> | floor $x | 1 | -2 | 1 | -2 |
A> +------------------+-----+------+-----+------+
A> | ceil $x | 2 | -1 | 2 | -1 |
A> +------------------+-----+------+-----+------+
A> | sprintf "%d", $x | 1 | -1 | 2 | -2 |
A> +------------------+-----+------+-----+------+

This should be in the `perldoc -f sprintf' page.

Ted

Re: Converting milliseconds to seconds

am 15.01.2008 21:07:03 von hjp-usenet2

On 2008-01-15 18:16, Jim Gibson wrote:
> In article , Abigail
> wrote:
>> Peter J. Holzer (hjp-usenet2@hjp.at) wrote on VCCL September MCMXCIII in
>> :
>> }}
>> }} Of course there is no other way to round-to-0, but the manual is talking
>> }} about "rounding" here: And "rounding" without any qualifiers usually
>> }} means "round to nearest", not "round to 0".
>> }}
>> }} The entry is still confusing: The hint to use sprintf instead is ok, but
>> }} in what way are floor and ceil supposed to be better than int? And the
>> }} caveat about decimal/binary confusions isn't really a reason for "don't
>> }} use int for rounding" - any rounding method has the same problem.
>>
>>
>> Neither floor, nor ceil does the same as int.
>>
>>
>> int: round to 0.
>> floor: round to -inf.
>> ceil: round to +inf.
>> sprintf: round to nearest.
>
>
> What would be a good round() function that "rounds-to-nearest-even"?
> Would using sprintf in this function slow it down?

sprintf is surprisingly fast. I wrote a little benchmark program (see
below) with a mathetically correct (round to nearest, round to even on
tie), two "naive" implementations and sprintf (which is also correct on
my machine). As expected, the correct version is the slowest. But
sprintf is not only the fastest, it is almost twice as fast as the next
one:

nearest_even: 47.640588
naive_floor: 27.722728
naive_int: 34.791525
sprintf: 18.669429



> Is there any chance such a function could be included as a built-in
> function in a future Perl?

A round() function written C (or assembler) could be quite a bit faster
than sprintf. But whether that makes a real difference depends on the
time your program spends rounding.


#!/usr/bin/perl
use warnings;
use strict;
use Time::HiRes qw(time);
use POSIX qw(floor);

{
sub nearest_even {
my $x = $_[0];
my $f = floor($x);
return $x - $f < 0.5 ? $f :
$x - $f > 0.5 ? $f + 1 :
$f % 2 == 0 ? $f :
$f + 1 ;
}

my $t0 = time;

for (my $x = -1_000_000; $x <= 1_000_000; $x += 0.0625) {
my $y = nearest_even($x);
# print "$x -> $y\n";
}

printf "nearest_even: %f\n", time - $t0;
}

{
sub naive_floor {
return floor($_[0] + 0.5);
}

my $t0 = time;

for (my $x = -1_000_000; $x <= 1_000_000; $x += 0.0625) {
my $y = naive_floor($x);
# print "$x -> $y\n";
}

printf "naive_floor: %f\n", time - $t0;
}

{
sub naive_int {
my $x = shift;
return $x >= 0 ? int($x + 0.5) : int($x - 0.5);
}

my $t0 = time;

for (my $x = -1_000_000; $x <= 1_000_000; $x += 0.0625) {
my $y = naive_int($x);
# print "$x -> $y\n";
}

printf "naive_int: %f\n", time - $t0;
}

{
my $t0 = time;

for (my $x = -1_000_000; $x <= 1_000_000; $x += 0.0625) {
my $y = sprintf("%.0f", $x);
# print "$x -> $y\n";
}

printf "sprintf: %f\n", time - $t0;
}
__END__

hp

Re: Converting milliseconds to seconds

am 15.01.2008 23:42:25 von Abigail

_
Joost Diepenmaat (joost@zeekat.nl) wrote on VCCL September MCMXCIII in
:
?? Jim Gibson writes:
??
?? > What would be a good round() function that "rounds-to-nearest-even"?
??
?? sprintf would work, but I'm not 100% sure it rounds to even on every
?? platform (it uses C's sprintf()). It works on my debian/x86 system though.

It doesn't, unless you have a really, really old perl. Modern Perls
only use the systems sprintf for floating numbers, when using standard
modifiers. But in this case, we're using "%d".

?? > Would using sprintf in this function slow it down?

Of course. But then, you're taking a huge speed penalty by your decision
to write your program in Perl in the first place, so I doubt this difference
will really matter.

?? > Is there any chance
?? > such a function could be included as a built-in function in a future
?? > Perl?

Almost zero, I'd say. Even if there was a real need for a fast function,
there would be no need to do this as a build-in. You can do all the logic
in an XS or Inline::C module.

Feel free to write one and upload in on CPAN.



Abigail
--
BEGIN {print "Just " }
CHECK {print "another "}
END {print "Hacker\n"}
INIT {print "Perl " }

Re: Converting milliseconds to seconds

am 15.01.2008 23:52:51 von Joost Diepenmaat

Abigail writes:

> _
> Joost Diepenmaat (joost@zeekat.nl) wrote on VCCL September MCMXCIII in
> :
> ?? Jim Gibson writes:
> ??
> ?? > What would be a good round() function that "rounds-to-nearest-even"?
> ??
> ?? sprintf would work, but I'm not 100% sure it rounds to even on every
> ?? platform (it uses C's sprintf()). It works on my debian/x86 system though.
>
> It doesn't, unless you have a really, really old perl. Modern Perls
> only use the systems sprintf for floating numbers, when using standard
> modifiers. But in this case, we're using "%d".

Heh. I always use %1.0f :-)

Joost.

Re: Converting milliseconds to seconds

am 16.01.2008 00:10:51 von Abigail

_
Joost Diepenmaat (joost@zeekat.nl) wrote on VCCL September MCMXCIII in
:
|| Abigail writes:
||
|| > _
|| > Joost Diepenmaat (joost@zeekat.nl) wrote on VCCL September MCMXCIII in
|| > :
|| > ?? Jim Gibson writes:
|| > ??
|| > ?? > What would be a good round() function that "rounds-to-nearest-even"?
|| > ??
|| > ?? sprintf would work, but I'm not 100% sure it rounds to even on every
|| > ?? platform (it uses C's sprintf()). It works on my debian/x86 system though.
|| >
|| > It doesn't, unless you have a really, really old perl. Modern Perls
|| > only use the systems sprintf for floating numbers, when using standard
|| > modifiers. But in this case, we're using "%d".
||
|| Heh. I always use %1.0f :-)


But that doesn't always give the same result as %d:

$ perl -wE 'printf "%d\n" => -0.1'
0
$ perl -wE 'printf "%1.0f\n" => -0.1'
-0


Abigail
--
map{${+chr}=chr}map{$_=>$_^ord$"}$=+$]..3*$=/2;
print "$J$u$s$t $a$n$o$t$h$e$r $P$e$r$l $H$a$c$k$e$r\n";

Re: Converting milliseconds to seconds

am 16.01.2008 00:12:05 von Joost Diepenmaat

Abigail writes:

> _
> Joost Diepenmaat (joost@zeekat.nl) wrote on VCCL September MCMXCIII in
> || Heh. I always use %1.0f :-)
>
> But that doesn't always give the same result as %d:
>
> $ perl -wE 'printf "%d\n" => -0.1'
> 0
> $ perl -wE 'printf "%1.0f\n" => -0.1'
> -0

Well, I guess this should be added to the docs :-)

Joost.

Re: Converting milliseconds to seconds

am 16.01.2008 00:20:38 von Abigail

_
Joost Diepenmaat (joost@zeekat.nl) wrote on VCCL September MCMXCIII in
:
:) Abigail writes:
:)
:) > _
:) > Joost Diepenmaat (joost@zeekat.nl) wrote on VCCL September MCMXCIII in
:) > || Heh. I always use %1.0f :-)
:) >
:) > But that doesn't always give the same result as %d:
:) >
:) > $ perl -wE 'printf "%d\n" => -0.1'
:) > 0
:) > $ perl -wE 'printf "%1.0f\n" => -0.1'
:) > -0
:)
:) Well, I guess this should be added to the docs :-)


Patches welcome.


Abigail
--
perl -le 's[$,][join$,,(split$,,($!=85))[(q[0006143730380126152532042 307].
q[41342211132019313505])=~m[..]g]]e and y[yIbp][HJkP] and print'

Re: Converting milliseconds to seconds

am 16.01.2008 02:05:09 von Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Peter J. Holzer
], who wrote in article :
> But I think Ilya is a barking up the wrong tree here:

Well, at least it was not the intent. Sorry if my writing lead you to
such a conclusion...

> >>> >This is just a reflection of a sorry state of Perl documentation.
> >>> >There is NO OTHER WAY to round-to-0 but to use int().

I reread what I wrote, and I STILL see no ambiguity in my original
post; what I objected to is "two", not "one", in the following fragment

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.

Yours,
Ilya

Re: Converting milliseconds to seconds

am 16.01.2008 12:46:34 von hjp-usenet2

On 2008-01-15 23:10, Abigail wrote:
> Joost Diepenmaat (joost@zeekat.nl) wrote on VCCL September MCMXCIII in
>:
>|| Abigail writes:

[rounding FP numbers with sprintf]

>|| > But in this case, we're using "%d".
>||
>|| Heh. I always use %1.0f :-)
>
>
> But that doesn't always give the same result as %d:
>
> $ perl -wE 'printf "%d\n" => -0.1'
> 0
> $ perl -wE 'printf "%1.0f\n" => -0.1'
> -0

More importantly:

% perl -e 'printf "%.0f\n", 1E10'
10000000000
% perl -e 'printf "%d\n", 1E10'
-1

So, I think I'll stay with %.0f.

hp

Re: Converting milliseconds to seconds

am 16.01.2008 13:08:03 von hjp-usenet2

On 2008-01-16 01:05, Ilya Zakharevich wrote:
> [A complimentary Cc of this posting was NOT [per weedlist] sent to
> Peter J. Holzer
>], who wrote in article :
>> But I think Ilya is a barking up the wrong tree here:
>
> Well, at least it was not the intent. Sorry if my writing lead you to
> such a conclusion...
>
>> >>> >This is just a reflection of a sorry state of Perl documentation.
>> >>> >There is NO OTHER WAY to round-to-0 but to use int().
>
> I reread what I wrote, and I STILL see no ambiguity in my original
> post; what I objected to is "two", not "one", in the following fragment
>
> 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.

Right. I agree completely that "two because machine representations ..."
is not a valid reason for "don't use this function for rounding".

(And I also reread your post again and I still don't see that you were
refering to that point specifically - but lets not start quibbling about
that. You got your point across and if it took two postings instead of
one to make yourself clear, that's not a problem (I wish I could always
make myself understood in two postings - sometimes an entire thread
doesn't seem to be sufficient).)

hp