"be consistent" PerlMonks

### Re^2: Seeing if two numbers have the same sign

by WoodyWeaver (Scribe)
 on Jan 10, 2008 at 23:18 UTC ( #661753=note: print w/replies, xml ) Need Help??

Using

```sub andNeg {
return ((\$_[0]^\$_[1]) < 0);
}
and test harness
```print "<table border>\n<tr><td>", join("</td><td>", "x", "y", "andNeg(
+)", "spaceship()", "mult()", "anchor()"), "</td></tr>\n";
for (0..3) {
my \$x = 1 - 2 * (\$_ % 2);
my \$y = 1 - 2 * int(\$_ / 2);
print "<tr><td>", join("</td><td>", \$x, \$y, andNeg(\$x, \$y), spaceshi
+p(\$x, \$y), mult(\$x, \$y), anchor(\$x, \$y)), "</td></tr>\n";
}
print "</table>\n";
I get
 x y xorNeg() spaceship() mult() anchor() 1 1 1 1 1 -1 1 0 1 -1 0 -1 -1 1 1 1
As for spaceship, multiplication, and logic, implemented as
```sub spaceship {
(0 <=> \$_[0]) == (0<=> \$_[1]);
}

sub mult {
\$_[0]*\$_[1] > 0;
}

sub anchor {
if (\$_[0] > 0) {
if (\$_[1] > 0) { # both pos
return 1
}
} elsif (\$_[0] < 0) {
if (\$_[1] < 0) { # both neg
return 1
}
}
return 0;
}
I get
 unit square spaceship multiply logic spaceship -------- worse 22.28% worse 10.40% multiply better 22.28% -------- better 13.26% logic better 10.40% worse 13.26% --------
and
 signed int spaceship multiply logic spaceship -------- worse 21.43% worse 7.65% multiply better 21.43% -------- better 14.92% logic better 7.65% worse 14.92% --------
that is, if you take points (x,y) uniformly chosen from the unit disk [-1,1]x[-1,1], then spaceship is 22% worse than testing multiplication, multiplication is 13% better than using logic, etc; and if you take them as random unsigned ints, multiplication is (surprisingly!) even better.

full test program (don't use this use Benchmark; instead)

```#!perl -w
#
use Time::HiRes qw(time);

print "<table border>\n<tr><td>", join("</td><td>", "x", "y", "andNeg(
+)", "spaceship()", "mult()", "anchor()"), "</td></tr>\n";
for (0..3) {
my \$x = 1 - 2 * (\$_ % 2);
my \$y = 1 - 2 * int(\$_ / 2);
print "<tr><td>", join("</td><td>", \$x, \$y, andNeg(\$x, \$y), spaceshi
+p(\$x, \$y), mult(\$x, \$y), anchor(\$x, \$y)), "</td></tr>\n";
}
print "</table>\n";

my \$count = 1000000;
for ('unit square', 'signed int') {
doTimeTest(\$count, \$_);
}
sub doTimeTest {
my \$count = shift;
my \$type = shift;

my @coordinates = primeCoordinates(\$count, \$type );
my \$time0 = Time::HiRes::time();
foreach (@coordinates) {
spaceship(\$_->[0],\$_->[1]);
}
my \$time1 = Time::HiRes::time();

foreach (@coordinates) {
mult(\$_->[0], \$_->[1]);
}
my \$time2 = Time::HiRes::time();

foreach (@coordinates) {
anchor(\$_->[0], \$_->[1]);
}

my \$time3 = Time::HiRes::time;

my \$spaceship = \$time1 - \$time0;
my \$multiple = \$time2 - \$time1;
my \$logic = \$time3 - \$time2;
print join("\t", \$type, "spaceship", "multiply", "logic"), "\n";
print join("\t", "spaceship", '-'x8, pretty(\$spaceship,\$multiple), p
+retty(\$spaceship,\$logic)), "\n";
print join("\t", "multiply ", pretty(\$multiple,\$spaceship), '-'x8, p
+retty(\$multiple,\$logic)), "\n";
print join("\t", "logic    ", pretty(\$logic,\$spaceship), pretty(\$log
+ic,\$multiple), '-'x8), "\n";
print "\n";
}

sub pretty {
my (\$one, \$two) = @_;
if (\$one > \$two) {
return sprintf("worse %.2f%%", (\$one - \$two) / \$one * 100);
} else {
return sprintf("better %.2f%%", (\$two - \$one) / \$two * 100);
}
}

sub spaceship {
(0 <=> \$_[0]) == (0<=> \$_[1]);
}

sub mult {
\$_[0]*\$_[1] > 0;
}

sub anchor {
if (\$_[0] > 0) {
if (\$_[1] > 0) { # both pos
return 1
}
} elsif (\$_[0] < 0) {
if (\$_[1] < 0) { # both neg
return 1
}
}
return 0;
}

sub andNeg {
return ((\$_[0]^\$_[1]) < 0);
}

sub primeCoordinates {
my \$count = shift;
my \$type = shift;
my @retval;
if (\$type eq 'unit square') {
for (0..\$count-1) {
\$retval[\$_] = [ 1 - 2 * rand(), 1 - 2 * rand()];
}
} elsif (\$type eq 'signed int') {
use POSIX;
for (0..\$count-1) {
\$retval[\$_] = [ rand() > 0.5 ? rand(INT_MAX) : -1 * rand(INT_MAX
+),
rand() > 0.5 ? rand(INT_MAX) : -1 * rand(INT_MAX
+)];
}
} else {
die "Blue.  No yel--  Auuuuuuuugh!\n";
}
return @retval;
}

Replies are listed 'Best First'.
Re^3: Seeing if two numbers have the same sign
by demerphq (Chancellor) on Jan 11, 2008 at 19:23 UTC

Hmm. I didnt actually test it and had assumed that the result of binary xor was going to be signed, but of course its unsigned, hence the xor ideas doesnt work as written. My bad. Sorry. Id just use the \$x<0 == \$y<0 approach anyway. :-)

---
\$world=~s/war/peace/g

Create A New User
Node Status?
node history
Node Type: note [id://661753]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (2)
As of 2018-01-20 01:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
How did you see in the new year?

Results (226 votes). Check out past polls.

Notices?