rubysolo/dentaku

Class Conversion

mgestoquejr opened this issue · 3 comments

When calculating two Float values and the result is a whole number, the calculator converts it to an Integer class. Is this a bug or intentional behavior?

Current behavior:

Dentaku::Calculator.new.evaluate('1.0 + 1.0')
=> 2

What we expect as behavior:

Dentaku::Calculator.new.evaluate('1.0 + 1.0')
=> 2.0

We use the calculator for multiple evaluations (dates, data comparisons). So a simple to_f on the returned value just won't work. We're having to check the entry values for #any? Float. And if the result is an Integer convert it back to Float.

@mgestoquejr
Greetings, I'm also facing your problem...!

There seems to be a problem with the argument prefer_integer.
Since it's set to true by default, we always get to_i value from arithmetical computations.

# lib/dentaku/ast/arithmetic.rb
def cast(val, prefer_integer = true)
  validate_value(val)
  numeric(val, prefer_integer)
end

def numeric(val, prefer_integer)
  v = BigDecimal(val, Float::DIG + 1)
  v = v.to_i if prefer_integer && v.frac.zero?
  v
rescue ::TypeError
  # If we got a TypeError BigDecimal or to_i failed;
  # let value through so ruby things like Time - integer work
  val
end

I try to fix this at #271, but I'm not sure that it's the best solution.
Please check it out or use it if you want 🙇‍♀️

I just pushed a commit that only performs the decimal conversion if necessary. Can you give this a try and see if it fixes the issue? (Feel free to reopen the issue if not!)

Greetings, thank you for your quick fix!

Now I got the expected behavior.

Dentaku::Calculator.new.evaluate('1.0 + 1.0')
=> 0.2e1(BigDecimal)

However, it doesn't seem to work well when I use a float variable:

Dentaku::Calculator.new.evaluate('1 + num', num: 1.0)
=> 2.0(Float)

I tried to fix it at #273