-1

Below is the small segment of code from my script:

The logic added is to covert any data value as per the scale value

x = "11400000206633458812"    
scale = 2    
x = x.to_f/10**scale.to_i    
x = x == x.to_i ? x.to_i : x    
puts x

observe that the value comes out to be "114000002066334592"

which is different from the initial value of x.

My test-points are failing at this point.

x can be any value. If i use x = 156, the output is correct, but when the length of the integer exceeds 16 digits then the problem arises.

The expected output in above case is 114000002066334588

Can anybody help me why the value is changing and how to fix it?

mu is too short
  • 426,620
  • 70
  • 833
  • 800
s c
  • 71
  • 1
  • 11
  • @AndreyDeineko, x is actually a string.. If i use x.to_d, it gives me error: undefined method `to_d' for "11400000206633458812":String (NoMethodError) – s c Feb 10 '17 at 07:09
  • 1
    _"large integers change their value"_ – `x.to_f` does not return an integer. – Stefan Feb 10 '17 at 08:36

1 Answers1

0

The expected output in above case is 114000002066334588

Not at all.

One can not expect floating point operations to be precise. That is just not the case because of processor architecture. In all languages, with no exceptions, there are workarounds to work with decimals precisely. In ruby it’s BigDecimal:

require 'bigdecimal'

BigDecimal("11400000206633458812") / 100
#⇒ 0.11400000206633458812E18

(BigDecimal("11400000206633458812") / 100).to_i
#⇒ 114000002066334588
Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160