0

I have to evaluate strings to get a result. For example,

eval('5*6.45').to_f # => 32.25

is expected.

Why do I get:

eval('7/14').to_f # => 0.0

instead of 0.5? How can I get the appropriate value? In my game (GUI), I should have 14 and not 14.0.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • Because you're converting the result to a float *after* performing integer division. You'll need to parse the user input properly to get the answer you want, not just `eval` it. – jonrsharpe Sep 04 '18 at 07:14
  • Why do you think you should get 0.5? – sawa Sep 04 '18 at 07:20
  • @sawa: because common sense :) GUI calculators do this, for example. – Sergio Tulentsev Sep 04 '18 at 07:24
  • @SergioTulentsev Ruby is not a GUI calculator. – sawa Sep 04 '18 at 07:25
  • But I'm making the game that acts like GUI calculator... I've to make Ruby work like GUI calculator otherwise the player will lose the game –  Sep 04 '18 at 07:39
  • Are you aware of floating point issues? For example, `19.9 * 100` returns `1989.9999999999998` whereas you probably want `1990`. – Stefan Sep 04 '18 at 07:59
  • BTW, why do you have to _evaluate_ `7/14` in the first place? Does the player enter `7/14` and your game has to solve it? – Stefan Sep 04 '18 at 08:01
  • Possible duplicate of [Why is division in Ruby returning an integer instead of decimal value?](https://stackoverflow.com/questions/5502761/why-is-division-in-ruby-returning-an-integer-instead-of-decimal-value) – Jagdeep Singh Sep 04 '18 at 08:45

2 Answers2

4
eval('7/14')

is the same as

7/14

which is 0 (integer division). Converting 0 to float results in zero as a float, i.e. 0.0

If you would write (i.e.)

7.0/14

, you would get the desired result.

user1934428
  • 19,864
  • 7
  • 42
  • 87
  • Yes, I found that out. But is there any way I can do 7/14 and get 0.5? Somehow? I'm making a game using Ruby2D (similar game to Lumosity's Raindrop) that requires the operation. –  Sep 04 '18 at 07:29
  • 1
    @S.Goswami if all else fails, you can always write a custom parser/evaluator. Although that's quite a bit of work. – Sergio Tulentsev Sep 04 '18 at 07:35
  • Yes, that's quite a bit of work. See if I can work with what Ruby has inbuilt! –  Sep 04 '18 at 07:40
  • You can do `7/14r`, which is not really `0.5`, but equivalent to it... `eval("7/14" + "r").to_f` is `0.5` – Amadan Sep 04 '18 at 09:13
  • 1
    @S.Goswami : Well, you will have to parse the user's input somehow anyway, otherwise someone will enter just for fun a string for evaluation which will cause to erase under your home directory. So, if you take the user's string apart to check for harmful parts, you will get the numbers entered, and if one of them is not an integer, you can replace it by a corresponding float. Of course another question is whether to do all calculations in float, because this may lead to unprecise results. – user1934428 Sep 04 '18 at 12:48
0

It is because (the absolute value of) 7 is smaller than (the absolute values of) 14. That gives 0. Then, 0 converted to float is 0.0.

sawa
  • 165,429
  • 45
  • 277
  • 381
  • 1
    Your second sentence does not follow from the first. :) The actual answer is: "because integer division" – Sergio Tulentsev Sep 04 '18 at 07:21
  • My second sentence is the second step executed after the first step expressed in the first sentence. – sawa Sep 04 '18 at 07:21
  • There's a missing bit, which is actually asked in the question: "WHY does that equal 0"? – Sergio Tulentsev Sep 04 '18 at 07:23
  • @SergioTulentsev "because integer division" is something that should not need to be mentioned since that is what `/` means. If the OP is using `/` without knowing what it means, then that is something OP should not have done. – sawa Sep 04 '18 at 07:30
  • 2
    That what it means in _ruby_. It means something else in other langs. I'd allow a bit of surprise if OP is coming from, say, JS. – Sergio Tulentsev Sep 04 '18 at 07:32
  • Of course. We are talking about Ruby, not about some other language. – sawa Sep 04 '18 at 07:33
  • If I open python 3.6, and type eval('7/14') it returns 0.5 That's not the case in Ruby, that's great... –  Sep 04 '18 at 07:44
  • 1
    _"integer division [...] that is what / means"_ / _"what it means in ruby"_ – even in Ruby `/` only means integer division if _both_ operands are integers. The OP apparently has to deal with both, integers and decimal numbers. – Stefan Sep 04 '18 at 10:21
  • @Stefan: indeed, even in ruby it doesn't mean that most of the time :) – Sergio Tulentsev Sep 04 '18 at 11:59
  • The game is like dropping water bubbles with an word inside. It will show random maths. inside the bubble. If the user type the appropriate value of the shown text inside the bubble, the answer is correct, and some other things happen. But, instead of sticking with eval, I have done something different to the custom class that generates the random maths. Now the program is much bug free, and works nice. If you want to see the program, I uploaded it on FB... https://www.facebook.com/Noughtnaught0/videos/489295834877941/ –  Sep 05 '18 at 09:38