Gnuplot 阶乘计算输出
Gnuplot factorial calculation output
我想在 gnuplot 中测试递归函数。
下面是函数
factorial(n)= ((n==1?sprintf("1"):sprintf("%f",n*factorial(n-1))))
当 factorial(100) 测试时,它看起来不错
93326215443944102188325606108575267240944254854960571509166910400407995064242937148632694030450512898042989296944474898258737204311236641477561877016501813248.000000
为了使数字成为整数,我这样更改了 sprintf
factorial(n)= ((n==1?sprintf("1"):sprintf("%d",n*factorial(n-1))))
但是,结果很奇怪;它似乎超出了整数大小的范围?
-2147483648
所以我改变了实数类型的功能,没有浮点以下的数字
factorial(n)= ((n==1?sprintf("1"):sprintf("%.0f",n*factorial(n-1))))
但是,结果比较奇怪,
-75703234367175440481992733883343393025021587121454605713387911182978138051561570016048371488788270318477285688499861254195149884149214115360733197762560
你能解释一下它是什么吗?
谢谢,
32位能表示的最大整数是2147483647。
所以一个 32 位整数(gnuplot 到 5.2 版)用完了 12 位之间的位!和 13!
一个 64 位整数(gnuplot 5.4)用完了 20 位!和 21!
如果您使用双精度浮点运算,它可以容纳更大的数字,但位数仍然限制了精度。 64 位浮点数只有 ~53 位精度,因此它可以表示的最大精确阶乘实际上小于 64 位整数所能处理的。
请注意,如果 n 是整数,则所有示例 gnuplot 代码都使用整数运算。更改为浮点格式进行打印不会改变这一点。
不确定您的最终目标是什么...但是为了乐趣和可行性,您可以可以使用 gnuplot 计算 Factorial(100)
。
但是,您将获得字符串形式的结果。我还没有测试参数 a
和 d
的限制是什么。对于 a
,这将是最大字符串长度,对于 d
,可能是整数限制(32 位或 64 位)。
代码:
### factorial for large numbers (output as string!)
reset session
# a: integer number string
# d: integer number
Multiply(a,d) = (_u=0, _tmp='', _n=strlen(a), sum [_i=1:_n] (_j=_n-_i+1, \
_m1=a[_j:_j]*d, _d1=(_m1+_u)%10, _u=(_m1+_u)/10, \
_tmp=sprintf("%d%s",_d1,_tmp),0), _u ? sprintf("%d%s",_u,_tmp) : _tmp)
Factorial(n) = (_tmp="1", sum [_j=1:n] ( _tmp=Multiply(_tmp,_j), 0), _tmp)
print Factorial(100)
### end of code
结果:100!(其实最后是24个0)
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
我想在 gnuplot 中测试递归函数。 下面是函数
factorial(n)= ((n==1?sprintf("1"):sprintf("%f",n*factorial(n-1))))
当 factorial(100) 测试时,它看起来不错
93326215443944102188325606108575267240944254854960571509166910400407995064242937148632694030450512898042989296944474898258737204311236641477561877016501813248.000000
为了使数字成为整数,我这样更改了 sprintf
factorial(n)= ((n==1?sprintf("1"):sprintf("%d",n*factorial(n-1))))
但是,结果很奇怪;它似乎超出了整数大小的范围?
-2147483648
所以我改变了实数类型的功能,没有浮点以下的数字
factorial(n)= ((n==1?sprintf("1"):sprintf("%.0f",n*factorial(n-1))))
但是,结果比较奇怪,
-75703234367175440481992733883343393025021587121454605713387911182978138051561570016048371488788270318477285688499861254195149884149214115360733197762560
你能解释一下它是什么吗? 谢谢,
32位能表示的最大整数是2147483647。 所以一个 32 位整数(gnuplot 到 5.2 版)用完了 12 位之间的位!和 13!
一个 64 位整数(gnuplot 5.4)用完了 20 位!和 21!
如果您使用双精度浮点运算,它可以容纳更大的数字,但位数仍然限制了精度。 64 位浮点数只有 ~53 位精度,因此它可以表示的最大精确阶乘实际上小于 64 位整数所能处理的。
请注意,如果 n 是整数,则所有示例 gnuplot 代码都使用整数运算。更改为浮点格式进行打印不会改变这一点。
不确定您的最终目标是什么...但是为了乐趣和可行性,您可以可以使用 gnuplot 计算 Factorial(100)
。
但是,您将获得字符串形式的结果。我还没有测试参数 a
和 d
的限制是什么。对于 a
,这将是最大字符串长度,对于 d
,可能是整数限制(32 位或 64 位)。
代码:
### factorial for large numbers (output as string!)
reset session
# a: integer number string
# d: integer number
Multiply(a,d) = (_u=0, _tmp='', _n=strlen(a), sum [_i=1:_n] (_j=_n-_i+1, \
_m1=a[_j:_j]*d, _d1=(_m1+_u)%10, _u=(_m1+_u)/10, \
_tmp=sprintf("%d%s",_d1,_tmp),0), _u ? sprintf("%d%s",_u,_tmp) : _tmp)
Factorial(n) = (_tmp="1", sum [_j=1:n] ( _tmp=Multiply(_tmp,_j), 0), _tmp)
print Factorial(100)
### end of code
结果:100!(其实最后是24个0)
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000