9

我想找到lengtha 的Fixnum,num而不将其转换为String.

换句话说,在num不调用该.to_s()方法的情况下有多少位数:

num.to_s.length
4

8 回答 8

28
puts Math.log10(1234).to_i + 1 # => 4

你可以像这样将它添加到 Fixnum 中:

class Fixnum
  def num_digits
    Math.log10(self).to_i + 1
  end
end

puts 1234.num_digits # => 4
于 2012-12-22T19:04:40.423 回答
13

Ruby 2.4 有一个Integer#digits方法,它返回一个包含数字的数组。

num = 123456
num.digits
# => [6, 5, 4, 3, 2, 1] 
num.digits.count
# => 6 

编辑:

要处理负数(感谢@MatzFan),请使用绝对值。整数#abs

-123456.abs.digits
# => [6, 5, 4, 3, 2, 1]
于 2016-12-26T17:22:11.723 回答
7

Ruby 2.4+的旁注

我对不同的解决方案进行了一些基准测试,Math.log10(x).to_i + 1实际上x.to_s.length. @Wayne Conrad的评论已过时。新的解决方案digits.count远远落后,尤其是在数量更大的情况下:

with_10_digits = 2_040_240_420

print Benchmark.measure { 1_000_000.times { Math.log10(with_10_digits).to_i + 1 } }
# => 0.100000   0.000000   0.100000 (  0.109846)
print Benchmark.measure { 1_000_000.times { with_10_digits.to_s.length } }
# => 0.360000   0.000000   0.360000 (  0.362604)
print Benchmark.measure { 1_000_000.times { with_10_digits.digits.count } }
# => 0.690000   0.020000   0.710000 (  0.717554)

with_42_digits = 750_325_442_042_020_572_057_420_745_037_450_237_570_322

print Benchmark.measure { 1_000_000.times { Math.log10(with_42_digits).to_i + 1 } }
# => 0.140000   0.000000   0.140000 (  0.142757)
print Benchmark.measure { 1_000_000.times { with_42_digits.to_s.length } }
# => 1.180000   0.000000   1.180000 (  1.186603)
print Benchmark.measure { 1_000_000.times { with_42_digits.digits.count } }
# => 8.480000   0.040000   8.520000 (  8.577174)
于 2018-02-19T13:04:17.137 回答
4

尽管投票率最高的循环很好,但它不是非常 Ruby,并且对于大数字会很慢, .to_s 是一个内置函数,因此会快得多。几乎通用的内置函数将比构造的循环或迭代器快得多。

于 2016-03-23T22:03:18.153 回答
1

其他方式:

def ndigits(n)
  n=n.abs
  (1..1.0/0).each { |i| return i if (n /= 10).zero? }
end

ndigits(1234) # => 4
ndigits(0)    # => 1
ndigits(-123) # => 3
于 2014-07-08T04:01:06.140 回答
0

如果你不想使用正则表达式,你可以使用这个方法:

def self.is_number(string_to_test)
is_number = false
# use to_f to handle float value and to_i for int
string_to_compare = string_to_test.to_i.to_s
string_to_compare_handle_end = string_to_test.to_i

# string has to be the same
if(string_to_compare == string_to_test)
  is_number = true
end
# length for fixnum in ruby
size = Math.log10(string_to_compare_handle_end).to_i + 1
# size has to be the same
if(size != string_to_test.length)
  is_number = false
end
is_number
end
于 2014-05-05T15:26:12.793 回答
0

你不必花哨,你可以做这么简单。

def l(input)
  output = 1
  while input - (10**output) > 0
    output += 1
  end
  return output
end
puts l(456)
于 2019-06-28T17:32:31.140 回答
-1

它可以是找出固定数字的长度/计数/大小的解决方案。

irb(main):004:0> x = 2021
=> 2021
irb(main):005:0> puts x.to_s.length
4
=> nil
irb(main):006:0>
于 2021-11-25T12:22:20.543 回答