Input 在Julia中解析rational的输入

Input 在Julia中解析rational的输入,input,type-conversion,julia,rational-number,Input,Type Conversion,Julia,Rational Number,我想读取用户输入并将其存储为一个有理数,不管类型是什么:integer、float或Rational。例如: 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存储258956975738

我想读取用户输入并将其存储为一个有理数,不管类型是什么:integer、float或Rational。例如:

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
存储
258956975738035//1125899906842624

如果我输入一个分数(无论是以
4/7
格式还是以
4//7
格式),我会得到一个
参数错误:Float64的数字格式无效

如何解决Float和Rational问题?

一种方法是将原始输入转换为
Expr
(符号)表达式,将其转换为
Float64
,并用于简化生成的Rational:

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
使用近似浮点数,您可以在参数中指定错误

使用Julia版本0.4.3进行测试


更新:在Julia version>=1.0中,
解析
方法被弃用。应该使用两种方法:(仅用于数字,并且需要类型参数)和(用于表达式):

用一个高度复合的整数乘法(然后除法)效果很好

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 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.1111111”)//N 82//9
您可以实现自己的
解析

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)

这应该可以通过
parse(Rational{Int},string)
获得,但目前还没有实现。@mschauer是的,我试过了,但没有成功。0.5年后会是这样吗?
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)