AnApprentice
AnApprentice

Reputation: 110960

How can I set a variable to divide and round up to 0 decimal places?

In Ruby, how can I do:

number_total = records / per_page

where per_page = 100, and records = 1050, and then round up so there are no decimals? So, instead of 10.5 it equals 11?

Upvotes: 20

Views: 12317

Answers (5)

Denai
Denai

Reputation: 21

number_total = records.fdiv(per_page).ceil

# https://apidock.com/ruby/Integer/fdiv
# fdiv(p1) public
# Returns the floating point result of dividing int by numeric.
#
# https://apidock.com/ruby/Float/ceil
# ceil(*args) public
# Returns the smallest number greater than or equal to float with a precision of ndigits decimal digits (default: 0).

Upvotes: 0

VinnyQ77
VinnyQ77

Reputation: 435

If you don't wish to use the float conversion, use % (modula) for the remainder items (which is how we would actually determine # pages when thinking about it logically).

number_total = (records / per_page) + ((records % per_page).positive? ? 1 : 0)

# (records / per_page) gets all full pages
# (records % per_page) get remainder of records after integer div
# + 1 only if remainder is positive

Upvotes: 0

Khalil Fazal
Khalil Fazal

Reputation: 41

@lulala Another root of all evil: cherry-picking results.

Run your benchmark multiple times. I get the following:

       user     system      total        real
   0.120000   0.000000   0.120000 (  0.119281)
   0.120000   0.000000   0.120000 (  0.123431)

Which is a tie.

       user     system      total        real
   0.110000   0.000000   0.110000 (  0.118602)
   0.130000   0.000000   0.130000 (  0.127195)

Which suggests that float_op is faster.

       user     system      total        real
   0.150000   0.000000   0.150000 (  0.151104)
   0.120000   0.000000   0.120000 (  0.123836)

Which suggests that integer_op us faster.

Upvotes: 1

lulalala
lulalala

Reputation: 17981

Here comes root of all evil: a prematurely optimized method:

class Integer
  # returns quotient's ceiling integer
  def div_ceil(divisor)
    q = self / divisor
    if self % divisor > 0
      return q + 1
    else
      return q
    end
  end
end

The following benchmark code:

require 'benchmark'

$a = 1050
$b = 100

def float_op
  ( $a / $b.to_f ).ceil
end

def integer_op
  q = $a / $b
  if $a % $b > 0
    return q + 1
  else
    return q
  end
end

n = 1000000
Benchmark.bm do |x|
  x.report { n.times do; float_op; end }
  x.report { n.times do; integer_op; end }
end

Gives me this result

       user     system      total        real
   0.160000   0.000000   0.160000 (  0.157589)
   0.130000   0.000000   0.130000 (  0.133821)

Upvotes: 0

sawa
sawa

Reputation: 168091

Edited following a comment

number_total = (records / per_page.to_f).ceil

Upvotes: 36

Related Questions