Ruby가 정밀도 2로 소수를 일관성있게 렌더링하지 않는 이유는 매우 궁금합니다. 예를 들어number_to_currency 반올림 정밀도가 잘못됨
:
helper.number_to_currency 9.995
=> "$ 9.99"
helper.number_to_currency 10.995
동안 => "$ 11.00"...이 "$ 10.99"해야 하는가?
Ruby가 정밀도 2로 소수를 일관성있게 렌더링하지 않는 이유는 매우 궁금합니다. 예를 들어number_to_currency 반올림 정밀도가 잘못됨
:
helper.number_to_currency 9.995
=> "$ 9.99"
helper.number_to_currency 10.995
동안 => "$ 11.00"...이 "$ 10.99"해야 하는가?
부동 소수점 오류입니다. 내 웹 사이트에서도 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 내림 것입니다.
내가 잠시 생각할 수있는 유일한 해결 방법은 번호를 전달하기 전에 사용자가 반올림을 수행하는 것입니다.
여기에서 볼 수있는 패치를 제출했습니다 : https://rails.lighthouseapp.com/projects/8994/tickets/6182-another-rounding-problem-in-number_with_precision – dontangg
'반쪽에서 홀수로'규칙을 사용하는 것처럼 보입니다.
따라서 "1.5"는 가장 가까운 홀수 (1)로 반올림되고 2.5는 가장 가까운 홀수 (3)로 반올림됩니다.
반올림되는 숫자의 임의로 분산 된 집합에 대해이 형태의 반올림은 반올림되지 않은 숫자의 합과 반올림 된 숫자의 합 사이에 가장 작은 차이를 발생시킵니다.
부동 소수점 정밀 문제 일 수 있습니다. – You