You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby中如何保留有理数原始形式而非自动约分?

如何在Ruby中保留有理数的原始输入形式

Ruby内置的Rational类从设计上就会自动将分数约分为最简形式——这是它的核心特性,目的是保证数值计算的一致性和效率,所以你没法直接让它存储3/12这种未约分的形式。不过我们可以通过自定义类的方式来实现需求,既保留原始的分子分母,又能兼容Rational的计算能力。

解决方案:自定义RawRational类

我们可以写一个简单的类来封装原始的分子和分母,同时提供转换为标准Rational的方法,以及自定义的输出格式:

class RawRational
  # 提供只读的分子分母访问器
  attr_reader :numerator, :denominator

  def initialize(numerator, denominator)
    @numerator = numerator
    @denominator = denominator
    # 基础校验:分母不能为0
    raise ArgumentError, "Denominator cannot be zero" if denominator.zero?
  end

  # 转换为标准Rational,用于数值计算
  def to_r
    Rational(numerator, denominator)
  end

  # 自定义字符串输出,显示原始分数形式
  def to_s
    "#{numerator}/#{denominator}"
  end

  # 示例:重载加法运算符,支持与其他RawRational或Rational相加
  def +(other)
    # 统一转换为RawRational处理
    other_raw = if other.is_a?(RawRational)
                  other
                elsif other.respond_to?(:numerator) && other.respond_to?(:denominator)
                  RawRational.new(other.numerator, other.denominator)
                else
                  raise TypeError, "Cannot add #{other.class} to RawRational"
                end
    # 用标准Rational计算结果,再封装为RawRational
    result_r = to_r + other_raw.to_r
    RawRational.new(result_r.numerator, result_r.denominator)
  end
end

使用示例

# 创建原始形式的有理数
rNo = RawRational.new(3, 12)
puts rNo.to_s  # 输出: 3/12
puts rNo.to_r  # 输出: 1/4(标准Rational的最简形式)

# 支持运算
another = RawRational.new(1, 4)
sum = rNo + another
puts sum.to_s  # 输出: 1/2(计算后的最简形式,你也可以修改加法逻辑保留其他形式)

补充说明

如果你只是偶尔需要显示原始输入的分子分母,也可以在创建Rational时额外存储原始值,比如用一个哈希或者元组:

raw_num, raw_den = 3, 12
rNo = Rational(raw_num, raw_den)
# 保留原始值
original_fraction = { numerator: raw_num, denominator: raw_den }
puts "原始形式: #{original_fraction[:numerator]}/#{original_fraction[:denominator]}"
puts "最简形式: #{rNo}"

这种方式更轻量,但如果需要频繁处理原始形式的分数,自定义类会更优雅。

内容的提问来源于stack exchange,提问作者FDI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:37:18