代码之家  ›  专栏  ›  技术社区  ›  Adrian Rotama

将十进制四舍五入到最接近的十次方的轨道

  •  1
  • Adrian Rotama  · 技术社区  · 7 年前

    我正在寻找一个rails函数,它可以将数字返回到最接近的十次方(101001000),并且还需要支持介于0和1之间的数字(0.1、0.01、0.001):

    round(9) = 10  
    round(19) = 10  
    round(79) = 100  
    round(812.12) = 1000  
    
    round(0.0321) = 0.01  
    round(0.0921) = 0.1
    

    我一直在关注: Round number down to nearest power of ten
    使用字符串长度的可接受答案,该长度不能应用于0到1之间的数字。

    已更新 Round up to nearest power of 10 这个看起来很棒。但我仍然无法让它在rails中工作。

    5 回复  |  直到 7 年前
        1
  •  2
  •   Ravi Teja Dandu    7 年前

    我不确定是否有任何函数会自动将数字四舍五入到最接近的十次方。您可以通过运行以下代码来实现:

    def rounded_to_nearest_power_of_ten(value)
        abs_value = value.abs
        power_of_ten = Math.log10(abs_value)
        upper_limit = power_of_ten.ceil
        lower_limit = power_of_ten.floor
        nearest_value = (10**upper_limit - abs_value).abs > (10**lower_limit - abs_value).abs ? 10**lower_limit : 10**upper_limit
        value > 0 ? nearest_value : -1*nearest_value
    end
    

    希望这有帮助。

        2
  •  1
  •   Maciej Nędza    7 年前

    让我们将您的问题简化为以下形式-让输入数字在范围内 [0.1, 1) ,那么这些数字的四舍五入情况如何?

    答案很简单——对于小于 0.5 我们将返回数字0.1,对于较大的数字,它将是 1.0

    我们所要做的就是确保我们的数字在这个范围内。我们将“移动”十进制分隔符,并记住在第二个变量中移动了多少次。此操作称为 normalization

    def normalize(fraction)
        exponent = 0
    
        while fraction < (1.0/10.0)
            fraction *= 10.0
            exponent -= 1
        end
    
        while fraction >= 1.0
            fraction /= 10.0
            exponent += 1
        end
    
        [fraction, exponent]
    end
    

    使用上述代码,您可以将任何浮点数表示为一对以10为基数的归一化分数和指数。要重新创建原始数字,我们将使用公式将小数点向相反方向移动

    原始=归一化*基^{指数}

    通过规范化数据属性,我们可以在简单的舍入方法中使用它,如下所示:

    def round(number)
        fraction, exponent = normalize(number)
    
        if fraction < 0.5
            0.1 * 10 ** exponent
        else
            1.0 * 10 ** exponent
        end
    end
    
        3
  •  1
  •   Буянбат Чойжилсүрэн    7 年前

    如果编号为>=1.0,这应该可以。

    10 ** (num.floor.to_s.size - ( num.floor.to_s[0].to_i > 4 ? 0 : 1))
    
        4
  •  1
  •   Буянбат Чойжилсүрэн    7 年前

    尝试以下操作:

    def round_tenth(a)
        if a.to_f >= 1
          return 10 ** (a.floor.to_s.size - ( a.floor.to_s[0].to_i > 4 ? 0 : 1))
        end
        #a = 0.0392
        c = a.to_s[2..a.to_s.length] 
        b = 0
        c.split('').each_with_index do |s, i|
          if s.to_i != 0
            b = i + 1
            break
          end
        end
        arr = Array.new(100, 0)
        if c[b-1].to_i > 4 
          b -= 1
          if b == 0
            return 1
          end
        end
        arr[b-1] = 1
        return ("0." + arr.join()).to_f
      end
    
        5
  •  0
  •   needprayfornotaxes    7 年前
    class Numeric
      def name
        def helper x, y, z
          num = self.abs
          r = 1
          while true
            result = nil
            if num.between?(x, y)
              if num >= y/2.0 
                result = y.round(r+1) 
              else
                result = x.round(r)
              end
              return self.negative? ? -result : result
            end
            x *= z; y *= z; r += 1
          end
        end
    
        if self.abs < 1
          helper 0.1, 1, 0.1
        else 
          helper 1, 10, 10
        end
      end
    end
    

    实例

    -0.049.name # => -0.01
    12.name # => 10
    

    等等,欢迎你!