2010-11-22 5 views
2

Ruby가 정밀도 2로 소수를 일관성있게 렌더링하지 않는 이유는 매우 궁금합니다. 예를 들어number_to_currency 반올림 정밀도가 잘못됨

:

helper.number_to_currency 9.995 

=> "$ 9.99"

helper.number_to_currency 10.995 

동안 => "$ 11.00"...이 "$ 10.99"해야 하는가?

+1

부동 소수점 정밀 문제 일 수 있습니다. – You

답변

5

부동 소수점 오류입니다. 내 웹 사이트에서도 number_to_currency를 사용하고 있기 때문에이 문제를 해결하기위한 패치를 제출할 것입니다.

여기에 더 자세히 무슨 일이 일어나고있는 작업은 다음과 같습니다

number_to_currency 그냥 올바른 형식 수를 얻을 수 number_with_precision를 호출 끝납니다. number_with_precision은 즉시 숫자를 Float로 변환합니다. 본질적으로 레일즈 코드에서이 줄로 넘어갑니다 :

# File actionpack/lib/action_view/helpers/number_helper.rb, line 280 
rounded_number = BigDecimal.new((number * (10 ** precision)).to_s).round.to_f/10 ** precision 

제공된 숫자는 BigDecimal로 변환되기 전에 100을 곱합니다. 이 간단한 IRB 세션 봐 :

irb(main):001:0> 9.995 * 100 
=> 999.4999999999999 

그 숫자는 분명히 다음은 당신이 9.99에게 제공하기 위해 100으로 나눈 것, 999 내림 것입니다.

내가 잠시 생각할 수있는 유일한 해결 방법은 번호를 전달하기 전에 사용자가 반올림을 수행하는 것입니다.

+0

여기에서 볼 수있는 패치를 제출했습니다 : https://rails.lighthouseapp.com/projects/8994/tickets/6182-another-rounding-problem-in-number_with_precision – dontangg

-2

'반쪽에서 홀수로'규칙을 사용하는 것처럼 보입니다.

따라서 "1.5"는 가장 가까운 홀수 (1)로 반올림되고 2.5는 가장 가까운 홀수 (3)로 반올림됩니다.

반올림되는 숫자의 임의로 분산 된 집합에 대해이 형태의 반올림은 반올림되지 않은 숫자의 합과 반올림 된 숫자의 합 사이에 가장 작은 차이를 발생시킵니다.