Конвертация строк в числа в Ruby
При чтении данных из файла или другого внешнего ресурса данные всегда приходят в Ruby как объекты String (Строка).
Если мы хотим использовать их как числа, сначала их нужно сконвертировать в числа.
Но в какие и как?
Объект String в Ruby имеет несколько методов конверации в число.
- to_i сконвертирует String в Integer.
- to_f сконвертирует String во Float (с плавающей точкой)
- to_r сконвертирует String в Rational number (рациональное число).
- to_c сконвертирует String в Complex number (комплексное число).
Конкатенация
Если для двух числовых значений, которые на самом деле объекты String (из-за обрамляющих кавычек), использовать оператор +, то он будет работать как конкатенация.
a = "2" b = "3" puts a+b # 23
no implicit conversion of Fixnum into String (TypeError)
Если одно из значений это объект String, а другое - число (без кавычек), и мы попробуем сложить их друг с другом, как в примере:
puts "2"+3
мы получим исключение: no implicit conversion of Fixnum into String (TypeError)
String, которые выглядят как integer
String, содержащие целое число (integer) могут быть сконвертированы в Integer, Float, Rational number, или Complex number:
puts a.to_i # 2 puts a.to_f # 2.0 puts a.to_r # 2/1 puts a.to_c # 2+0i
Как задать основание: конвертация двоичных, восьмеричных, шестнадцатеричных значений в десятичные
По умолчанию to_i предполагает, что наш объект String представлен в десятичной системе (основание 10), но что если вы хотите это изменить?
Что если вы хотите рассматривать String как двоичное число, восьмеричное или шестнадцатеричное? Тогда нужно просто передать аргумент base= с подходящим числом в метод to_i:
puts "11".to_i # 11 puts "11".to_i(base=2) # 3 puts "11".to_i(base=16) # 17
Конечно шестнадцатеричные числа могут также содержать символы a-f. Функция to_i умеет с ними обращаться.
puts "aB".to_i(base=16) # 171
Возникает вопрос, что случится, если мы используем to_i без указания основания для строки с шестнадцатеричным числом, или с основанием, которое не предусматривает таких символов? Тогда просто вернется 0 (без какой-либо ошибки).
puts "aB".to_i # 0 puts "9".to_i(base=8) # 0
Это подводит нас к вопросу: Что случится, если не все символы могут быть сконвертированы в число? Ответ прост. to_i сконвертирует все 'digits' от начала до того места, где уже не будет понятно, что делать. Оставшаяся часть строки будет отброшена. Даже если там есть еще понимаемые значения.
puts "2x3".to_i # 2 puts "2 3".to_i # 2
Конвертация в число с плавающей точкой или рациональное число
Мы можем использовать остальные методы для конвертации во Floating point (число с плавающей точкой), Rational number (рациональное число), и даже в Complex number (комплексное число): Некоторые из них понимают точку в десятичной дроби в String
c = "14.6" puts c.to_i # 14 puts c.to_f # 14.6 puts c.to_r # 73/5 puts c.to_c # 14.6+0i
Некоторые даже понимают символ e, обозначающий экспоненту в String:
e = "2.3e4x5" puts e # 2.3e4x5 puts e.to_i # 2 puts e.to_f # 23000.0 puts e.to_r # 23000/1 puts e.to_c # 23000.0+0i
Полный пример
examples/ruby/string_to_number.rb
a = "2" b = "3" puts a+b # 23 puts '-------' # puts "2"+3 # no implicit conversion of Fixnum into String (TypeError) puts a.to_i # 2 puts a.to_f # 2.0 puts a.to_r # 2/1 puts a.to_c # 2+0i puts '-------' puts "11".to_i # 11 puts "11".to_i(base=2) # 3 puts "11".to_i(base=8) # 9 puts "11".to_i(base=16) # 17 puts '-------' puts "aB".to_i(base=16) # 171 puts "aB".to_i # 0 puts "9".to_i(base=8) # 0 puts '-------' puts "2x3".to_i # 2 puts "2 3".to_i # 2 puts '-------' c = "14.6" puts c.to_i # 14 puts c.to_f # 14.6 puts c.to_r # 73/5 puts c.to_c # 14.6+0i puts '-------' e = "2.3e4x5" puts e # 2.3e4x5 puts e.to_i # 2 puts e.to_f # 23000.0 puts e.to_r # 23000/1 puts e.to_c # 23000.0+0i puts '-------'
Published on 2016-03-27