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
相关产品推荐
相关产品推荐

