4

我想读取用户输入并将其存储为 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存储2589569785738035//1125899906842624 .

如果我输入一个分数(无论是在 form4/7还是 form 4//7),我会得到一个ArgumentError: invalid number format for Float64.

如何解决 Float&Rational 问题?

4

3 回答 3

8

一种方法是将原始输入解析Expr为(符号),评估表达式,将其转换为 aFloat64并使用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 进行测试


更新:该parse方法在 Julia 版本 >= 1.0 中已弃用。应该使用两种方法:(Base.parse仅用于数字,并且需要Type参数)和Meta.parse(用于表达式):

julia> rationalize(convert(Float64, eval(parse(Int64, "5"))))
5//1

julia> rationalize(convert(Float64, eval(parse(Float64, "2.3"))))
23//10
于 2016-02-15T17:01:53.723 回答
0

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

朱莉娅> 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
于 2016-02-17T04:58:16.583 回答
0

您可以实现自己的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)
于 2016-09-01T19:20:30.487 回答