在 Julia 中解析对 rational 的输入
parse input to rational in Julia
我想读取用户输入并将其存储为有理数,无论是什么类型:整数、浮点数或有理数。例如:
5 --> store it as 5//1
2.3 --> store it as 23//10
4//7 --> store it as 4//7
此刻我写了以下内容:
a = convert(Rational,parse(Float64,readline(STDIN)))
如果我输入一个整数就好了,比如 5。
但是如果我输入 2.3,a
存储 2589569785738035//1125899906842624
。
如果我输入分数(无论是 4/7
形式还是 4//7
形式),我都会得到 ArgumentError: invalid number format for Float64
.
如何解决Float&Rational问题?
一种方法是parse the raw input to an Expr
(symbols), eval the expression, convert it to a Float64
and use rationalize简化有理生成:
julia> rationalize(convert(Float64, eval(parse("5"))))
5//1
julia> rationalize(convert(Float64, eval(parse("2.3"))))
23//10
julia> rationalize(convert(Float64, eval(parse("4/7"))))
4//7
julia> rationalize(convert(Float64, eval(parse("4//7"))))
4//7
rationalize
适用于近似浮点数,您可以在参数 tol
.
中指定错误
使用 Julia 版本 0.4.3 测试
Update:parse
方法在 Julia 版本 >= 1.0 中被弃用。应该使用两种方法:Base.parse
(just for numbers, and it requires a Type argument) and Meta.parse
(对于表达式):
julia> rationalize(convert(Float64, eval(parse(Int64, "5"))))
5//1
julia> rationalize(convert(Float64, eval(parse(Float64, "2.3"))))
23//10
用一个高度复合的整数乘法(然后除法)效果很好。
julia> N = 2*2 * 3*3 * 5*5 * 7 * 11 * 13
900900
julia> a = round(Int, N * parse(Float64, "2.3")) // N
23//10
julia> a = round(Int, N * parse(Float64, "5")) // N
5//1
julia> a = round(Int, N * parse(Float64, "9.1111111111")) // N
82//9
您可以实现自己的 parse
:
function Base.parse(::Type{Rational{Int}}, x::ASCIIString)
ms, ns = split(x, '/', keep=false)
m = parse(Int, ms)
n = parse(Int, ns)
return m//n
end
Base.parse(::Type{Rational}, x::ASCIIString) = parse(Rational{Int}, x)
我想读取用户输入并将其存储为有理数,无论是什么类型:整数、浮点数或有理数。例如:
5 --> store it as 5//1
2.3 --> store it as 23//10
4//7 --> store it as 4//7
此刻我写了以下内容:
a = convert(Rational,parse(Float64,readline(STDIN)))
如果我输入一个整数就好了,比如 5。
但是如果我输入 2.3,a
存储 2589569785738035//1125899906842624
。
如果我输入分数(无论是 4/7
形式还是 4//7
形式),我都会得到 ArgumentError: invalid number format for Float64
.
如何解决Float&Rational问题?
一种方法是parse the raw input to an Expr
(symbols), eval the expression, convert it to a Float64
and use rationalize简化有理生成:
julia> rationalize(convert(Float64, eval(parse("5"))))
5//1
julia> rationalize(convert(Float64, eval(parse("2.3"))))
23//10
julia> rationalize(convert(Float64, eval(parse("4/7"))))
4//7
julia> rationalize(convert(Float64, eval(parse("4//7"))))
4//7
rationalize
适用于近似浮点数,您可以在参数 tol
.
使用 Julia 版本 0.4.3 测试
Update:parse
方法在 Julia 版本 >= 1.0 中被弃用。应该使用两种方法:Base.parse
(just for numbers, and it requires a Type argument) and Meta.parse
(对于表达式):
julia> rationalize(convert(Float64, eval(parse(Int64, "5"))))
5//1
julia> rationalize(convert(Float64, eval(parse(Float64, "2.3"))))
23//10
用一个高度复合的整数乘法(然后除法)效果很好。
julia> N = 2*2 * 3*3 * 5*5 * 7 * 11 * 13 900900 julia> a = round(Int, N * parse(Float64, "2.3")) // N 23//10 julia> a = round(Int, N * parse(Float64, "5")) // N 5//1 julia> a = round(Int, N * parse(Float64, "9.1111111111")) // N 82//9
您可以实现自己的 parse
:
function Base.parse(::Type{Rational{Int}}, x::ASCIIString)
ms, ns = split(x, '/', keep=false)
m = parse(Int, ms)
n = parse(Int, ns)
return m//n
end
Base.parse(::Type{Rational}, x::ASCIIString) = parse(Rational{Int}, x)