Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

perl inline::c sorting problem

by dalittle (Novice)
on Apr 30, 2009 at 00:51 UTC ( #761015=perlquestion: print w/ replies, xml ) Need Help??
dalittle has asked for the wisdom of the Perl Monks concerning the following question:

I built a perl inline::c module, but there is some oddity with the sorting. Anyone know why it would sort like this? Why is the 4.0e-5 is not first?
my $ref = [ 5.0e-5,4.2e-5,4.3e-5,4.4e-5,4.4e-5,4.2e-5,4.2e-5,4.0e- +5]; use Inline C => <<'END_OF_C_CODE'; void test(SV* sv, ...) { I32 i; I32 arrayLen; AV* data; float retval; SV** pvalue; Inline_Stack_Vars; data = SvUV(Inline_Stack_Item(0)); /* Determine the length of the array */ arrayLen = av_len(data); // sort sortsv(AvARRAY(data),arrayLen+1,Perl_sv_cmp_locale); for (i = 0; i < arrayLen+1; i++) { pvalue = av_fetch(data,i,0); /* fetch the scalar located at i + .*/ retval = SvNV(*pvalue); /* dereference the scalar into a numb +er. */ printf("%f \n",newSVnv(retval)); } } END_OF_C_CODE
> test($ref);

0.000042
0.000042
0.000042
0.000043
0.000044
0.000044
0.000040
0.000050

Comment on perl inline::c sorting problem
Download Code
Re: perl inline::c sorting problem
by whakka (Hermit) on Apr 30, 2009 at 03:08 UTC
    It looks like you're using lexical sorting with cmp instead of <=>. It looks like Perl chops "4.0e-5" to "4e-5" and then looks at the string, hence the ordering you see.

    You'll probably have to change Perl_sv_cmp_locale to whatever the constant is for <=> though I'm sorry I can't seem to track that down at the moment. You may have to use sortsv_flags. The perlapi documentation is a little thin.

      You'll probably have to change Perl_sv_cmp_locale to whatever the constant is for <=> though I'm sorry I can't seem to track that down at the moment

      I can't find it either. Is there such a thing ? Or is sortsv() invariably lexical ?

      I tried
      Perl_sortsv_flags(aTHX_ AvARRAY(data),arrayLen+1,Perl_sv_cmp, flags);
      for differing values of 'flags', but it looked like 0 (and any even value) causes a lexical sort in ascending order, and 1 (and any odd value) causes a lexical sort in descending order. I didn't stumble across any value that forces a numeric sort.

      The following produces the desired output:
      use warnings; use Inline C => Config => CLEAN_AFTER_BUILD => 0, BUILD_NOISY => 1; use Inline C => <<'END_OF_C_CODE'; void test(AV* data) { I32 i; I32 arrayLen; float retval; SV** pvalue; arrayLen = av_len(data); sortsv(AvARRAY(data),arrayLen+1,Perl_sv_cmp); for (i = 0; i < arrayLen+1; i++) { pvalue = av_fetch(data,i,0); printf("%s \n",SvPVX(*pvalue)); } } END_OF_C_CODE my $ref = [ 5.0e-5,4.2e-5,4.3e-5,4.4e-5,4.4e-5,4.2e-5,4.2e-5,4.0e-5]; for(@$ref) {$_ = sprintf "%f", $_} test($ref);
      I don't know if that's helpful in the "real world" application. All it does is stringify the values in the array reference into such a form that the lexical sort produces the desired output. There may be a better way of achieving that stringification.

      Cheers,
      Rob

        PP_sort.c contains all these routines which appear to be defined such that they could be used as alternatives to Perl_sv_cmp:

        S_sortcv(pTHX_ SV *a, SV *b) S_sortcv_stacked(pTHX_ SV *a, SV *b) S_sortcv_xsub(pTHX_ SV *a, SV *b) S_sv_ncmp(pTHX_ SV *a, SV *b) S_sv_i_ncmp(pTHX_ SV *a, SV *b) S_amagic_ncmp(pTHX_ register SV *a, register SV *b) S_amagic_i_ncmp(pTHX_ register SV *a, register SV *b) S_amagic_cmp(pTHX_ register SV *str1, register SV *str2) S_amagic_cmp_locale(pTHX_ register SV *str1, register SV *str2)

        They are prototyped in proto.h and aliased in embed.h, but even including those explicitly does not allow them to be seen at compile time?


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://761015]
Approved by planetscape
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (6)
As of 2014-10-31 08:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (215 votes), past polls