首页 文章

在Ruby中将数字四舍五入到最接近的八分之一或三分之一

提问于
浏览
2

我希望将任何给定数字四舍五入到Ruby中的八分之一或三分之一,以最接近的为准 .

我希望输出像 1/82/3 .

我尝试过以下方法:

scalar_in_eighths = (scalar * 8.0).round / 8.0
scalar_in_thirds = (scalar * 3.0).round / 3.0

thirds_difference = (scalar - scalar_in_thirds).abs
eighths_difference = (scalar - scalar_in_eighths).abs

compute_in_thirds = thirds_difference < eighths_difference

if compute_in_thirds
  less_than_eighth = false
  rounded_scalar = scalar_in_thirds
else
  less_than_eighth = false
  rounded_scalar = scalar_in_eighths
end

quotient, modulus = rounded_scalar.to_s.split '.'
quotient = quotient.to_f
modulus = ".#{modulus}".to_f

这适用于8个,但对于像 1.32 这样的数字,它会崩溃 .

对小数组件执行 modulus.numeratormodulus.denominator 将产生 600479950316066118014398509481984 之类的数字 .

有没有更好的方法来解决这个问题?

1 回答

  • 1

    这是你可以写的一种方式 .

    Code

    def closest_fraction(f,*denominators)
      n, frac = denominators.map { |n| [n, round_to_fraction(f,n)] }
                            .min_by { |_,g| (f-g).abs }
      [(n*frac).round, n, frac] 
    end
    
    def round_to_fraction(f,n)
      (f*n).round/n.to_f
    end
    

    Examples

    closest_fraction(2.33, 3, 8)
      #=> [7, 3, 2.3333333333333335]
    closest_fraction(2.12, 3, 8)
      #=> [17, 8, 2.125]
    closest_fraction(2.46, 2, 3, 5)
      #=> [5, 2, 2.5]
    closest_fraction(2.76, 2, 3, 5, 7, 11, 13, 17)
      #=> [47, 17, 2.764705882352941]
    

相关问题