有没有更好的方法来使用 Pari/GP 提取实数的数字?
Is there a better way to extract the digits of a real number using Pari/GP?
这是我当前的代码,但它很丑陋,我担心来自非常大或非常小的数字可能出现的边缘情况。有更好的方法吗?
real_to_int(n)={
if(n==floor(n),return(floor(n))); \ If "n" is a whole number we're done
my(v=Vec(strprintf("%g",n))); \ Convert "n" to a zero-padded character vector
my(d=sum(i=1,#v,i*(v[i]=="."))); \ Find the decimal point
my(t=eval(concat(v[^d]))); \ Delete the decimal point and reconvert to a number
my(z=valuation(t,10)); \ Count trailing zeroes
t/=10^z; \ Get rid of trailing zeroes
return(t)
}
您可以将输入的实数拆分为整数和小数部分,而无需查找点。
real_to_int(n) = {
my(intpart=digits(floor(n)));
my(fracpartrev=fromdigits(eval(Vecrev(Str(n))[1..-(2+#intpart)])));
fromdigits(concat(intpart, Vecrev(digits(fracpartrev))))
};
real_to_int(123456789.123456789009876543210000)
> 12345678912345678900987654321
请注意,digits
和 fromdigits
的组合为您消除了数字列表中的所有前导零。
问题没有明确定义,因为从实数(以二进制形式在内部存储)到十进制字符串的转换可能需要舍入,而如何完成取决于许多因素,例如 format
默认值, 或当前 bitprecision
.
可以得到 t_REAL
的内部二进制表示为 m * 2^e,其中 m
和 e
都是整数。
install(mantissa2nr, GL);
real_to_int(n) =
{
e = exponent(n) + 1 - bitprecision(n);
[mantissa2nr(n, 0), e];
}
? [m, e] = real_to_int(Pi)
%1 = [267257146016241686964920093290467695825, -126]
? m * 1. * 2^e
%2 = 3.1415926535897932384626433832795028842
使用 [m, e] 我们获得了数字的精确(有理数)内部表示,并且两者都是明确定义的,即独立于所有设置。 m
是十进制请求的二进制等价物。
这是我当前的代码,但它很丑陋,我担心来自非常大或非常小的数字可能出现的边缘情况。有更好的方法吗?
real_to_int(n)={
if(n==floor(n),return(floor(n))); \ If "n" is a whole number we're done
my(v=Vec(strprintf("%g",n))); \ Convert "n" to a zero-padded character vector
my(d=sum(i=1,#v,i*(v[i]=="."))); \ Find the decimal point
my(t=eval(concat(v[^d]))); \ Delete the decimal point and reconvert to a number
my(z=valuation(t,10)); \ Count trailing zeroes
t/=10^z; \ Get rid of trailing zeroes
return(t)
}
您可以将输入的实数拆分为整数和小数部分,而无需查找点。
real_to_int(n) = {
my(intpart=digits(floor(n)));
my(fracpartrev=fromdigits(eval(Vecrev(Str(n))[1..-(2+#intpart)])));
fromdigits(concat(intpart, Vecrev(digits(fracpartrev))))
};
real_to_int(123456789.123456789009876543210000)
> 12345678912345678900987654321
请注意,digits
和 fromdigits
的组合为您消除了数字列表中的所有前导零。
问题没有明确定义,因为从实数(以二进制形式在内部存储)到十进制字符串的转换可能需要舍入,而如何完成取决于许多因素,例如 format
默认值, 或当前 bitprecision
.
可以得到 t_REAL
的内部二进制表示为 m * 2^e,其中 m
和 e
都是整数。
install(mantissa2nr, GL);
real_to_int(n) =
{
e = exponent(n) + 1 - bitprecision(n);
[mantissa2nr(n, 0), e];
}
? [m, e] = real_to_int(Pi)
%1 = [267257146016241686964920093290467695825, -126]
? m * 1. * 2^e
%2 = 3.1415926535897932384626433832795028842
使用 [m, e] 我们获得了数字的精确(有理数)内部表示,并且两者都是明确定义的,即独立于所有设置。 m
是十进制请求的二进制等价物。