Open DinisCruz opened 8 years ago
here is a possible solution: to_Decimal
extension method
it 'testing extension method solution', ->
Number::to_Decimal = -> Number.parseFloat(@.toFixed(4)) # extension method that adds a new .to_Decimal to the Number class
c = a + b # addition that will cause the prob
c.assert_Is 0.6000000000000001 # confirming the problem
c.to_Decimal().assert_Is 0.6 # confirming that .to_Decimal() works as expected
c.to_Decimal().assert_Is 0.60
c.to_Decimal().assert_Is 0.6000000
(typeof c.to_Decimal() ).assert_Is 'number' # check the value type name
(typeof c.to_Decimal().to_Decimal()).assert_Is 'number' # make sure there are no side effects with multiple transformations
c.to_Decimal().to_Decimal().assert_Is 0.6
d = c.to_Decimal()
(d + 0.3) .assert_Is 0.8999999999999999 # confirm that we have the same prob if we do another addition
(d + 0.3).to_Decimal().assert_Is 0.9 # confirm we can use .to_Decimal to fix it
Here is the before,during and after of applying the solution (using the .to_Number()
extension method)
before
during (when the tests failed)
after (when the tests have been fixed and are now regression tests)
For reference this fix was going from
calculate = (activity, prefix)->
initial_Value = 0.2
yes_Value = 0.4
score = initial_Value
for key,value of result.activities[activity] when key.contains(prefix)
if value is 'Yes'
score += yes_Value
to
calculate = (activity, prefix)->
initial_Value = 0.2
yes_Value = 0.4
score = initial_Value
for key,value of result.activities[activity] when key.contains(prefix)
if value is 'Yes'
score = (score + yes_Value).to_Decimal()
i.e. from
score += yes_Value
to
score = (score + yes_Value).to_Decimal()
which is a pretty nice solution
and leave a story behind
https://twitter.com/DinisCruz/status/745283929142398976
code