Discussion:
Passing 64-bit integers from perl to C
(too old to reply)
Sisyphus
2007-02-13 04:24:16 UTC
Permalink
Hi,
Running Cygwin perl 5.8.7 on Windows XP (32 bit).
Perl was built with -Duse64bitint.

-------------------
use warnings;
use Inline C => Config =>
BUILD_NOISY => 1;

use Inline C => <<'EOC';

int foo(SV * integer) {

if(SvIOK(integer)) {
printf("IV: %s\n", SvPV_nolen(integer));
return 1;
}

if(SvNOK(integer)) {
printf("NV: %s\n", SvPV_nolen(integer));
return 2;
}

printf("Neither IV nor NV");
return 3;
}

EOC

{
use integer;
$x = 2 ** 57 + 12345;
}

$y = 2 ** 57 + 12345;

foo($x);
foo($y);
-------------------

This outputs:
IV: 144115188075868217
NV: 1.44115188075868e+17

foo() has no problem in getting $x into the string form
"144115188075868217". But how can the same be achieved when foo() is given
$y ?

I need to pass the value to the GMP C library. That library is not built
with "long long" or "long double" support. The only way I can see of passing
such large integer values successfully is to first convert them into a
string of digits (as per what the foo function does to $x). But can that be
achieved if the large integer argument is an NV ?

Cheers,
Rob
Nicholas Clark
2007-02-13 11:58:06 UTC
Permalink
Post by Sisyphus
if(SvNOK(integer)) {
printf("NV: %s\n", SvPV_nolen(integer));
return 2;
}
I need to pass the value to the GMP C library. That library is not built
with "long long" or "long double" support. The only way I can see of
passing such large integer values successfully is to first convert them
into a string of digits (as per what the foo function does to $x). But can
that be achieved if the large integer argument is an NV ?
Something like

printf("forced UV: %"UVuf"\n", SvUV(integer));

? [not tested]

You might need to manage the sign explicitly.

Nicholas Clark
Sisyphus
2007-02-13 23:31:58 UTC
Permalink
----- Original Message -----
From: "Nicholas Clark" <***@ccl4.org>
.
.
Post by Nicholas Clark
Something like
printf("forced UV: %"UVuf"\n", SvUV(integer));
? [not tested]
Yes - that gets at the value in the IV slot. Sadly, that value is
144115188075868224 (not the desired 144115188075868217).

But then, it's an NV - so, of course, precision has been lost !!

The following tests on $x (the IV) and $y (the NV) return true:

$x == $y
$x + 1 == $y + 1
$x - 1 == $y - 1

I took that to indicate that $y did, in fact, hold the same value as $x (ie
144115188075868217), and that my problem was just one of how to get at that
value.

I now find that the following tests also return true:

$x == $y + 1
$x == $y -1

which would suggest that precision has, in fact, been lost.

Thanks Nicholas.

Cheers,
Rob

Continue reading on narkive:
Loading...