perl - if-clause seems not to be executed under certain arbitrary conditions -


i trying divide triangular matrix parts, hold approximately same amount of elements.

i wrote following code, works nicely combinations of inputs, , segments matrix given number of parts 0 $length.

however, there input combinations $length = 2003 , $number_of_segments = 50, last segment missing in output. tested values of $threshold , $total, seem correct in odd cases.

do have ideas, bug is?

#!/usr/bin/perl  use strict;         #should used use warnings;       #that 1 use autodie;        #just in case forgot check  $length = shift or die "error: not enough arguments!\n";         #number of rows in matrix $number_of_segments = shift or die "error: not enough arguments!\n";     #number of segments want  @segments = &divide;         #array of segment-limits print "$_\n" foreach @segments;  sub divide {     @segments = (0);         #the first segment starts @ 0     $number_of_pairs = ($length*($length+1))/2;          #number of elements in matrix     $total = 0;          #counter elements visited     $segment_counter = 1;        #we in first segment      (my $i=0; $i<$length; $i++){        #going on rows of matrix         $total += $length-$i;           #counting elements in each row         $threshold = ($number_of_pairs/$number_of_segments)*$segment_counter;        #threshold next segment         if ($total >= $threshold){          #if our current segment large enough             push @segments, $i+1;              #save limit             $segment_counter++;            #and open next segment         }     }      return @segments; } 

the problem can't compare floating-point numbers equality because of limited accuracy. final value of $threshold comes out fractionally high (2007006.0000000002 on 32-bit perl) have allow margin of error.

if change test

if ( $total + 1e-8 >= $threshold ) { ... } 

then results expect. may have adjust delta value correct results.

note slow , inaccurate way of doing things. should keep arithmetic integers instead of floating point values, don't have time @ present refactor code


Comments