Suman
Suman

Reputation: 3545

Formatting in Raku

I have written a function that outputs a double, upto 25 decimal places. I am trying to print it as a formatted output from Raku.

However, the output is incorrect and truncated.

See MWE:

my $var = 0.8144262510988963255087469;
say sprintf("The variable value is: %.25f", $var) 

The above code gives The variable value is: 0.8144262510988963000000000 which is not what is expected.

Also, this seems weird:


my $var = 0.8144262510988963255087469;

say $var.Str.chars; # 29 wrong, expected 27

I tested the same in C:

#include <stdio.h>

int main() {
   double var = 0.8144262510988963255087469;
   printf("The variable value is: %.25lf \n", var);

   return 0;
}

However, it works fine. Given the identical nature of sprintf and printf, I expected this C example to work in Raku too. Seems like %lf is not supported.

So is there a workaround to fix this?

Upvotes: 8

Views: 328

Answers (2)

librasteve
librasteve

Reputation: 7581

From your question:

I have written a function that outputs a double, upto 25 decimal places.

From google:

Double precision numbers are accurate up to sixteen decimal places

From the raku docs :

When constructing a Rat (i.e. when it is not a result of some mathematical expression), however, a larger denominator can be used

so if you go

my $v = 0.8144262510988963255087469; 
say $v.raku;
#<8144262510988963255087469/10000000000000000000000000>

it works.

However, do a mathematical expression such as

my $b = $a/10000000000000000000000000;

and you get the Rat => Num degradation applied unless you explicitly declare FatRats. I visualise this as the math operation placing the result in a Num register in the CPU.

The docs also mention that .say and .put may be less faithful than .raku, presumably because they use math operations (or coercion) internally.

Sorry to be the bearer of bad news, but 10**25 > 2 **64, but what you report as an issue is correct & (fairly) well documented behaviour given the constraints of double precision IEEE P754.

Upvotes: 3

Elizabeth Mattijsen
Elizabeth Mattijsen

Reputation: 26969

I think this is actually a bug in how Rat literals are created. Or at least as WAT :-).

I actually sort of expect 0.8144262510988963255087469 to either give a compile time warning, or create a Num, as it exceeds the standard precision of a Rat:

raku -e 'say 0.8144262510988963255087469'
0.814426251098896400086204416

Note that these are not the same.

There is fortunately an easy workaround, by creating a FatRat

$ raku -e 'say 0.8144262510988963255087469.FatRat'
0.8144262510988963255087469

FWIW, I think this is worthy of creating an issue

Upvotes: 6

Related Questions