Mea culpa. The culprit is the following:
if (!($time=~/^\d+$/ and $rate=~/^\d+$/ and $shares=~/^\d+$/ and $rate>0 and $shares>0 and $time>0)){
Unfortunately it wants an _integer_, rather than a number with a dot, for the rate.
As such, the code should be (split it for readability):
$time=~s/^.*"duration":(\d+).*$/$1/;
$shares=~s/^.*"shares_this_round":(\d+).*/$1/;
$rate=~s/^.*"hashrate":(\d+).*/$1/;
$rate = int($rate/10**9); # this was: $rate /= 10**9, which caused the floating point "error"
Sorry, apologies, head on a plate, etc.etc.