34

I am trying to get a fraction part of a decimal number in rails. For example I have a number, that "1.23" and I want to get "23" It is may be too easy but, does anyone have any idea about how can I do?

lacrosse
  • 54
  • 6
yagmurdursun
  • 933
  • 1
  • 9
  • 21

9 Answers9

65

Try to use modulo method:

1.23.modulo(1) => 0.23

Read more here: http://www.ruby-doc.org/core-1.9.3/Numeric.html#method-i-modulo

Or you can convert float to integer and substract it from original float value.

1.23 - 1.23.to_i => 0.23
Eugene Dorian
  • 907
  • 1
  • 5
  • 5
11

I am not sure if it is the easiest way to do it - but you can simply split the number using "." character - like this:

number = 1.23
parts = number.to_s.split(".")
result = parts.count > 1 ? parts[1].to_s : 0
EfratBlaier
  • 559
  • 2
  • 6
  • 8
    Future readers, please don't use this approach. It may work in a simplistic case, but will trip in any locale-aware scenario. Although not very error-prone in Ruby which hardcodes `.` as the floating point delimiter, it would promote the bad habit to be used with other, less forgiving languages. Please use math functions for math operations, see answers below. – Nic Nilov May 23 '16 at 18:16
10
n = 1.23

n.modulo(1)
=> 0.22999999999999998

n - n.to_i
=> 0.22999999999999998

Recommended read http://floating-point-gui.de/

Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
Jonas Elfström
  • 30,834
  • 6
  • 70
  • 106
6

if you know your desired precision, this might be a tad faster to to_s solution.

1.1234.modulo(1).round(4) #0.1234
bioffe
  • 6,283
  • 3
  • 50
  • 65
6

Deciding on the proper solution requires understanding the type that you're working with. If your values are Float (the standard type for non-whole numbers in Ruby) then logically correct answers like mod(1) may produce unexpected results due to floating point errors. For any case where Float is the proper data type to be using in the first place, this is likely acceptable.

If floating point errors are not acceptable, don't use Float! Ruby comes with the great BigDecimal class which is much more accurate at the cost of performance and a slightly more verbose syntax.

decimal = BigDecimal.new("1.23")
decimal.frac #=> 0.23
Community
  • 1
  • 1
bloudermilk
  • 17,820
  • 15
  • 68
  • 98
2

..."1.23" and I want to get "23".

Just remove the integer part and multiply per 100.

((number - number.to_i) * 100).to_i
  • 2
    This introduces imprecision, so I would not recommend this approach. Example: (37319.70 - 37319.70.to_i) * 100 = 69.99999999970896 – zephos2014 May 14 '19 at 16:46
1
 a=1.23 #value of a will be 1.23
 a=a-a.to_i #value of a will be 0.23
dsk
  • 615
  • 1
  • 7
  • 19
1

There are various ways we can achieve the output modulo is one of them

1.23.modulo(1) => 0.22999999999999998

you can round the result as per your convenience

but to achieve what you have asked in your question

I will follow a very simple approach

value = 1.23.to_s.split('.') -> ["1", "23"]
value.last.to_i -> "23"
Sudhir Vishwakarma
  • 785
  • 10
  • 15
0

After trying everything... I feel the best answer is (num - num.to_i).abs because it also works for negative numbers.

e.g.

(1.23 - 1.23.to_i).abs = 0.23

(-1.23 - -1.23.to_i).abs = 0.23

slindsey3000
  • 4,053
  • 5
  • 36
  • 56
  • 2
    This will give you imprecision. Bad approach. Example: (37319.70-37319.70.to_i).abs => 0.6999999999970896 – zephos2014 May 14 '19 at 16:47