Discussion:
[Pdl-porters] typecasting in MOD macro
Derek Lamb
2015-02-18 06:05:51 UTC
Permalink
At the very beginning of Basic/Ops/ops.pd there are currently two MOD macros to define the modulus operator. BU_MOD works on byte and ushort piddles, whereas MOD works on all other types. In both of those, but particularly worrisome in MOD, there are C typecasts to (int). I think this is the source of the modulo failures that Luis Mochan has been reporting on the perldl list for large longlong operands: the longlongs get truncated to ints, lose high order bits, and thus the operator returns garbage.

You can see what I mean by doing:
$a= longlong(71,710,7100,71000,710000,7100000,71000000,710000000,7100000000,71000000000,710000000000,7100000000000,71000000000000,710000000000000,710000000000000,7100000000000000,71000000000000000)

print $a; #the internal representation is fine (at least on my machine)

print $a % 71; #should return 0 for each
[0 0 0 0 0 0 0 0 0 0 609885356032 7013681594368 71051643977728 709906554421248 709906554421248 7.09998037224653e+15 7.10001086651433e+16]

The simplest fix seems to be changing those typecasts from (int) to (long). The above $a%71 returns all zeroes, and "make test" passes. But I'm not sure about portability (is long defined on all our systems?), and it's now obvious that the tests in ops.t for modulo are completely inadequate. Or is that just kicking the can down the road?

I can also get rid of the failures for longlong operands by creating a new macro Q_MOD that works on longlongs only, and replaces the (int) typecasts with (long long). Here I worry more about portability: my "pdl -V" has "longsize=8, d_longlong=define, longlongsize=8".

I guess I'm unclear what we support on what machines; I haven't been paying too much attention to that lately.

Kind of stupid that this long message is for potentially a 14-character source code change, but thought I'd check first before pushing something that's going to mess somebody else up.

best,
Derek
Craig DeForest
2015-02-18 14:46:17 UTC
Permalink
We may need another mod operator to handle long longs - or to use the $T macro to do the promotion. The author (sorry) relied on the fact that long and int are the same thing on most systems in this century. That has stayed more or less the same, but doesn't work for then-uncommon-but-now-common long longs.

Sent from my iPad
Post by Derek Lamb
At the very beginning of Basic/Ops/ops.pd there are currently two MOD macros to define the modulus operator. BU_MOD works on byte and ushort piddles, whereas MOD works on all other types. In both of those, but particularly worrisome in MOD, there are C typecasts to (int). I think this is the source of the modulo failures that Luis Mochan has been reporting on the perldl list for large longlong operands: the longlongs get truncated to ints, lose high order bits, and thus the operator returns garbage.
$a= longlong(71,710,7100,71000,710000,7100000,71000000,710000000,7100000000,71000000000,710000000000,7100000000000,71000000000000,710000000000000,710000000000000,7100000000000000,71000000000000000)
print $a; #the internal representation is fine (at least on my machine)
print $a % 71; #should return 0 for each
[0 0 0 0 0 0 0 0 0 0 609885356032 7013681594368 71051643977728 709906554421248 709906554421248 7.09998037224653e+15 7.10001086651433e+16]
The simplest fix seems to be changing those typecasts from (int) to (long). The above $a%71 returns all zeroes, and "make test" passes. But I'm not sure about portability (is long defined on all our systems?), and it's now obvious that the tests in ops.t for modulo are completely inadequate. Or is that just kicking the can down the road?
I can also get rid of the failures for longlong operands by creating a new macro Q_MOD that works on longlongs only, and replaces the (int) typecasts with (long long). Here I worry more about portability: my "pdl -V" has "longsize=8, d_longlong=define, longlongsize=8".
I guess I'm unclear what we support on what machines; I haven't been paying too much attention to that lately.
Kind of stupid that this long message is for potentially a 14-character source code change, but thought I'd check first before pushing something that's going to mess somebody else up.
best,
Derek
_______________________________________________
PDL-porters mailing list
http://mailman.jach.hawaii.edu/mailman/listinfo/pdl-porters
Loading...