28

I'm new to Ruby and I'm trying to figure out how ceil and floor works as I get different answers when a fraction or a decimal number is used (similar value). Below is what I have tried:

puts 8/3.ceil == 2   #=> true
puts 8/3.floor == 2  #=> true
puts 2.67.ceil == 2  #=> false
puts 2.67.floor == 2 #=> true

From my understanding, ceil should return a number higher and floor is a number lower. Hope someone can enlighten me on this. Thank you! :)

Andrey Deineko
  • 47,502
  • 10
  • 90
  • 121
misokuan
  • 283
  • 1
  • 3
  • 6

1 Answers1

44

Everything is returned correctly.

puts 8/3.ceil == 2
#=> true, because 8/3 returns an Integer, 2
puts 8/3.floor == 2
#=> true, because 8/3 returns an Integer, 2
puts 2.67.ceil == 2
#=> false, because 2.67.ceil is 3
puts 2.67.floor == 2
#=> true, because 2.67.floor is 2

To make things of more sense here, you can convert results to Float:

(8.to_f / 3).ceil == 2  #=> false
(8.to_f / 3).floor == 2 #=> true
2.67.ceil == 2          #=> false
2.67.floor == 2         #=> true

Another thing to bear in mind, that having written 8/3.ceil is actually 8 / (3.ceil), because the . binds stronger than /. (thx @tadman)

Yet another thing to mention, is that (thx @Stefan):

There's also fdiv to perform floating point division, i.e. 8.fdiv(3).ceil. And Ruby also comes with a nice Rational class: (8/3r).ceil.

Andrey Deineko
  • 47,502
  • 10
  • 90
  • 121
  • 4
    Also worth mentioning `8/3.floor` is actually `8/(3.floor)` since the `.` binds stronger than `/`. – tadman Oct 11 '16 at 07:05
  • Ahh alright! So for the first line, it's actually doing 3.ceil first, resulting in 3, and then an integer division of 8/3, which is why it's 2 (true) instead of 3 (false) like the 3rd line. Correct me if I'm wrong :) – misokuan Oct 11 '16 at 07:13
  • @misokuan `it's actually doing 3.ceil first, resulting in 3, and then an integer division of 8/3, which is why it's 2` yes, that's correct. – Andrey Deineko Oct 11 '16 at 07:15
  • 1
    There's also [`fdiv`](http://ruby-doc.org/core-2.3.1/Fixnum.html#method-i-fdiv) to perform floating point division, i.e. `8.fdiv(3).ceil`. And Ruby also comes with a nice [`Rational`](https://ruby-doc.org/core/Rational.html) class: `(8/3r).ceil` – Stefan Oct 11 '16 at 07:20
  • https://www.techotopia.com/index.php/Ruby_Operator_Precedence Precedence rules always tell the tale of mysterious calculations. :) – JeffK Nov 27 '18 at 12:48