Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

weird problem with macports perl on apple m1/m2 based system

by perltux (Monk)
on Jun 10, 2023 at 19:19 UTC ( [id://11152734]=perlquestion: print w/replies, xml ) Need Help??

perltux has asked for the wisdom of the Perl Monks concerning the following question:

I have written a fairly complex Perl-Tk application that runs fine on Linux, FreeBSD and on Intel Macs (using MacPorts Perl-Tk).

But on Macs based on M1/M2 cpu (again using MacPorts Perl-Tk) simple floating point arithmetics fail to return the correct result, instead the floating point parts of the operands are ignored and the result is calculated like if it was integer numbers.

For example on Linux and Intel Mac 12.99 * 16.25 returns 211.0875, which is correct, but on M1/M2 Macs with MacPorts Perl I get 192, so Perl is simply doing 12 * 16, completely ignoring the decimals.

I have written a small Perl-Tk script that reproduces this problem (this is really an extract from my application that's why it might look unnecessarily convoluted):
#!/usr/bin/env perl use strict; use warnings; use POSIX qw(strftime); use Tk; my %pid=( DCDC_A_51=>{cmd=>'22 46 5B', cu=>'51', desc=>'DC/DC output curren +t t30', unit=>'A', d=>2, formula=>'sprintf("%.2f", U16(1 +,4)/16)'}, DCDC_V_51=>{cmd=>'22 46 5C', cu=>'51', desc=>'DC/DC output voltag +e t30', unit=>'V', d=>2, formula=>'sprintf("%.2f", U16(2 +5,253)/512)', val=>'---'}, DCDC_W_51=>{ desc=>'DC/DC power output' +, unit=>'W', action=>'sprintf("%.0f", ($pid +{DCDC_V_51}{val} * $pid{DCDC_A_51}{val}))', val=>'---'} ); my $mw=MainWindow->new(); $mw->Button(-text=>" Test ", -command=>sub{test()}, -font=>'Helvet +ica 18 bold', -pady=>20)->pack(); MainLoop; sub test { $pid{DCDC_V_51}{val}=eval($pid{DCDC_V_51}{formula}); print $pid{DCDC_V +_51}{val} ."\n"; $pid{DCDC_A_51}{val}=eval($pid{DCDC_A_51}{formula}); print $pid{DCDC_A +_51}{val} ."\n"; my $formula=$pid{DCDC_W_51}{action}; $pid{DCDC_W_51}{val}=eval($formula); print $pid{DCDC_W_51}{val} ."\n"; } sub U16 { my($a,$b)=@_; return ($a*256+$b); }
This test program can also be downloaded from my website at the following URL: http://obd-amigos.linuxtech.net/test1/amigos-test1.pl

Is there anybody here who uses MacPorts Perl on a M1/M2 Mac who can reproduce this issue with the above test script and perhaps has an idea why this happens?
I'm thinking of opening a bug report at MacPorts but would prefer to first get some feedback here in case it's not a MacPorts issue.
Thanks in advance for any testing / feedback / opinions / insights.

Edit: changed "use POSIX;" to "use POSIX qw(strftime);" in the test script.

Replies are listed 'Best First'.
Re: weird problem with macports perl on apple m1/m2 based system
by hv (Prior) on Jun 10, 2023 at 21:51 UTC

    That is rather odd; the first thing it occurs to me to check is whether on the affected system some environment variable such as PERL5LIB or PERLLIB PERL5OPT could be introducing a use integer or use bigint, or even to check the contents of %INC to see if anything like that is getting loaded.

    I've never heard of a system on which a perl build simply truncated decimals of its own accord - such a build certainly wouldn't pass much of the test suite.

    Update: corrected the name of the environment variable.

      would it help if I add 'no integer;' ad the beginning of the program?

      My problem is I don't actually own a M1 or M2 Mac myself (to be precise I don't own any Mac at all), this problem got reported to me by a user who runs my program on a M1 Mac, and he is the one who tests the code I give him and then reports back the output he gets.
      Now that after some back and forth I finally managed to narrow down the issue to those lines of code posted in the first post I'd prefer not to bother him again straight-away with more questions and tests, I don't want to strain his willingness to help too much.

      That's why I was hoping that someone here with a M1/M2 Mac and good Perl knowledge could look into this a bit.

      If it helps, these are the instructions my user followed to install MacPorts Perl on his M1 MacBook:
      http://obd-amigos.linuxtech.net/files/00-How_to_install_OBD_Amigos_on_macOS.html

        would it help if I add 'no integer;' at the beginning of the program?

        I generally would not recommend making random changes - I would always rather actually understand the root cause of the problem first. You can at least do tests on your own system to see if, for example, setting environment variables allows you to replicate the behaviour that the user has reported.

        I misspoke in my previous message: the environment variable I was thinking of is actually PERL5OPT. So here I see, for example:

        % perl -wle 'print 3.9 * 3.9' 15.21 % export PERL5OPT='-Minteger' % perl -wle 'print 3.9 * 3.9' 9 % export PERL5OPT='-Mbigint' zen2% perl -wle 'print 3.9 * 3.9' 9 % export PERL5OPT='' % perl -wle 'print 3.9 * 3.9' 15.21 %

        If such tests give behaviour that matches what your user reports, then it would be reasonable a) to report the contents of that environment variable at startup, and optionally b) to clear it. But don't get me wrong - I don't think it is highly likely that a strange setting of PERL5OPT is the cause, it's just one of the few things I can think of that could affect something as fundamental as Perl's arithmetic if the perl build is otherwise functional.

        I don't have a Mac, but I think it is relatively unlikely that there is so fundamental a problem on all Macs of this sort; it is more likely something specific to the environment (in the general sense) of this user's system.

Re: weird problem with macports perl on apple m1/m2 based system
by afoken (Chancellor) on Jun 10, 2023 at 21:12 UTC

    Can you reproduce the problem with less code? Tk should not be needed to invoke test().

    Also, you should not use $a and $b, they are reserved for sort by perlvar.

    And you should not need a string eval if you replace the formula and action fields in %pid with code references.

    Both should not be the cause of your problem, though.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      I did previously a one liner test without Tk and couldn't reproduce the issue, that's why I added Tk which is also used in the program where I originally encountered this issue. Therefore I have a feeling that Tk has something to do with this issue.

      I noticed one other strange behavior with MacPorts Perl-Tk, it only seems to accept screen units in pixels, not inches, don't know what's up with that, but that's a different not so important (for me) issue.
Re: weird problem with macports perl on apple m1/m2 based system
by kcott (Archbishop) on Jun 10, 2023 at 21:11 UTC

    G'day perltux,

    Firstly, I don't have M1/M2 so can't do any testing.

    One thing that did stand out for me was "use POSIX;". I don't suppose that has anything to do with your problem; however, this usage is strongly discouraged — see "POSIX: CAVEATS".

    It's good that you're checking here before raising a bug report. Attendence is typically less on the weekends; I've front-paged your post to hopefully gain a wider audience.

    — Ken

      Ok I found why I originally added "use POSIX", it was for the strftime function, therefore I will change that to "use POSIX qw(strftime)" in my application.

        Off-topic to the original question, but relevant to use POSIX.

        Time::Piece provides equivalent functionality to POSIX::strftime, and has been core since 5.10.0. Read the docs carefully before using, though, because by default it replaces the core gmtime() and localtime() functions with ones that return an object if called in scalar context.

      Thanks for the front-pageing and for the advice with regards to "use POSIX", I can't remember why I added that, there must have been a reason because I don't normally use that by default, but I will look into it again.
Re: weird problem with macports perl on apple m1/m2 based system
by NetWallah (Canon) on Jun 10, 2023 at 21:25 UTC
    I don't have any Macs so I tested on a PC.

    I modified your code to get rid of the evals. With some luck, this may fix your (unidentified) problem.

    #!/usr/bin/env perl use strict; use warnings; use POSIX; use Tk; my %pid; %pid=( DCDC_A_51=>{cmd=>'22 46 5B', cu=>'51', desc=>'DC/DC output curren +t t30', unit=>'A', d=>2, formula=>sub{sprintf("%.2f", U1 +6(1,4)/16)}}, DCDC_V_51=>{cmd=>'22 46 5C', cu=>'51', desc=>'DC/DC output voltag +e t30', unit=>'V', d=>2, formula=>sub{sprintf("%.2f", U1 +6(25,253)/512)}, val=>'---'}, DCDC_W_51=>{ desc=>'DC/DC power output' +, unit=>'W', action=>sub{sprintf("%.0f", ($ +pid{DCDC_V_51}{val} * $pid{DCDC_A_51}{val}))}, val=>'---'} ); my $mw=MainWindow->new(); $mw->Button(-text=>" Test ", -command=>sub{test()}, -font=>'Helvet +ica 18 bold', -pady=>20)->pack(); MainLoop; sub test { $pid{DCDC_V_51}{val}=$pid{DCDC_V_51}{formula}->(); print $pid{DCDC +_V_51}{val} ."\n"; $pid{DCDC_A_51}{val}=$pid{DCDC_A_51}{formula}->(); print $pid{DCDC +_A_51}{val} ."\n"; $pid{DCDC_W_51}{val}=$pid{DCDC_W_51}{action}->(); print $pid{DCDC_W_51}{val} ."\n"; } sub U16 { my($a,$b)=@_; return ($a*256+$b); }

                    "These opinions are my own, though for a small fee they be yours too."

      The evals are there because this test code is an extract of the larger program were I originally encountered the problem and there they are necessary (at least AFAIK), but the point isn't whether my code is optimized or not, the point is the weird behavior on the M1/M2 Macs, on all other systems I tested it on the code works fine and provides the expected correct result.
      If you are curious the original program is here: http://obd-amigos.linuxtech.net/files/
Re: weird problem with macports perl on apple m1/m2 based system
by karlgoethebier (Abbot) on Jun 11, 2023 at 13:23 UTC

    I follow the sleuth of the anonymous monk: What does locale -k LC_NUMERIC say? Wild guessing, I know.

    Update: From sprintf:

    «If use locale (including use locale ':not_characters') is in effect and POSIX::setlocale has been called, the character used for the decimal separator in formatted floating-point numbers is affected by the LC_NUMERIC locale. See perllocale and POSIX.»

    «The Crux of the Biscuit is the Apostrophe»

      AFAIK, based on Tests on my Linux PC, to get LC_NUMERIC to influence the output of sprintf requires adding 'use locale;' (in addition to 'use POSIX;' or 'use POSIX qw(locale_h);') in the script.

      On my Linux PC I actually have a locale (de_DE) that uses comma as decimal point and dot as thousands separator and despite that it has no influence on the calculations in the test program or the original application.

      But since 'use POSIX;' also includes 'use POSIX qw(locale_h);' I have now modified my test script to use 'use POSIX qw(strftime);' instead of 'use POSIX;' and asked the Mac M1 user to download and run the test script again and based on his feedback it's still ignoring decimals in the multiplication, the output is still:
      12.99 16.25 192

        That would have been too nice if it had been this problem. Too bad. Good luck with the further research.

        «The Crux of the Biscuit is the Apostrophe»

Re: weird problem with macports perl on apple m1/m2 based system
by perltux (Monk) on Jun 12, 2023 at 15:41 UTC
    Is there really no MacPorts Perl on M1/M2 Mac user here who could try the test script and confirm the issue?
    It would take less than a minute to download and run the test script and report back the ouput.

    This would at least confirm that it's not a specific issue of the Mac of the user of my application.
    Many thanks in advance

      I didn't run your script because I installed p5-tk with MacPorts and got a display error, I think because I have to install xquartz and I'm not interested in doing that right now on this machine. I did just now run the below though, with a 5.34 perl installed via MacPorts on an M1 mac:

      % uname -a Darwin ... 21.6.0 Darwin Kernel Version 21.6.0: Mon Apr 24 21:11:17 PD +T 2023; root:xnu-8020.240.18.701.5~1/RELEASE_ARM64_T6000 arm64 % perl -le 'print 12.99 * 16.25' 211.0875
        I don't know about xquartz (as I said I don't own a Mac so I'm not familiar with what xquartz is), but you would have to install xorg from MacPorts like this:

        sudo port install xorg
        sudo port install p5-tk

        that's taken from the macOS installation instructions for my application, these instructions were written for me by another macOS user (with an Intel Mac though).
        http://obd-amigos.linuxtech.net/files/00-How_to_install_OBD_Amigos_on_macOS.html

        Since these are MacPorts packages, isn't it quite easy to uninstall them cleanly again after the test, if you have no need for them?

        Thanks for the one-liner test but unfortunately it's not as simple as that to trigger this issue, I also gave the user of my application a similar one-liner (but with eval) at first, without triggering the issue. I have a feeling that Tk is needed to trigger the issue.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11152734]
Approved by johngg
Front-paged by kcott
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (1)
As of 2024-04-15 12:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found