Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Raku: Attempt to divide by zero when coercing Rational to Str

I am crunching large amounts of data without a hitch until I added more data. The results are written to file as strings, but I received this error message and I am unable to find programming error after combing my codes for 2 days; my codes have been working fine before new data were added.

Died with the exception:
    Attempt to divide by zero when coercing Rational to Str
      in sub analyzeData at /home/xyz/numberCrunch.p6 line 2720
      in block  at /home/xyz/numberCrunch.p6 line 3363

Segmentation fault (core dumped)

The line 2720 is the line that outputs to file: $fh.say("$result");

So, Rational appears to be a delayed evaluation. Is there a way to force immediate conversion of Rational to decimals? Or make Rational smarter by enabling it to detect 0 denominators early?

like image 572
lisprogtor Avatar asked Jun 15 '21 05:06

lisprogtor


2 Answers

First of all: a Rat with a denominator of 0 is a perfectly legal Rational value. So creating a Rat with a 0 denominator will not throw an exception on creation.

I see two issues really:

  • how do you represent a Rat with a denominator of 0 as a string?
  • how do you want your program to react to such a Rat?

When you represent a Rats as a string, there is a good chance you will lose precision:

say 1/3;  # 0.333333

So the problem with Rat to string conversion is more general. Fortunately, there's the .raku method that will not throw:

say (1/3).raku;   # <1/3>
say (42/0).raku;  # <42/0>

Now, if you want your program to just not print the value to the file handle if the denominator is 0, then you have several options:

  • prefix with try
try $fh.say($result)
  • check for 0 denominator explicitly
$fh.say($result) if $result.denominator

Finally, the final error message: "Segmentation fault (core dumped)" is a bit worrying. If this is not a multi-threaded program, we should probably try to find out why that is happening: an execution error should not create a segfault. If it is, then maybe we need to look at your code closer to find out if there are any race conditions on structures such as arrays and hashes.

like image 165
Elizabeth Mattijsen Avatar answered Oct 28 '22 08:10

Elizabeth Mattijsen


There is a perfectly logical reason that 1/0 doesn't immediately throw.

Let's say you have a floating point number that you want to coerce into a Rat, and back again.

my Num() $a = Inf;
my Rat() $b = $a;
my Num() $c = $b;

say $c;

What do you expect the say $c statement to print?

Inf

What would happen if you wrote say $b?

say $b;
Attempt to divide by zero when coercing Rational to Str

What are the contents of $b?

say $b.nude.join('/');
1/0

Now what if you do a division and immediately coerce it to a Num?

say ( 1/0).Num;
say ( 0/0).Num;
say (-1/0).Num;
Inf
NaN
-Inf
like image 45
Brad Gilbert Avatar answered Oct 28 '22 09:10

Brad Gilbert