Converting milliseconds to seconds

P

Peter J. Holzer

Peter J. Holzer ([email protected]) wrote on VCCL September MCMXCIII in
<URL:}}
}} 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
 
J

Joost Diepenmaat

Jim Gibson said:
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.
 
T

Ted Zlatanov

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
 
P

Peter J. Holzer

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
 
J

Joost Diepenmaat

Abigail said:
_
Joost Diepenmaat ([email protected]) wrote on VCCL September MCMXCIII in
<URL:??
?? > 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.
 
J

Joost Diepenmaat

Abigail said:
_
Joost Diepenmaat ([email protected]) 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.
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Peter J. Holzer
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...

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
 
P

Peter J. Holzer

Joost Diepenmaat ([email protected]) wrote on VCCL September MCMXCIII in
<URL:|| Abigail <[email protected]> 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
 
P

Peter J. Holzer

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Peter J. Holzer
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...

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
 
D

David Combs

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Ilya Zakharevich
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

Am a bit confused about (1) the vocabulary being used
here and (2) about just what this bug you say you created is.

"Round down" (that was the term used earlier in the thread, yes?)
I always thought that had to do relative to a .5 or nearby. Clearly,
I'm wrong, but can someone explain it a bit more fully?

Int for positives meant truncation, I thought.

For negatives, hmmm, what you *want* for int(-3.999)?

Or would some people *reasonably* want one thing and others the other?



And now, for something completely different: Mod on negatives.

I think I recall that some languages and Knuth did it one way,
and other languages another.


And did different fields do it different ways?

(Sorry for asking such totally idiotically "basic" stuff! :)

Thanks,

David
 
B

Ben Morrow

Quoth (e-mail address removed) (David Combs):
Am a bit confused about (1) the vocabulary being used
here and (2) about just what this bug you say you created is.

"Round down" (that was the term used earlier in the thread, yes?)
I always thought that had to do relative to a .5 or nearby. Clearly,
I'm wrong, but can someone explain it a bit more fully?

'Round' is a vague term. The only thing it definitely means is 'convert
a float into an int'; the details of the conversion are left
unspecified. Most people unfamiliar with computer numerics want (or
think they want) 'round to nearest, i+0.5 -> i+1 for all integers i', as
they were taught in school. The most useful general-purpose form is
'round to even', that is 1.4->1, 1.5->2, 2.5->2, as with this form
round(a) + round(b) == round(a + b), which is useful.
Int for positives meant truncation, I thought.

For negatives, hmmm, what you *want* for int(-3.999)?

In C and C-derived languages int means 'round to zero', or truncation,
so int(-3.99) == 3. If people want 'round (strictly) downwards', so
3.5->3 but -3.5->-4, that's POSIX::floor.
Or would some people *reasonably* want one thing and others the other?

Depending on exactly what you're doing, you may want a different answer;
Perl lets you choose the answer you want.
And now, for something completely different: Mod on negatives.

I think I recall that some languages and Knuth did it one way,
and other languages another.

Does $a % $b mean int( int($a) / int($b) ) or does it mean '$r such that
$r is between 0 (inclusive) and $b (exclusive) with $b * $i + $r == $a
for some integer $i'? Perl chooses the latter, so -7 % 2 == 1, not -1.

Ben
 
J

Jürgen Exner

Ben Morrow said:
'Round' is a vague term. The only thing it definitely means is 'convert
a float into an int';

Actually 'convert a float to a specific number of decimals' which may be
zero decimals, but could just as well be any other number of decimals.

jue
 

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
474,209
Messages
2,571,088
Members
47,686
Latest member
sparada

Latest Threads

Top