有没有办法阻止 Julia 对 BigFloats 使用科学(指数)符号?
Is there a way to stop Julia using scientific (exponential) notation with BigFloats?
好的,从表面上看,我的问题似乎很简单。我想将无理数的小数部分取到指定位数并将其视为整数。例如,如果我的无理数是 2.657829...并且我想要五位数,我正在寻找 65782(尽管我实际上正在处理 'Big' 个数字)。
这很容易使用字符串实现,例如,如果我想要根 3 的小数部分为 50 位:
function main_1(n::Int, m::Int)::BigInt
setprecision(Int(trunc((m + 3) * log2(10))))
sr = string(sqrt(big(n)))
ff = findfirst(sr, '.')
dp = parse(BigInt, sr[ff + 1:ff + m])
return dp
end
@time main_1(3, 50)
输出为73205080756887729352744634150587236694280525381038
。
但是,当我只处理数字时,我讨厌使用字符串!我希望能够做的是从 BigFloat 开始,减去整数部分,将结果乘以适当的因子 10,将结果四舍五入为零,然后将其转换为 BigInt。问题是 Julia 使用科学/指数符号,所以我似乎无法仅使用数字来实现我想要的。以下(部分)代码显示了问题:
function main_2(n::Int, m::Int)::BigFloat
setprecision(Int(trunc((m + 3) * log2(10))))
sr = sqrt(big(n))
tr = trunc(sr)
dp = (sr - tr) * big(10.0) ^ 50
return dp
end
@time main_2(3, 50)
这种情况下的输出是 7.32050807568877293527446341505872366942805253810380625e+49
(在舍入阶段会删除一些额外的数字)。
所以我的问题是,有没有什么方法可以不借助字符串来实现我的 objective?
在不使用字符串的情况下实现此目的的一种方法是在执行减法之前将结果及其整数部分转换为 BigInt(并将函数类型从 BigFloat 到 BigInt):
function main_2(n::Int, m::Int)::BigInt
setprecision(Int(trunc((m + 3) * log2(10))))
# Calc the sqrt
result = sqrt(big(n))
# Convert the whole number to BigInt to the specified precision
sr = convert(BigInt, trunc(result*big(10)^m))
# Convert the integer part to BigInt
tr = convert(BigInt, trunc(result)*big(10)^m)
dp = sr - tr
return dp
end
上面的实现与main_1
功能相比,有一点改进:
julia> @time main_1(3, 50)
0.000042 seconds (36 allocations: 5.254 KiB)
73205080756887729352744634150587236694280525381038
julia> @time main_2(3, 50)
0.000028 seconds (51 allocations: 1.617 KiB)
73205080756887729352744634150587236694280525381038
编辑:
其他方式(如@Bill 所评论)只是 trunc 结果(摆脱 InexactError()
)并将函数类型更改为 BigInt:
function main_2(n::Int, m::Int)::BigInt
setprecision(Int(trunc((m + 3) * log2(10))))
sr = sqrt(big(n))
tr = trunc(sr)
dp = (sr - tr) * big(10.0) ^ 50
return trunc(dp)
end
测试后:
julia> @time main_2(3,50)
0.000026 seconds (28 allocations: 1.016 KiB)
73205080756887729352744634150587236694280525381038
好的,从表面上看,我的问题似乎很简单。我想将无理数的小数部分取到指定位数并将其视为整数。例如,如果我的无理数是 2.657829...并且我想要五位数,我正在寻找 65782(尽管我实际上正在处理 'Big' 个数字)。
这很容易使用字符串实现,例如,如果我想要根 3 的小数部分为 50 位:
function main_1(n::Int, m::Int)::BigInt
setprecision(Int(trunc((m + 3) * log2(10))))
sr = string(sqrt(big(n)))
ff = findfirst(sr, '.')
dp = parse(BigInt, sr[ff + 1:ff + m])
return dp
end
@time main_1(3, 50)
输出为73205080756887729352744634150587236694280525381038
。
但是,当我只处理数字时,我讨厌使用字符串!我希望能够做的是从 BigFloat 开始,减去整数部分,将结果乘以适当的因子 10,将结果四舍五入为零,然后将其转换为 BigInt。问题是 Julia 使用科学/指数符号,所以我似乎无法仅使用数字来实现我想要的。以下(部分)代码显示了问题:
function main_2(n::Int, m::Int)::BigFloat
setprecision(Int(trunc((m + 3) * log2(10))))
sr = sqrt(big(n))
tr = trunc(sr)
dp = (sr - tr) * big(10.0) ^ 50
return dp
end
@time main_2(3, 50)
这种情况下的输出是 7.32050807568877293527446341505872366942805253810380625e+49
(在舍入阶段会删除一些额外的数字)。
所以我的问题是,有没有什么方法可以不借助字符串来实现我的 objective?
在不使用字符串的情况下实现此目的的一种方法是在执行减法之前将结果及其整数部分转换为 BigInt(并将函数类型从 BigFloat 到 BigInt):
function main_2(n::Int, m::Int)::BigInt
setprecision(Int(trunc((m + 3) * log2(10))))
# Calc the sqrt
result = sqrt(big(n))
# Convert the whole number to BigInt to the specified precision
sr = convert(BigInt, trunc(result*big(10)^m))
# Convert the integer part to BigInt
tr = convert(BigInt, trunc(result)*big(10)^m)
dp = sr - tr
return dp
end
上面的实现与main_1
功能相比,有一点改进:
julia> @time main_1(3, 50)
0.000042 seconds (36 allocations: 5.254 KiB)
73205080756887729352744634150587236694280525381038
julia> @time main_2(3, 50)
0.000028 seconds (51 allocations: 1.617 KiB)
73205080756887729352744634150587236694280525381038
编辑:
其他方式(如@Bill 所评论)只是 trunc 结果(摆脱 InexactError()
)并将函数类型更改为 BigInt:
function main_2(n::Int, m::Int)::BigInt
setprecision(Int(trunc((m + 3) * log2(10))))
sr = sqrt(big(n))
tr = trunc(sr)
dp = (sr - tr) * big(10.0) ^ 50
return trunc(dp)
end
测试后:
julia> @time main_2(3,50)
0.000026 seconds (28 allocations: 1.016 KiB)
73205080756887729352744634150587236694280525381038