문제점
당신이 정수 (일명 정수 나누기)에 의해 정수를 나눌 때, 루비 등 대부분의 프로그래밍 언어는, 가정 당신은 당신의 결과를 Integer로 원한다. 숫자의 낮은 수준 표현에서는 정수가 소수점 이하의 숫자와 매우 다르기 때문에 정수가있는 부분은 보다 빠르기 때문에 대부분 역사에 기인합니다. 그래서 비율, 0과 1 사이의 숫자는 그 진수가 잘립니다있다, 그래서 100을 곱한 때 0 또는 1을, 0 또는 100
일반적인 솔루션
을하게되고 만약의 나누기의 숫자가 정수가 아닌 경우 정수 나누기가 수행되지 않습니다. 대안은 소수점이있는 숫자입니다. 이런 종류의 숫자 유형이 있지만 일반적으로 부동 소수점 수라고하며 루비에서는 가장 일반적인 부동 소수점 수는 Float 클래스입니다. 레일 '모델에서
1.0.class.ancestors
# => [Float, Precision, Numeric, Comparable, Object, Kernel]
1.class.ancestors
# => [Fixnum, Integer, Precision, Numeric, Comparable, Object, Kernel]
는 수레는 루비의 BigDecimal 클래스 루비 Float 클래스 및 십진수로 표시됩니다. 차이점은 BigDecimals가 훨씬 정확하다는 것입니다 (즉, 돈을 위해 사용될 수 있음).
일반적으로 숫자를 실수로 "typecaste"할 수 있습니다. 즉, 더 이상 정수 나누기를 수행하지 않습니다. 그런 다음 필요할 경우 계산 후 다시 정수로 변환 할 수 있습니다.
x = 20 # => 20
y = 30 # => 30
y.to_f # => 30.0
x.class # => Fixnum
y.class # => Fixnum
y.to_f.class # => Float
20/30 # => 0
20/30.0 # => 0.666666666666667
x/y # => 0
x/y.to_f # => 0.666666666666667
(x/y.to_f).round # => 1
솔루션을 당신은 당신의 경우
, 당신이 분할 전에 100에 의해 번식하는 것이 작업을 수행하는 가장 쉬운 방법을 생각하면 (즉, 42 42 %)을 정수 결과를하고자하는 가정. 이것은 소수점을 오른쪽으로 멀리 밀어내어 부서 앞에 올리면 숫자가 정확할만큼 정확하다는 것을 의미합니다.
before_save :update_percentages
def update_percentages
total = likes + dislikes
self.likes_percent = 100 * likes/total
self.dislikes_percent = 100 * dislikes/total
end
주 :
- 난 당신은 로컬 변수를 만드는 것을 명확하게하는 임무를해야하고, 로컬 변수가 때 오히려 메소드를 호출 할 것을 명확하게 암시 적
self
을 제거 변수를 참조하는 것보다
- egarcia에서 제안한대로 저장하기 전에 콜백으로 이동했습니다. (내가 before_ 을 저장하고을 저장했는데 이유는 모르겠지만 업데이트에서이 백분율을 계산해야하는 이유는 모르지만 창조하다 먹었고, 숫자가 정확하다는 것을 확인한 후에 일어날 것 같아요. 즉, 범위 내에서, 정수 또는 소수점 이하에서
- 저장하기 전에 완료되었으므로 코드에서 save 호출을 제거하고, 이미 일어날 것입니다.
- 콜백에 명시 적으로 저장하지 않기 때문에 무한 루프가 발생하지 않으므로 숫자가 업데이트되었는지 확인할 필요가 없습니다. 저장할 때마다 백분율을 계산합니다.
고마워요, 그 말이 낫습니다. –