Melly has asked for the wisdom of the Perl Monks concerning the following question:
Hi,
The following script works on Win32 (produces a crude mandelbrot), but fails on Linux (produces zeroes only).
I've put the output under the readmore, but here's the code... (oh, and I should add that this is the end result of some golf, hence no strict, etc.)
map{
$a=1-$_/10;
map{
$d=$a;
$e=$b=$_/20-2;
map{
($d,$e)=(2*$d*$e+$a,$e**2-$d**2+$b);
$c=$d**2+$e**2>4?_:0
}1..99;
print$c
}0..59;
print$/
}0..20;
Win32 Output:
________________________________________0___________________
____________________________________________________________
____________________________________0000____________________
____________________________________0000____________________
______________________________0__0000000000_________________
______________________________00000000000000000_____________
____________________________0000000000000000000_____________
___________________________000000000000000000000____________
_________________0000000__0000000000000000000000____________
________________000000000_0000000000000000000000____________
0000000000000000000000000000000000000000000000______________
________________000000000_0000000000000000000000____________
_________________0000000__0000000000000000000000____________
___________________________000000000000000000000____________
____________________________0000000000000000000_____________
______________________________00000000000000000_____________
______________________________0__0000000000_________________
____________________________________0000____________________
____________________________________0000____________________
____________________________________________________________
________________________________________0___________________
Linux:
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
map{$a=1-$_/10;map{$d=$a;$e=$b=$_/20-2;map{($d,$e)=(2*$d*$e+$a,$e**
2-$d**2+$b);$c=$d**2+$e**2>4?_:0}1..99;print$c}0..59;print$/}0..20;
Tom Melly, pm@tomandlu.co.uk
Re: Wrong output on linux, ok on Win32
by shmem (Chancellor) on Nov 30, 2006 at 16:29 UTC
|
#!/usr/bin/perl
use Term::Cap;
$t= Tgetent Term::Cap;
$t=$t->Tgoto('cm', 0, 0);
for$i(1..shift){
print $t;
map{
$a=1-$_/10;
map{
$d=$a;
$e=$b=$_/20-2;
map{
($d,$e)=(2*$d*$e+$a,$e**2-$d**2+$b);
$c=$d**2+$e**2>4?_:0
}1..$i;
print$c
}0..59;
print$/
}0..20;
}
Try perl mandel.pl 13. If I pass 99, there'll be a block
of zeroes at the end.
<update>
It's not an overflow issue. As the area delimiting the mandelbrot converges to a line with increased iterations over the inner loop, there's not enough resolution to draw it. You can skip the outer area exiting the inner loop as soon as $d**2+$e**2>4
map{
$a=1-$_/10;
map{
$d=$a;
$e=$b=$_/20-2;
for(1..99){
($d,$e)=(2*$d*$e+$a,$e**2-$d**2+$b);
$c=$d**2+$e**2>4?_:0;
last if $c eq _
}
print$c
}0..59;
print$/
}0..20;
I wonder how that works on your windows box, though.
</update>
--shmem
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
| [reply] [d/l] [select] |
|
| [reply] |
|
| [reply] |
|
Indeed, but then I lose at golf ;)
Here's my solution that avoids a last and only gains me a couple of strokes...
map{
$a=1-$_/10;
map{
$d=$a;
$e=$b=$_/20-2;
map{
($d,$e)=(2*$d*$e+$a,$e**2-$d**2+$b);
$c=$d**2+$e**2>4?$d=8:_
}1..50;
print$c
}0..59;
print$/
}0..20
Tom Melly, pm@tomandlu.co.uk
| [reply] [d/l] |
Re: Wrong output on linux, ok on Win32
by almut (Canon) on Nov 30, 2006 at 15:00 UTC
|
...probably some differences in handling of NAN / INF, etc. The algorithm makes your $d and $e values overflow rather quickly.
By reducing the number of iterations from 99 to something like 9
you should get a coarse approximation of the desired shape -- on both
platforms.
| [reply] |
Re: Wrong output on linux, ok on Win32
by gellyfish (Monsignor) on Nov 30, 2006 at 15:01 UTC
|
Printing out the values of $d and $e on the respective platforms might give you a clue. The rendering of the floating point over/underflow on windows gives rise to a value that can be coerced to a number on Windows (or at least the version of Perl I have.
/J\
| [reply] [d/l] [select] |
Re: Wrong output on linux, ok on Win32
by rinceWind (Monsignor) on Nov 30, 2006 at 14:24 UTC
|
| [reply] |
|
| [reply] [d/l] |
|
| [reply] |
|
|