The errata list is a list of errors and their corrections that were found after the product was released.
The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.
Version |
Location |
Description |
Submitted by |
Date submitted |
Printed |
Page 1,2
(4,2), and (5,4). |
The magnitude of the cross product of the vectors [4,2]x[1,2] is the area of
that parallelogram, which is the determinant.
This *does* correspond to the area of a rectangle (still not a square), but
not one with vertices at (1,2), (4,2). Again, I'll illustrate with a simpler
case:
Draw a parallelogram with vertices (0,0), (1,1), (3,1), (2,0). The area is,
again, given by a determinant built from the components of the vectors [1,1]
and [2,0].
| 1 1 |
| 2 0 |
If you shear the parallelogram top leftwards, you can create a rectangle with
the same area, with vertices at (0,0), (0,1), (2,1), (2,0).
Notice that this is not a rectangle with any vertex at (1,1).
The treatment of "Polygon Area" on pp. 430-432 assumes this section is
correct, and so also needs a rewrite.
|
Anonymous |
|
Printed |
Page 1, 2, 2, 5, 3, 1, 2, 1
hangs the algorithm. |
|
Anonymous |
|
Printed |
Page 2, 3
(i.e. a reference to an anonymous array, effectively, since any private |
variables will have passed out of scope), which would be more unwieldy than
returning the median. This would mean that either single modes would have to
be passed back in referenced arrays or as scalars, with the programmer than
differentiating between a reference and a numeric scalar themself, both of
which are somewhat more difficult than the current option. However, this
*would* be the correct answer, since the mode is *all* of the most common
values, and not just the median thereof.
I hope this is of some use, even if it means a far more unwieldy algorithm
being used, or presented as an alternative use.
|
Anonymous |
|
PDF |
Page 2+3, prob. others too
Code section for BINARY-SEARCH algorithm, lines 2/3/4/6/8 |
The leftward arrows found in the printed version of the book aren't displayed correctly or at all in multiple PDF reader applications: Preview v5.0.3, Adobe Acrobat Pro v11.0.04, Adobe Acrobat Pro 10.1.8 on Mac OS X 10.6.8 = nothing displayed at all (looks like a double space there), iBooks v3.1.1 on iOS 5.1.1 = replaced with X in a rectangle symbol. Probably the same also in other code listings throughout the book where this arrow is used.
|
Julian R. |
Sep 22, 2013 |
Printed |
Page 3
pseudocode, line 6 |
|
Anonymous |
|
Printed |
Page 3,3
and (2,3) (d) (2,3), 0,3) and ((0,2). Now the areas of these triangles are 0.5, |
2, 0.5 and 1 sq. units respectively. So the area of the pentagon is 9 - (0.5+2+0.5+1)
= 5.
Also, there is a better algorithm for finding the area of a polygon.
Stated simply, it is as follows:
1. List the points in order (clockwise or anti-clockwise)and append the first point
to the end of the list.
2. Against each point tabulate product of y value against the x value of the previous
point.
3. Against each point tabulate the product of x value against the y value of the
previous point.
4. Sum the tabulations and take half of the diffrence of these sums,
which is the area of the polygon.
Example: Polygon (0,1), (1,0), (3,2), (2,3) and (0,2).
Working:
x y
0 1
1 1 0 0
0 3 2 2
0 2 3 9
4 0 2 4
0 0 1 0
------------------
5 15
The area of the polygon is abs(15 -5)/2 = 5.
This works all polygons, whether convex or concave.
This algorithm is quite easy to implement also!
|
Anonymous |
|
Printed |
Page 9
last line |
|
Anonymous |
|
Printed |
Page 12
Comment in quadratic() function |
The comment "Compute the larger root of a quadratic polynomial" isn't correct.
The root found isn't necessarily the larger one. For instance:
f(x) = -x^2 + 2x + 3
The roots are 3 and -1, and the subroutine will return -1.
|
Anonymous |
|
Printed |
Page 12
last line of the code sample |
I believe the last line of the code sample contains an error. My copy of the
book has:
bruteforce => 'forloop(0, 1)' });
However, I believe that the word forloop should be changed to "bruteforce" so
the code looks like:
bruteforce => bruteforce(0, 1)' });
|
Anonymous |
|
Other Digital Version |
21
Online code sample |
The correction of the constant from 1.5... to 6.28318530718 has not been made in the code "factorial" provided online.
Also, the recursive and approximate versions return 0 for the value of 0!, rather than 1.
(I will try to provide corrected code later.)
|
Anonymous |
May 14, 2012 |
Other Digital Version |
21
|
Revised version of "factorial_recursive" and "factorial_approx"
#! /usr/bin/perl
use 5.10.0;
my $n = 3;
say factorial($n);
say factorial_recursive($n);
say factorial_approx($n);
## factorial($n) computes the factorial of $n,
# using an iterative algorithm.
sub factorial {
my ($n) = shift;
my ($result, $i) = (1, 2);
for ( ; $i <= $n; $i++) {
$result *= $i;
}
return $result;
}
# factorial_recursive($n) computes the factorial of $n,
# using a recursive algorithm.
sub factorial_recursive {
my ($n) = shift;
return $n * factorial_recursive($n - 1) if $n > 2;
return 1 if $n == 0;
return $n if $n <= 2;
}
sub factorial_approx {
return 1 if $_[0] == 0;
return sqrt (6.28318530718 * $_[0]) *
(($_[0] / 2.71828182845905) ** $_[0]);
}
|
Anonymous |
May 14, 2012 |
Printed |
Page 84
code |
Original print
# ? $cmp->($val, $tree->{val})
# : $val <=> $tree->{val};
should be
? $cmp->($tree->{val},$val)
: $tree->{val} <=> $val;
if ( $relation != 0 ) {
# Not this node, go down the tree.
|
Anonymous |
Mar 20, 2012 |
Printed |
Page 85
5th line from top |
The comment says "node" could be undef, but it can't.
|
Anonymous |
|
Printed |
Page 112
Fourth code block: |
need a space before the closing paren.
|
Anonymous |
|
Printed |
Page 129
Source code for Insertion Sort |
The source code for Insertion Code has Theta(N^2) best-case performance, not Theta(N) as described in the paragraph below. The outer loop ALWAYS runs from 0 to N-1 and, for each iteration, the inner loop runs from i+1 to N-1, for a total of N*(N-1)/2 comparisons (regardless of the distribution of the input data).
|
Carlos Joa |
Jan 09, 2015 |
Printed |
Page 133
middle of figure 4-6 |
caption for "d" should be "shell = 2"
|
Anonymous |
|
Printed |
Page 136
middle |
The statements "my $high = $index * 2 + 1" and "my $try = $index * 2" should be changed to instead read "my $high = $index *2 + 2" and "my $try = $index * 2 + 1".
When I run the sample code that I downloaded from the site, it produces the correct final output. But upon closer inspection, the intermediate state is wrong. Check the order of @$array after the first pass in heapsort(), but before the second pass (that is, after the first foreach loop containing the first call to heapify(), but before the second foreach loop containing the second call to heapify()). There are two instances where the parent is not larger than one of its children, but should be.
In case the sample code on the site has changed, the sample input it was using (when I downloaded it) was, "I have a holographic chocolate bar. No really. I'm supposed to save it because it's like art or something. But I'm really hungry and I've been checking these examples all day. I think I deserve a reward."
I'm not sure whether minor errors the intermediate state ultimately don't matter, and if the second heapify() pass will always smooth them out, or if we just got lucky with the sample input that was chosen.
|
Paul DeLong |
Jul 20, 2009 |
Printed |
Page 146
the fourth line of the source code |
for ( my $i = length $array->[ 0 ] - 1; $i >= 0; $i-- ) {
seems should be
for ( my $i = length ($array->[ 0 ]) - 1; $i >= 0; $i-- ) {
|
Anonymous |
|
Printed |
Page 156
It says that Shell's sort is stable, it isn't unless the only h-sort |
pass is h=1, which would then be called Insertion Sort, and that is not
Shell's sort. If you don't believe me, se Table 1 P.382 of "The Art...,
Volume 3: Sorting and Searching", 2nd Ed. Also, there is a missing ')' on the
Shell's sort line of Table 4-2.
|
Anonymous |
|
Printed |
Page 163
source code in ora.com |
The @keywords array is not sorted even when they say on page 162:
The prerequisite for a binary search is that the
collection must be already sorted.
|
Anonymous |
|
Printed |
Page 163
sub binary_string function |
In the subroutine binary_string:
my ($low, $high) = (0, calar@$array));
should be:
my ($low, $high = (0, scalar(@$array));
|
Anonymous |
|
Printed |
Page 196
middle of table |
|
Anonymous |
|
Printed |
Page 196
middle of table |
|
Anonymous |
Feb 16, 2015 |
Printed |
Page 200
Chart and first line of text following chart |
The conclusion for the branch and bound algorithm states that the best route
goes thru Wolfbane Corners. It should be Sula Junction. Also, the run chart
shows the cost of urchin -> wolfbane corners -> sula center to be 44, it
should be 46.
|
Anonymous |
|
Printed |
Page 200
1st paragraph |
Best route from Urchin to Sula Center is to go through "Sula Junction", not
through "Wolfbane Corners." And, on the chart right above the paragraph, the
'Cost So Far' column of the route Urchin->Wolfbane Corners -> Sula Center
should be 56, not 44 as in the book, nor 46 which a reader pointed out on the
unconfirmed errata.
|
Anonymous |
|
Printed |
Page 205
4th line from bottom |
delete $Mammal { platypus } # Nor is platypus a mammal
This is incorrect; the Platypus is a mammal. It is warm blooded, has fur and
lactates.
|
Anonymous |
|
Printed |
Page 215
middle of the page |
The second and third versions of sub union() are wrong.
The expected return value is a hashref where
the keys are the elements of the set and the
values are either undef or 1 or anything - it does not matter.
The anonymous hash that is returned from the
second and third versions of union() is initialized
with keys only, no values. The value of
the first key would be the second key. Not what
was intended!
Something like this would be correct:
sub union {+{
map { $_, () }
map { keys %$_ }
@_
}}
|
Anonymous |
|
Printed |
Page 245
3rd paragraph |
The line:
(Perl Data Language) module, a huge package...
should be
PDL (Perl Data Language) module, a huge package...
|
Anonymous |
Feb 16, 2015 |
Printed |
Page 246
last two lines |
"$row" and "$column" should be switched.
should read:
$elem = at($matrix, $column, $row); # access
set($matrix, $column, $row, $value); # modify
|
Anonymous |
|
Printed |
Page 262
3rd paragraph under "Computing the Determinant" |
"A 2x2 matrix defines a square (and the determinant gives
its area)"
I think this is confused.
A 2x2 matrix defines a parallelogram. The easiest ones to think about are
ones with only positive values for the coordinates, so I'll do that case.
The pair (1,2), (4,2) defines a parallelogram whose vertices are at (0,0),
|
Anonymous |
|
Printed |
Page 277
I think the display of ASCII representation on the graph |
print "g = $g
";
a-b,b-c,c-d,d-e
should be:
print "g = $g
";
a-c,b-c,c-d
|
Anonymous |
|
Printed |
Page 277
2nd paragrah |
I also agree with another readers' comment that the ASCII representation for Figure 8-4 should be:
g = a-c,b-c,c-d
There's no edge defined between vertices a and b. The inclusion of a-b in the list of edges is incorrect.
|
Anonymous |
|
Printed |
Page 290
Figure 8-24 |
Found this in the August 1999 edition of the book:
The {Pred} part in the Perl representation of Graph G is possibly incorrect, IMHO.
It should be:
$G->{Pred}->{c} = ['a']
and
$G->{Pred}->{d} = ['c', 'c', 'b']
instead of
$G->{Pred}->{c} = ['a', 'b']
and
$G->{Pred}->{d} = ['c', 'c']
|
Anonymous |
|
Printed |
Page 299
Final paragraph |
The "" operator is not overloaded in the base class. Delete
from the word "all" to the end of the line in the first sentence
of the final paragraph. The complete first sentence of the
final paragraph should read:
We overload the "" operator in the two derived classes, Graph::Directed
and Graph::Undirected.
|
Anonymous |
|
Printed |
Page 311
Paragraph 3 |
Now reads:
"at most two of the vertex degrees If there are...",
Should read:
"at most two of the vertices have odd degrees. If there are..."
|
Anonymous |
|
Printed |
Page 315
Figure 8-17 |
error in the First Edition, Aug 1999
Since there is no node 'f' in the picture,
there should be no node 'f' mentioned in the annotations.
|
Anonymous |
|
Printed |
Page 321
sample code articulation_points |
Code fragment below is in Error. The line:
my $v = $T[ -$i ];
is wrong, should be:
my $v = $S[ -$i ];
I tested and works fine.
------------------------------------
my $articulate =
sub {
my ( $u, $T ) = @_;
my $ap = $T->{ vertex_found }->{ $u };
my @S = @{ $T->{ active_list } }; # Current stack.
$T->{ articulation_point }->{ $u } = $ap
unless exists $T->{ articulation_point }->{ $u };
# Walk back the stack marking the active DFS branch
# (below $u) as belonging to the articulation point $ap.
for ( my $i = 1; $i < @S; $i++ ) {
my $v = $T[ -$i ];
last if $v eq $u;
$T->{ articulation_point }->{ $v } = $ap
if not exists $T->{ articulation_point }->{ $v } or
$ap < $T->{ articulation_point }->{ $v };
}
};
|
Anonymous |
|
Printed |
Page 326-329
Reading through the section on Kruskal's Algorithm (also known as |
the Greedy Algoithm), I was perusing the pseudo-code for it, page 326. The
worked example, on page 328, does not appear to be in error, but the
pseudo-code is, somewhat.
Assuming that I have the following graph:
A-B 2
A-B 4
A-C 2
B-C 2
Using the pseudo-code, I take an edge in my graph, G, that would not create a
cycle - I choose A-B with a weight of 4, which is perfectly legitimate by the
pseudo-code, which specifies nothing else. As my next edge, I choose A-C with
a weight of 2. Both of the other edges create cycles, so I finish. I now
have my Minimum Spanning Tree with a total weight of 6, which is clearly
wrong, since A-C 2 and B-C 2 (as one option) create an MST with a weight of 4.
The pseudo-code needs to be altered to reflect the fact that, when passing
through the list of edges, they need to be taken in weight order, starting
with the least and working upwards, with any edges of equal weight having an
arbitrary order (e.g. if I were to be listing my edges above in weight order,
it would be inconsequential whether I listed B-C 2 before A-C 2).
As I say, the worked example on 328 reflects this perfectly, and the code
MST_Kruskal on page 329 contains the section "Sort by weights", so hopefully
no-one has been confused, but I thought I should submit this for completeness
sake, given that some of those reading the section may never have encountered
Kruskal's algorithm in a non-computer based setting and so may be confused by
the disparity. I hope this is of use.
|
Anonymous |
|
Printed |
Page 343
transitive-closure pseudocode |
n[ i ][ j ] =
m[ i ][ k ] ||
( m[ i ][ k ] && m[ k ][ j ] )
should be:
n[ i ][ j ] =
m[ i ][ j ] ||
( m[ i ][ k ] && m[ k ][ j ] )
|
Anonymous |
|
Printed |
Page 344
After the comment # Do the O(N**3) loop |
I think there is a significant optimization to be had in
Graph::Base::TransitiveClosure_Floyd_Warshall.
The speedup is sufficient (hours become minutes, in my case), that it could be
construed as an error.
Consider the central loop:
# Do the O(N**3) loop.
for ( my $k = 0; $k < @V; $k++ ) {
my @nC = ( '' ) x @V; # new @C
for ( my $i = 0; $i < @V; $i++ ) {
for ( my $j = 0; $j < @V; $j++ ) {
vec( $nC[ $i ], $j, 1 ) =
vec( $C[ $i ], $j, 1 ) |
vec( $C[ $i ], $k, 1 ) & vec( $C[ $k ], $j, 1 );
}
}
@C = @nC; # Update the closure.
}
I believe that
1) The adjacency matrix C can be modified in-place, and more significantly: 2)
The the vec( $C[ $], $k, 1) test can be broken out of the innermost loop. This
can be much faster.
The modified code would look something like:
# Do the O(N**3) loop.
for ( my $k = 0; $k < @V; $k++ ) {
for ( my $i = 0; $i < @V; $i++ ) {
next unless vec( $C[ $i ], $k, 1 );
for ( my $j = 0; $j < @V; $j++ ) {
vec( $C[ $i ], $j, 1 ) |= vec( $C[ $k ], $j, 1 );
}
}
}
|
Anonymous |
|
Printed |
Page 362
2nd paragraph of Rabin-Karp |
256**80 is shown as about 4.6e193, should be 4.6e192.
(It's still large.)
|
Ben Nathanson |
Jun 15, 2016 |
Printed |
Page 366
Figure 9-1 |
Modulus in figure 9-1 is different from the modulus in the text (8355961 vs 8355967).
|
Ben Nathanson |
Jun 15, 2016 |
Printed |
Page 369
The authors appear to claim that the unpack('%32C*', $P) construct is |
equivalent to Rabin-Karp. In fact, the Perl construct only sums the ascii
values of each character in the string and is thus much weaker than RK.
|
Anonymous |
|
Printed |
Page 370
penult paragraph ("We will implement...") |
"We define next[$j]...such that the suffix of length $k-1 is still a proper suffix of the pattern." Should the second "suffix" be "prefix"? And might be clearer if "text" were inserted before the first "suffix".
|
Ben Nathanson |
Jun 15, 2016 |
Printed |
Page 370
last paragraph |
"In Figure 9-3..." Suspect that's a typo for Figure 9-2 (9-3 shows the result after the skip).
|
Ben Nathanson |
Jun 15, 2016 |
Printed |
Page 372
2nd section of code ... knuth_morris_pratt |
Should
my $m = knuth_morris_pratt_next( $P );
my ($n, $i, $j) = (length($T), 0, 0);
my @next;
be
my ($m, @next) = knuth_morris_pratt_next( $P );
my ($n, $i, $j) = (length($T), 0, 0);
|
Anonymous |
|
Printed |
Page 389
This isn't so much errata as just out of date. Text::Metaphone is listed |
as "still experimental". It has been out of alpha and stable since January.
If you would remove the note about it being experimental I'd appreciate it,
thanks.
|
Anonymous |
|
Printed |
Page 389
In the code example for using Text::Metaphone, the function is |
Metaphone() with a capital M.
$metaphone_a = Metaphone $a;
$metaphone_b = Metaphone $b;
|
Anonymous |
|
Printed |
Page 389
|
Now reads:
Soundex trades precision for space/time simplicity
Shouldn't it be:
Soundex trades precision for space/time/simplicity
|
Anonymous |
|
Printed |
Page 399
first paragraph |
the source of p. 403:
- does not give most error messages.
- does not work with the example query of p.399 abc and not (def or ghi)
- when you type a non-gramatical string or simply a query with (), it hungs up
and does not process any other string from <STDIN>.
|
Anonymous |
|
Printed |
Page 403
the code |
The url:
"ftp://ftp.media.mit.edu/pub/orwant/wolf/ch09.tar.gz"
...on the errata web page should change to:
"http://examples.oreilly.com/9781565923980/ch09.tar.gz".
|
Anonymous |
Feb 10, 2015 |
Printed |
Page 406
3/5 down the page, definition of @token |
The token INTEGER will not match 0. Perhaps this is an old example supplied
with the module, or perhaps it could be renamed to POSITIVE_INTEGER (or
NATURAL) to match its function.
|
Anonymous |
|
Printed |
Page 415
second example |
#!/usr/bin/perl -pi.bak
s/(x10)(.)(.)/ $2 x (ord($3) || 256) /eg;
should be:
#!/usr/bin/perl -pi.bak
s/(x10)(.)(.)/ $2 x (ord($3) || 256) /seg;
|
Anonymous |
|
Printed |
Page 419
next to last line of code |
The code snippet:
$a->{value} <=> $b->{value}
gives a warning (non-numeric in ncmp) because the value is sometimes a string,
not a single character. [This is online in the file ch9/huffman.]
Also, in the online example, in ch9/huffman-example, sub get_bit is defined as:
sub get_bit {
return $bit{shift @bits};
}
but this generates a "Use of unitialized value" warning when it runs off the
end of @bits. Instead, something like this is warranted:
sub get_bit {
defined( @bits ) ? return $bit{shift @bits} : undef;
}
|
Anonymous |
|
Printed |
Page 420
top picture |
The picture erroneously has an "a" in the left child of the root node where it
should apparently be an "f".
|
Anonymous |
|
Printed |
Page 421
1st paragraph |
If my memory serves, gzip/pkzip and compress are two entirely different algorithms. The former is based on the 1977 paper. The latter is based on their 1978 paper and Welch's 1984 paper. I don't recall if someone proved that the two algorithms are equivalent; but at the very least, Welch's 1984 paper isn't revising the 1977 paper -- they're different algorithms.
|
Anonymous |
|
Printed |
Page 432
Paragraph 5 from bottom. Area of example pentagon. |
The area of example pentagon formed by points (0,1), (1,0), (3,2), (2,3) and (0.2) is
5 and not 2 as stated. It is quite easy to verify that. The pentagon given is
enclosed in a square formed by (0,0), (3,0), (3,3) and (0,3) whose area is, of
course, 9. In this square, apart from the pentagon, there are 4 right angled
trianlges given by (a) (0,0),(1,0) and (0,1) (b) (1,0), (3,0) and (3,2) (c) (3,2),
|
Anonymous |
|
Printed |
Page 455
Code Block Near: "# Backtrack: while there are right turns or no turns, shrink |
the hull.";
while (
clockwise( $x[ $h[ $#h - 1 ] ],
$y[ $h[ $#h - 1 ] ],
$x[ $h[ $#h ] ],
$y[ $h[ $#h ] ],
$x[ $i ],
$y[ $i ] ) < epsilon
Should read:
while (
clockwise( $x[ $h[ $#h - 1 ] ],
$y[ $h[ $#h - 1 ] ],
$x[ $h[ $#h ] ],
$y[ $h[ $#h ] ],
$x[ $i ],
$y[ $i ] ) > epsilon
Note greater than/less than symbols
clockwise returns negative for left and positive for right, thus if the code reads
"less than epsilon", and epsilon is an non negative value, the code will pop elements
of the hull.
|
Anonymous |
|
Printed |
Page 455
Code block near: "# Interlace x's and y's of the hull back into one list, and |
return"i;
return map { ( $x[ $_ ], $y[ $_ ] ) } 0 .. $#h;
Should read:
return map { ( $x[ $_ ], $y[ $_ ] ) } @h;
In the first case the wrong values are used, namely all elements of @x and @y up to
$#h. The correct version uses the values contained in @h as the indices into @x and
@y as desired.
|
Anonymous |
|
Printed |
Page 461
9th line from bottom |
The if() statement lacks a check for the "equality" case, so closest_points
|
Anonymous |
|
Printed |
Page 465
GD Section |
GD no longer works with GIF files. PNG is the new format.
|
Anonymous |
|
Printed |
Page 465
within GD subsection, second last line of code example |
print GIF $gif;
should read:
print GIF $gif->gif;
Otherwise, the file will not correctly as a GIF. It will just write as ascii
with jibberish.
|
Anonymous |
|
Printed |
Page 473
both blocks of code |
SUMMARY
Use of epsilon in comparing two floating point numbers for (approximate)
equality is incorrect in both code blocks and for the same reason each
time. Also there is textual error.
This refers to the August 1999 first edition of the book.
DETAILS
The authors write
if (abs($value1 - $value2) < epsilon) { # They match ...
However the correct code is
if (abs($value1 - $value2) < abs($value1 * epsilon)) {
It is incorrect to compare a raw difference to epsilon. Rather one must
compare a scaled difference (ie., divide the difference by $value1 or
$value2). That's what my correction accomplishes (and does so in a way that
is not subject to divide by zero errors).
Technically, epsilon is the smallest distinguishable difference relative to
one (not zero, as the claimed in the book -- middle of p. 473 -- this is
another error to correct). Thus for comparison to epsilon, one needs to use
differences normalized or scaled to one.
For more about epsilon, see Numerical Recipes in C (2nd ed.). Also, see
Bruce Bush's The Perils of Floating Point HTML page
www.lahey.com/float.htm
|
Anonymous |
|
Printed |
Page 474
2nd code block, the floor function |
According to the definition in my ancient K&R: "largest integer not greater
than x, as a double"
The sub provided rounds UP for negative numbers. This is not a direct
replacement for the POSIX floor/ceil functions as implied in the text.
|
Anonymous |
|
Printed |
Page 482
<INFO> There's a program snippit for calculating how many of the bits in |
your computer are ones. Other than the obvious "you need to be root to do
this", on some hardware architechtures this is a *really bad idea* that will
cause you pain. I once spent several hours pounding my head into a wall with
an hp300, where the machine would crash when trying to use its serial card,
but only if the X server had been started. I had to resort to my guru to
figure this one out, and he had to scratch his head for a minute before he
figured it out.
Turns out the hp300 maps device memory into the first 16 mb of /dev/mem, and
the serial card in question uses activate on read registers. X's magic cookie
auth generates its random number seed by checksumming /dev/mem. Reading from
/dev/mem caused the card to change state without the OS knowing about it. Oops.
|
Anonymous |
|
Printed |
Page 483
sub base { } |
print base(17, 9, 2) ,"
";
print base(10000,2,9) ,"
";
print base("fff", 16, 3) ,"
";
print base(12121200,3,16),"
";
print base("g", 17, 10) ,"
";
print base(16 , 10, 17) ,"
";
print base(121,10,15),"
";
print base(132,10,15),"
";
====> get result as below
10000
17
12121200
151515
16
16
81
812
# May change as below
# Convert the number form base 10 to $outbase.
# logbase() is defined below.
for($i=int(logbase($realnum, $outbase)); $i>= 0; $i--) {
$digit = int($realnum / ($outbase ** $i));
$realnum -= $digit * ($outbase ** $i);
if($digit >=10)
{
$digit=$digit+87;
$digit=chr($digit);
}
#if(ord($digit) >57 )
# {
# $digit = ord($digit +49) ;
# }
$output .=$digit;
}
# To Get the result as below:
10000
17
12121200
fff
16
g
81
8c
|
Anonymous |
|
Printed |
Page 518
exp_fast subroutine code |
In the code for the non-recursive exponential subroutine "exp_fast" there is a
block that tests whether or not the variable representing the power is odd. At
the end of this conditional block the variable ($j) is decremented, which
would cause it to become an even number. Presumably this is done so that the
division by 2 which immediately follows does not coerce $j into a
floating-point number. This would be Perl's normal behavior, however, since
the entire subroutine falls under the scope of a "use integer" pragma there is
no danger of integer-to-float conversion. Consequently, the $j-- is not needed.
|
Anonymous |
|
Printed |
Page 523
sub collatz routine |
$seen{$n} should be 'my'-ed in the subroutine.
|
Anonymous |
|
Printed |
Page 540
within sub one_time_pad () |
The expression:
seek PAD, 2, -$pos or return undef;
is wrong. The order of the arguments to seek are transposed. The correct
expression is:
seek PAD, -$pos, 2 or return undef;
Also, since the sub makes use of sysread (), the appropriate seek function
is sysseek (). Therefore, the expression should be:
sysseek PAD, -$pos, 2 or return undef;
Better would be:
return undef unless sysseek( PAD, -$pos, 2 );
return undef unless sysread( PAD, $key, $len ) == $len;
Good practice is to always check the return value of system calls.
|
Wm. Schmidt |
Jun 22, 2020 |
Printed |
Page 541
bottom, subroutine rot13 |
Instead of:
$val = tr/a-zA-Z/n-za-mN-ZA-M/;
should be:
$val =~ tr/a-zA-Z/n-za-mN-ZA-M/;
|
Anonymous |
|
Printed |
Page 557
code block at top of page |
The extract subroutine builds up the extracted message in the lexical variable
$message, but doesn't return it. This line should be inserted at the end of
the extract subroutine:
return $message;
|
Anonymous |
|
Printed |
Page 584
|
smartie_weight = 0;
@smartie_order = sort { $dist->{$a} <=> $dist->{$b} } keys %smartie_weights;
for (@smartie_order) { $smartie_weight += $smartie_weight{$_} }
As it is right now, @smartie_order would contain nothing since $dist is a part
of the subroutine rand_dist_weighted.
It should read:
@smartie_order = sort { $smartie_weights{$a} <=> $smartie_weights{$b} } keys
%smartie_weights;
|
Anonymous |
|
Printed |
Page 584
sub rand_dist_weighted() code at top of page |
While not an error, the linear search in this routine can be made a tad faster by
sorting the large weights first:
$key_order = [ sort { $dist->{$b} <=> $dist->{$a} } keys %$dist ]
Likewise for the "@smartie_order =" line at the bottom of the page.
|
Anonymous |
|
Printed |
Page 585
sub binomial, first two return statements |
replace with
return(0) if ((($p == 0) && ($k != 0)) || (($p == 1) && ($k != $n)));
return(1) if ((($p == 1) && ($k == $n)) || (($p == 0) && ($k == 0)));
or something equivalent but more beautiful. At present some cases
$p==1, $k!=$n gets return1 rather than 0
$p==1, $k==$n gets undefined rather than 1
$p==0, $k!=$n gets undefined rather than 0
tested on Perl 5.005_03 built for i686-linux
|
Anonymous |
|
Printed |
Page 592
2nd to last paragraph |
The authors egregiously misinterpret the probability density (mass) function
for continuous distributions. To compute probabilities from a density
function, it is necessary to integrate the function over some range, not
simply to evaluate the density at a point. As an example of the sort of
nonsense that can result from the authors' error, if we reduce the variance in
the example on page 592 to 0.1 and compute gaussian(0, 0, 0.1), we arrive at
the conclusion that 126% of leaflets will hit the target. Let r be the sum of
the radii of the target and a leaflet; the correct answer is the integral of
the Gaussian(0, 0.1) density from -r to +r.
|
Anonymous |
|
Printed |
Page 596
Hypergeometric DIstributions |
my $val = hypergeometric(3,5,53,48);
print "Hyper = $val
"; # will give: 0.00393074501208321
Proposed changes to:
sub hypergeometric {
my ($x,$k,$m,$n) = @_;
return unless $m>0 && $m == int($m) && $n > 0 && $n == int($n) &&
$k > 0 && $k <= $m+$n;
return 0 unless $x <= $k && $x == int($x);
return choose($k,$x) * choose($n, $k-$x)/ choose($m,$k); # changes here
}
Such that
my $val = hypergeometric(3,5,53,48);
print "Hyper = $val
"; # will give: 0.00393074501208321
The proposed changes follows the example from this link:
http://www.lottery.state.mn.us/hypergeo.html
|
Anonymous |
|
Printed |
Page 600
First full paragraph |
The Statistics::Descriptive module is by Colin Kuskie and Jason Kastner, not
Lastner.
Neither Colin, Jason, nor S::D show up in the index.
|
Anonymous |
|
Printed |
Page 603
|
The line:
my @array = sort @$arrayref;
Should be written:
my @array = sort { $a <=> $b } @$arrayref;
Otherwise the array is not numerically sorted and the answer is wrong.
|
Anonymous |
|
Printed |
Page 603
Reads: |
If there are two or more equally common elements, there
are two options: declare that there is no mode (that is,
return *undef*), or return the median of the modes. The
following subroutine does the latter."
Neither of these options is mathematically correct, though the latter hints at
the correct answer, in that you return the median of the 'modes'. In a
sequence such as 1, 2, 2, 3, 3, 4, the mode is in actual fact both 2 and 3,
the distribution being a 'multi-modal' distribution.
I appreciate that in this instance, returning both 2 and 3 would probably
require a heavy alteration of the subroutine. As it stands, it currently
returns a scalar, whereas in this instance it would probably have to return
|
Anonymous |
|
Printed |
Page 605
The "equivalent formulation of the standard deviation" at the bottom of |
the page is mathematically, but _NOT_ numerically equivalent to the formula on
p. 604. In fact, an understanding of the differences between these two
formulae is a common screening question for hiring scientific programmers.
Since many readers may try to implement the second formula, it would be a
service if the text provided a warning that the two methods can give different
results.
|
Anonymous |
|
Printed |
Page 606
3rd paragraph |
actually this is the error of the errata web page:
Change -10 to 16 and 10 to 16;
change -5 to 8 and 5 to 8;
....should be:
Change -10 to -16 and 10 to 16;
change -5 to -8 and 5 to 8;
|
Anonymous |
Feb 12, 2015 |
Printed |
Page 611
5th line of the 1st code block |
$confidence += binomial ($trials, $hits, $probability)
should read
$confidence += binomial ($trials, $_, $probability)
|
Anonymous |
|
Printed |
Page 613
formula |
The formula given for computation of the z statistic is:
(mean of data - expected mean)/standard deviation.
It seems to me that it should be:
(mean of data - expected mean)/(standard deviation / sqrt (sample size)).
(The code presented in the middle of the page is right, since it uses the
good formula).
|
Anonymous |
|
Printed |
Page 614
bottom (after the t formula) |
It is written that "the estimate of the standard error of the mean is the
square root of the estimate of the population variance". It seems to me that
this is false. The estimate of the standard error of the mean is the square
root of the estimate of the population variance, divided by the square root of
the sample size.
|
Anonymous |
|
Printed |
Page 622
2nd paragraph |
The mistake of
In the correlation sub, the following line is present:
sqrt(((@$array1ref * $sum1_squared) - ($sum1 ** 2)) *
((@$array1ref * $sum2_squared) - ($sum2 ** 2)));
The second mention of @$array1ref should be @$array2ref.
is mentioned in the errata section, but is not corrected in the downloadable sample code. I downloaded the code and spent quite a buit of time trying to troubleshoot the problem in my code when actually it was a problem in your sample code. Could you please make this change in the downloadable examples so that others do not have the same problem that I did.
|
Anonymous |
|
Printed |
Page 630
third row of matrix |
On page 629 appears the following equation:
h(x, y, z) = xyz
On page 630, the partial derivatives of this equation are listed as (x - 4)(y
+ 2), (x - 4)(z + 7), and (x - 4)(y + 2).
These partial derivatives should be listed as yz, xz, and xy, respectively.
|
Anonymous |
|
Printed |
Page 631
upper third of page |
An equation has a missing term.
@jacobian = jacobian( [&f, &g], [3, 4, -2] );
should be modified to read as follows:
@jacobian = jacobian( [&f, &g, &h], [3, 4, -2] );
|
Anonymous |
|
Printed |
Page 635
1st code block |
$b/abs($b) will fail if $b is 0. As a replacement, $b <=> 0 will not fail and
is about 20% faster on my machine. It might need an explanation in the prose,
however.
The code on p. 637 includes $sgn = $b/abs($b) if $b, which doesn't fail but
could also be sped up.
|
Anonymous |
|
Printed |
Page 646
The 5th line from the comment "# Decompositon phase ..." in the code |
$coeffs[$i] = ($delta - 1) / @points;
should read
$coeffs[$i] = ($delta - 1) / $temp;
Accordingly, the example on the next page 647 should be:
Spline coefficients: 0 -8.8 11.2 0
[-1.00, 1.00]
[-0.50, 2.05]
[0.00, 2.00]
[0.50, 0.35]
[1.00, -1.00]
[1.50, -0.20]
[2.00, 2.00]
[2.50, 4.20]
[3.00, 5.00]
The error is so minor that the difference is invisible in Figure 16-3, however.
|
Anonymous |
|
Printed |
Page 647
|
On line 2, the code reads:
my $coeffs = spline_generate @points;
It should read:
my $coeffs = spline_generate(@points);
|
Anonymous |
|