Круглий поплавок в Рубі


150

У мене проблеми з округленням. У мене є поплавок, який я хочу округлити до сотої частини десяткової. Однак я можу тільки користуватися.round що в основному перетворює його на інту, тобто 2.34.round # => 2. чи є простий спосіб зробити щось подібне2.3465 # => 2.35

Відповіді:


181

Під час відображення можна використовувати (наприклад)

>> '%.2f' % 2.3465
=> "2.35"

Якщо ви хочете зберегти його округлим, ви можете використовувати

>> (2.3465*100).round / 100.0
=> 2.35

2
Дякую. Я не знав, що спринт буде піклуватися про округлення для мене. sprintf '%.2f', 2.3465також працює.
Ной Суссман

66
value.round (2) краще, ніж це рішення
Kit Ho

12
Майте на увазі, що 2.3000.round(2) => 2.3і sprintf '%.2f', 2.300 => 2.30. На мою думку, це недолік у турі (), або він повинен мати можливість збереження задніх нулів.
Екскалібур

14
@Excalibur 2.3000.round(2)- це число, а не рядок. Ні в якому разі не число 2.3відрізняється від числа 2.30, тому немає можливості зберегти проміжні нулі. Ви можете створити власний клас значень значень_з_значення, але тоді у нас вже є рядки.
Roobie Nuby

6
Зверніть увагу , що , хоча це робить роботу для двох знаків після коми, є помилка в '%.3f' % 1.2345(3 знаки після коми, а НЕ 2), однак !! Те ж саме sprintf. Остерігайся. Це повернеться => 1.234 не так, => 1.235 як очікували більшість (через 2-й десятковий, sprintf раунди 5 вниз і тільки раунди 6 вверх). Ось чому коментар Кіт Хо має вище 25 відгуків. Більш безпечно у використанні, '%.3f' % 1.2345.round(3)тому число .roundспочатку правильно закруглюється , а потім відформатовується (якщо потрібно, з нульовими нулями).
лікетський

392

Передайте аргумент до раунду, що містить кількість десяткових знаків, які слід округлити

>> 2.3465.round
=> 2
>> 2.3465.round(2)
=> 2.35
>> 2.3465.round(3)
=> 2.347

8
Це здавалося б більш розумним, ніж множення, округлення та ділення. +1
Марк Embling

3
Хм, цей метод, здається, не знаходиться в рубіні 1.8.7. Може, в 1.9?
Брайан Армстронг

2
@Brian. Це, безумовно, в 1.9 і також знаходиться в рейках (На якому це питання було позначено)
Стів Вет

3
Метод раунда Ruby 1.8.7 не має такої можливості, додавання параметра округлення десяткового місця є здатністю 1,9
bobmagoo

1
Зауважте, що ви не отримуєте заздалегідь нулі з цим, тому 1.1.round(2)=> 1.1ні1.10
NotAnAmbiTurner

9

Ви можете використовувати це для округлення до точності.

//to_f is for float

salary= 2921.9121
puts salary.to_f.round(2) // to 2 decimal place                   

puts salary.to_f.round() // to 3 decimal place          

7

Ви можете додати метод у Float Class, я дізнався це з stackoverflow:

class Float
    def precision(p)
        # Make sure the precision level is actually an integer and > 0
        raise ArgumentError, "#{p} is an invalid precision level. Valid ranges are integers > 0." unless p.class == Fixnum or p < 0
        # Special case for 0 precision so it returns a Fixnum and thus doesn't have a trailing .0
        return self.round if p == 0
        # Standard case  
        return (self * 10**p).round.to_f / 10**p
    end
end

3

Ви також можете надати від'ємне число як аргумент roundметоду для округлення до найближчого кратного 10, 100 тощо.

# Round to the nearest multiple of 10. 
12.3453.round(-1)       # Output: 10

# Round to the nearest multiple of 100. 
124.3453.round(-2)      # Output: 100



1

Якщо вам просто потрібно його відобразити, я б скористався помічником number_with_precision . Якщо вам це потрібно десь іншому, я б застосував, як вказував Стів Вет, roundметод


1
Зауважте, що number_with_precisionце лише метод Rails.
Смар

0

Для рубіну 1.8.7 ви можете додати у свій код:

class Float
    alias oldround:round
    def round(precision = nil)
        if precision.nil?
            return self
        else
            return ((self * 10**precision).oldround.to_f) / (10**precision)
        end 
    end 
end
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.