什么';awk检查任意整数精度的最佳方法

什么';awk检查任意整数精度的最佳方法,awk,precision,arbitrary-precision,Awk,Precision,Arbitrary Precision,从GNU gawk的页面 https://www.gnu.org/software/gawk/manual/html_node/Checking-for-MPFR.html 他们有一个公式来检查任意精度 function adequate_math_precision(n) { return (1 != (1+(1/(2^(n-1))))) } 我的问题是:在整数数学域中使用如下公式不是会更有效吗 ( 2^abs(n) - 1 ) % 2 # note 2^(n-1) vs. 2^|n|

从GNU gawk的页面

https://www.gnu.org/software/gawk/manual/html_node/Checking-for-MPFR.html
他们有一个公式来检查任意精度

function adequate_math_precision(n) { return (1 != (1+(1/(2^(n-1))))) }
我的问题是:在整数数学域中使用如下公式不是会更有效吗

( 2^abs(n) - 1 ) % 2   # note 2^(n-1) vs. 2^|n| - 1
由于2的任何幂也必须是偶数,那么减去1必须始终是奇数,那么它在2上的模(%)就成为is_odd()的指示函数,表示
n>=0
,而
abs(n)
则处理它为负数的情况


或者模是否需要对浮点进行强制转换,从而抵消任何增益?

好问题。让我们来解决它

建议的代码片段旨在检查是否使用
-M
选项调用了gawk

我会在底部附加一些离题的选项

函数的参数
n
是必须执行的任何操作所需的浮点精度。所以,假设您的脚本在某个库中,并且将被调用,但您无法控制它。您将在脚本开始时运行该函数,以立即抛出异常并退出,这表明由于缺少存储数字的位,最终结果将是错误的

您的代码保持在整数域中:整数的二次幂就是整数。这里不需要使用
abs(n)
,因为没有必要首先指定需要多少位作为负数

然后从一个偶数、整数中减去一。现在,除非
n=0
,在这种情况下
2^0=1
,然后代码读取
(1-1)%2=0
,否则代码段将始终返回
1
,因为奇数除以2的商(
%
)是1

问题是:您试图在一个函数中计算一个可能愚蠢的大数字,这个函数应该首先检查您是否能够这样做

因为2的任何幂也必须是偶数,所以减去1必须始终是偶数 如果是奇数,则其2的模(%)成为 是n>=0的_odd(),而abs(n)处理其 没有

除了我们上面讨论的
n=0
之外,您是对的。这段代码将告诉我们,2的任何幂都是偶数,而2的任何幂减去1都是奇数。我们在讨论另一个问题,完全是深思熟虑

让我们分析另一个函数:

return (1 != (1+(1/(2^(n-1)))))
请记住,awk中的布尔值是这样运行的:
0=false
和非零等于true。因此,如果
1+x
,其中
x
是一个非常小的数字,则从数学上来说,通常是两的大幂(
2^122
,在示例页面中)保证是
=1
,在数字世界中,情况并非如此。在某一点上,浮点计算将达到精度的最低点,将向下舍入,
x=0
将突然声明。此时,任意精度函数将返回
0
:false:1等于1


关于类型和数据表示的更大讨论 您链接的页面解释了使用
-M
选项调用的gawk的精度。这听起来像Technobahblah,让我们来解释一下

在某一点上,您的操作系统架构必须决定如何存储数据,如何在内存中表示数据,以便再次访问和显示数据。整数、浮点、双精度、无符号整数等术语都是数据表示的示例。我们这里是寻址整数表示:整数是如何存储在内存中的

32位系统将使用4个字节表示和整数,这反过来决定整数的大小。32位从最高有效位(MSB)读取到较低有效位(LSB),如果有符号,一位将表示符号(MSB通常会大大减少整数的最大大小)

如果要求计算一个较大的数字,机器将尝试适应可用的最大数字。如果最终结果大于该值,则会出现溢出,并最终导致错误结果或错误。许多在线挑战通常要求您为任意长循环或大总和编写代码,然后使用将打破64位障碍的输入进行测试,以查看您是否掌握了适当的索引类型

AWK不是强类型语言。也就是说,任何变量都可以存储数据,而不管类型如何。数据类型可以更改,并且在运行时由解释器确定,因此开发人员无需在意。例如:

$awk '{a="this is text"; print a; a=2; print a; print a+3.0*2}'
-| this is text
-| 2
-| 8
在本例中,
a
是文本,然后是整数,可以求和为浮点数并打印为整数,而无需任何特殊类型处理

将显示以下代码段:

$ gawk -M 'BEGIN {
>   s = 2.0
>   for (i = 1; i <= 7; i++)
>       s = s * (s - 1) + 1
>   print s
> }'
-| 113423713055421845118910464
$gawk-M'开始{
>s=2.0
>对于(i=1;is=s*(s-1)+1
>印刷品
> }'
-| 113423713055421845118910464
后面有一些数学巫术,我们将跳过它。因为
s
被解释为浮点数,最终结果被计算为浮点数

尝试在Windows calculator上以十进制形式输入该数字,它将失败。尽管您可以将其作为二进制进行计算。您需要程序员设置,并将其相加到53位,才能将其作为无符号整数

53在这里是一个神奇的数字:使用
-M
选项,gawk对数字使用任意精度。换句话说,它占用了多少位是必需的,跟踪它们并打破了本机操作系统架构。默认选项说,gawk将为任何给定的任意数字分配53位。有趣的是,实际结果是nippet是错误的,它需要100位才能正确计算

为了实现任意大数处理,gawk依赖一个名为MPFR的外部库。提供任意大数后,MPFR将处理内存分配和位请求以存储它。但是,gawk和MPFR之间的接口并不完美,gawk无法始终控制MPFR将使用的类型。如果