2011-12-21 4 views
8

저는 Ruby 1.8.7과 Rails 2.3.5를 사용하고 있습니다.Float에서 소수 자릿수를 계산하는 방법은 무엇입니까?

12.525와 같은 부동 소수점이있는 경우 어떻게 소수점 이하 자릿수를 얻을 수 있습니까? 이 경우 나는 '3'을 되 찾을 것으로 예상한다.

theFloat.to_s.split(".")[1].length 

그것은 아주 예쁜하지 않습니다,하지만 당신은 플로트하는 방법으로 삽입 할 수 있습니다 :이처럼

답변

9

다음은 매우 간단한 방법입니다.

def decimals(a) 
    num = 0 
    while(a != a.to_i) 
     num += 1 
     a *= 10 
    end 
    num 
end 

decimals(1.234) # -> 3 
decimals(10/3.0) # -> 16 
+1

아주 멋진 해결책! – Linuxios

+0

감사합니다. 내 애플리케이션 도우미 파일보다 더 붙어 있습니다. 필요할 때 전화하게되어 기쁘게 생각합니다. – Reno

+1

(1/3)은 어떨까요? – MrYoshiji

2

같은

class Float 
    def decimalPlaces 
     self.to_s.split(".")[1].length 
    end 
end 
+0

이 접근법은 (10/3.0)에 대해 14를 제공하지만 제 대답은 16을 제공합니다. 반복되는 소수는 문제가 될 수 있습니다. –

+0

글쎄, 그건 이상한데 ... IRB를 사용해야 겠어! – Linuxios

+0

각 접근법은 서로 다른 것에 달려 있습니다. 따라서 다른 대답은 그리 놀랄만하지 않습니다. –

17

뭔가 것 같아요 :

n = 12.525 
n.to_s.split('.').last.size 
+2

아마도 '0'을 원할 때 'n'이 정수이면 1을 반환합니다. 이것은 정수와 수레가 혼합되었을 때 나를 위태롭게했다. – Barry

+3

'num.to_s.include가 아닌 경우 0을 반환합니다. '.' – laffuste

0

당신이 바닥을 차감 한 후 바로 왼쪽 문자 수를 셀 수 :이 이에 상응하는 정수에 해당하기 전에 (10)에 의해 여러에 얼마나 많은 시간 수를 추적?

(12.525 - (12.525.floor)) to_s.length-2 => 3

편집 :. 아니 가지 이유로, 네거티브의 무리와 0.99999 문제에 대한이 나던 일이

+0

1.8에서만 작동합니다. 1.9로 시도하십시오. –

15

당신이해야 당신이 원하는 것에 매우 조심하십시오. Floating point numbers은 과학적 목적으로는 우수하며 일상적으로 사용하기 위해 주로 사용되지만, "소수점 이하 몇 자릿수"와 같은 것을 알고 싶을 때는 상당히 어둡습니다. 단지 about 16 digits total을 포함하기 때문에 정확한 데이터입니다. (또는 일부 라이브러리는 "반올림 된 숫자가 더 친숙합니다"라는 이유로 출력을 위해 숫자 서식을 지정할 때 숫자의 끝 부분으로 정확한 데이터를 버릴 수도 있습니다. 실제로 사실이지만 약간 위험 할 수 있음을 의미합니다. . 형식화 된 출력에 의존)

당신이 부동 소수점 숫자를 임의 정밀도를 제공하기 위해 BigDecimal 클래스와 표준 부동 소수점 숫자를 대체 할 수있는 경우에, 당신이 검사 할 수있는 "원시"번호 :의

> require 'bigdecimal' 
=> true 
> def digits_after_decimal_point(f) 
> sign, digits, base, exponent = f.split 
> return digits.length - exponent 
> end 
> l = %w{1.0, 1.1, 1000000000.1, 1.0000000001} 
=> ["1.0,", "1.1,", "1000000000.1,", "1.0000000001"] 
> list = l.map { |n| BigDecimal(n) } 
=> [#<BigDecimal:7f7a56aa8f70,'0.1E1',9(18)>, #<BigDecimal:7f7a56aa8ef8,'0.11E1',18(18)>, #<BigDecimal:7f7a56aa8ea8,'0.1000000000 1E10',27(27)>, #<BigDecimal:7f7a56aa8e58,'0.1000000000 1E1',27(27)>] 
> list.map { |i| digits_after_decimal_point(i) } 
=> [0, 1, 1, 10] 

물론 BigDecimal으로 이동하면 응용 프로그램이 너무 느려지거나 필요에 따라 너무 강력 해져서 코드가 복잡해 지므로 실제로 이점이 없습니다. 당신은 당신의 신청에 가장 중요한 것을 결정해야 할 것입니다.

+2

TAKE CARE : 값 0은 1 (0이어야 함)을, 값 10은 -1을 반환합니다. – reto

+0

@reto, 멋진 잡기. 감사. – sarnold

+0

이미 숫자를 문자열로 가지고 있다면 ('precision' 인수없이 BigDecimal을 초기화해야하는 경우),'n [/ \ d + $ /]. size'를 실행하는 것이 어떻습니까? –

0

정수에서는 Olexandr의 대답이 작동하지 않습니다. 다음과 같이 시도해보십시오.

관련 문제