7

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?

Elizabeth Mattijsen
  • 25,654
  • 3
  • 75
  • 105
lisprogtor
  • 5,677
  • 11
  • 17
  • .oO ( Perhaps... "The now wildly popular pragma `use ffs;`, that makes a range of Raku features fail fast, was first introduced in 202X. When first released it supported just `use ffs :Numerics` and all it did was throw an exception on construction of a `Rat` divided by zero, written in reaction to an earlier SO by @lisprogtor." ) – raiph Jun 15 '21 at 16:36
  • Thank you very much raiph ! I will learn and try the ffs feature. – lisprogtor Jun 16 '21 at 03:30

2 Answers2

4

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.

Elizabeth Mattijsen
  • 25,654
  • 3
  • 75
  • 105
  • It's a several thousand lines long code file. Who knows what lurks in there? – Holli Jun 15 '21 at 07:11
  • 1
    Which version of Rakudo? – Elizabeth Mattijsen Jun 15 '21 at 07:14
  • 1
    Thank you very much Elizabeth Mattijsen and Holli. I am using the latest "Welcome to Rakudo(tm) v2021.04." I forgot to mention that I am crunching numbers on Dell i9 256G RAM workstation running 20 threads each reading from the same GIANT array to do its part of the task. I will utilize your suggestions to find the source of the errors. Thanks! – lisprogtor Jun 16 '21 at 03:38
4

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
Brad Gilbert
  • 33,846
  • 11
  • 78
  • 129
  • Out of curiosity, why is `Inf` represented in a Rat as `1/0`? That’s wrong mathematically, and at the same time there are perfectly reasonable alternatives available: `Inf/1`. – Dan Bron Jun 15 '21 at 13:47
  • 1
    @DanBron Per Wikipedia, "[number divided by zero] may generate positive or negative infinity by the IEEE 754 floating point standard, ... an exception, ... an error message, cause the program to terminate, result in **a special not-a-number value**, or a crash." For its floating point `Num` type/representation, Raku represents the "special not-a-number" positive and negative infinity values as `Inf` and `-Inf`. For its `Rat` type/representation it chooses `1/0` / `-1/0`. (`Rat` is defined as `Rational[Int, uint64]`, i.e. integer over integer, so `Num`'s `Inf` values can't be used.) – raiph Jun 15 '21 at 16:17
  • 1
    @raiph Ah, yes, I’d forgotten IEEE permits this (and my own fave lang, J, defines 1/0 as inf as well). That Rat is an abstraction over int and not num explains why it couldn’t take a mathematically purer approach. Thanks for the insights. – Dan Bron Jun 15 '21 at 16:19
  • Thank you very much Brad Gilbert, Dan Bron, and raiph ! – lisprogtor Jun 16 '21 at 03:34