如果 Perl 已经链接到 libm,为什么没有向用户公开任何函数?

问题描述

Perl 已经链接libm

$ ldd $(which perl)
    ...
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd8ce2ea000)
    ...

因此,如果 Perl 已经链接libm,为什么不经常使用的功能ceilfloorpow 提供为 CORE::GLOBAL 或在另一个命名空间中提供?为什么 perldoc -q ceil 指向 POSIX.pm 作为这个函数的来源,为什么 Math::Libm 甚至存在?

Python 还链接libm,当您使用模块 import math 中可用的符号运行 math 时,该 math.ceil(num) 会向用户公开,并且可以从外部引用,例如 {{1}}

解决方法

Perl 确实内置了数学函数:只是它对您可能需要的函数的想法与 1970 年代的小型计算机相当。我能找到的都有:

#!/usr/bin/env perl
# maths_builtins.pl - some (all?) of the libm functions built in to Perl
# scruss - 2021-05

my $val = -1.234;

print 'abs(',$val,')',"\t=  ",abs($val),"\n";

my $pi = 4 * atan2( 1,1 );
print '4*atan2(1,1)',$pi,"\t(= π)","\n";
print 'cos(π/6)',cos( $pi / 6 ),"\n";

my $e = exp(1);
print 'exp(1)',"\t\t=  ",$e,"\t(= e)","\n";
print 'int(',"\t= ",int($val),"\n";
print 'log(e)',log($e),"\n";
print 'sin(π/6)',sin( $pi / 6 ),"\n";
print 'sqrt(3)/2',sqrt(3) / 2,"\n";
print 'sqrt(3)**2',sqrt(3)**2,"\n";
exit;

导致:

abs(-1.234)     =  1.234
4*atan2(1,1)    =  3.14159265358979     (= π)
cos(π/6)        =  0.866025403784439
exp(1)          =  2.71828182845905     (= e)
int(-1.234)     = -1
log(e)          =  1
sin(π/6)        =  0.5
sqrt(3)/2       =  0.866025403784439
sqrt(3)**2      =  3

请注意,Perl 没有 pow() 函数,而是具有 ** 运算符,就像 FORTRAN 一样。您没有得到 tan() 函数,因为它是 sin($x)/cos($x)。如果您需要其他超越函数,这就是为什么他们将 trigonometric functions table(PDF,第 39 页)放在所有优秀的编程书籍中的原因。

我不记得自己曾经使用或需要 ceil()floor(),但是 Perl 缺少 sgn() 作为内置函数每次都会让我感到困惑。由于 Perl 本质上是一种无类型脚本语言,因此已经可以使用字符串函数(例如 sprintf "%.f",$val)来完成诸如舍入之类的数字园艺任务。