Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If you want to round to an arbitrary precision and your round method lacks precision control, this should work: </p> <h2>In Perl at least, mod should still be faster </h2> <p>Heres why: Sample of ( 10 ** 7 ) * 3 random floats produced this benchmark: </p> <pre><code>Dividing Time taken was 7 wallclock secs ( 6.83 usr 0.00 sys + 0.00 cusr 0.00 csys = 6.83 CPU) seconds Multiplying Time taken was 7 wallclock secs ( 6.67 usr 0.00 sys + 0.00 cusr 0.00 csys = 6.67 CPU) seconds Modding Time taken was 8 wallclock secs ( 7.87 usr 0.00 sys + 0.00 cusr 0.00 csys = 7.87 CPU) seconds Multiply + Dividing Time taken was 10 wallclock secs (10.18 usr 0.01 sys + 0.00 cusr 0.00 csys = 10.19 CPU) seconds </code></pre> <p>Do note however that <code>10 ** 7 * 3</code> is a <strong>REDICULOUS</strong> number of floats. I couldn't use <code>10**8</code> floats because for a fair test, i had to use the same float sequence for all tests, and that many floats <strong>EXHAUSTED MY 4G OF MEMORY</strong></p> <p><strong>Ok, bit side topic :/ </strong> </p> <p>( Perl Implementation using only Int, which truncates instead of rounding normally ) </p> <pre><code>use strict; use warnings; use version; our $VERSION = qv('0.1'); sub xround { my ( $number, $precision ) = @_ ; if ( $precision eq 0 ) { return int( $number + .5 ); } my $scale = 10 ** abs( $precision ) ; $number = $number / $scale if $precision &gt; 0; $number = $number * $scale if $precision &lt; 0; $number = int( $number + .5 ); $number = $number * $scale if $precision &gt; 0; $number = $number / $scale if $precision &lt; 0; return $number; } my $fmt = "%s : %s ( %s )\n"; my $n = 55555.55555; for my $i ( -4 .. 4 ) { printf $fmt, $n, xround($n, $i), $i; } </code></pre> <p>.</p> <pre><code>55555.55555 : 55555.5556 ( -4 ) 55555.55555 : 55555.556 ( -3 ) 55555.55555 : 55555.56 ( -2 ) 55555.55555 : 55555.6 ( -1 ) 55555.55555 : 55556 ( 0 ) 55555.55555 : 55560 ( 1 ) 55555.55555 : 55600 ( 2 ) 55555.55555 : 56000 ( 3 ) 55555.55555 : 60000 ( 4 ) </code></pre> <h3>using Modulus method</h3> <p>This works as above, ( except without rounding ) using modulus method for ints, but still works for rounding into float precision ( with a bit of a slow-down for precisions right of the decimal point.</p> <pre><code>use strict; use warnings; use version; our $VERSION = qv('0.1'); sub xround { my ( $number, $precision ) = @_; my $ino = int( $number ); if ( $precision eq 0 ) { return $ino; } my $power = 10**$precision; if ( $precision &gt; 0 ) { return int( $number - ( $number % $power ) ); } return $ino + int( ( $number - $ino ) / $power ) * $power; } my $fmt = "%s : %s ( %s )\n"; my $n = 55555.55555; for my $i ( -4 .. 4 ) { printf $fmt, $n, xround($n, $i), $i; } </code></pre> <p>.</p> <pre><code>55555.55555 : 55555.5555 ( -4 ) 55555.55555 : 55555.555 ( -3 ) 55555.55555 : 55555.55 ( -2 ) 55555.55555 : 55555.5 ( -1 ) 55555.55555 : 55555 ( 0 ) 55555.55555 : 55550 ( 1 ) 55555.55555 : 55500 ( 2 ) 55555.55555 : 55000 ( 3 ) 55555.55555 : 50000 ( 4 ) </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload