문제

Ruby에서는 정수인 경우 float를 int로 변환하고 싶습니다.예를 들어

a = 1.0
b = 2.5

a.to_int_if_whole # => 1
b.to_int_if_whole # => 2.5

기본적으로 저는 소수점이 없는 숫자에 ".0"을 표시하지 않으려고 노력하고 있습니다.나는 우아한(또는 내장된) 방법을 찾고 있습니다.

def to_int_if_whole(float)
  (float % 1 == 0) ? float.to_i : float
end
도움이 되었습니까?

해결책 3

이것은 내가 원하는 방식으로 작동하는 솔루션입니다.

class Float
  alias_method(:original_to_s, :to_s) unless method_defined?(:original_to_s)

  def is_whole?
    self % 1 == 0
  end

  def to_s
    self.is_whole? ? self.to_i.to_s : self.original_to_s
  end
end

이런 식으로 업데이트 할 수 있습니다 is_whole? 논리 (나는 Tadman 's가 가장 정교한 것 같습니다) 필요한 경우, 플로트 출력이 줄 (예 : 양식)으로 출력되는 곳이 내가 원하는 방식으로 나타납니다 (예 : 끝에는 0이 없음).

당신의 아이디어에 대해 모두에게 감사합니다 - 그들은 정말 도움이되었습니다.

다른 팁

그것의 간단한 방법 중 하나는 다음과 같습니다.

class Float
  def prettify
    to_i == self ? to_i : self
  end
end

그것은 ~ 때문에:

irb> 1.0 == 1
=> true
irb> 1 == 1.0
=> true

그런 다음 할 수 있습니다 :

irb> 1.0.prettify
=> 1

irb> 1.5.prettify
=> 1.5

하나의 라이너 스프린트 ...

sprintf("%g", 5.0)
=> "5"

sprintf("%g", 5.5)
=> "5.5"

저는 루비에 대해 잘 모릅니다.

그러나 이것은 표시하다 문제.사용 중인 라이브러리에 숫자를 문자열로 변환할 때 숫자 형식을 지정하는 방법이 없다면 매우 놀랄 것입니다.

원하는 것을 정확히 수행하는 포괄적인 형식 지정 옵션이 없을 수도 있지만 부동 소수점이 정수의 부동 소수점 표현인 경우 true를 반환하고 그렇지 않으면 false를 반환하는 메서드를 설정할 수 있습니다.생성한 형식 지정 루틴 내에서(따라서 이 작업은 한 번만 수행하면 됨) 이것이 true인지 false인지에 따라 형식을 변경하면 됩니다.

이것 숫자를 표시할 때 소수점 이하 자릿수를 제어하는 ​​방법을 설명합니다.

부동 소수점 표현의 복잡성에 주의하세요.수학에서는 답이 3이라고 말할 수 있지만 3.000000000000000000001을 얻을 수도 있습니다.숫자가 거의 정수인지 확인하려면 델타를 사용하는 것이 좋습니다.

위의 게시물에 동의하는 경향이 있지만이 작업을 수행 해야하는 경우 :

(float == float.floor) ? float.to_i : float

레일을 사용하는 경우 도우미를 사용할 수 있습니다 number_to_rounded 옵션으로 strip_insignificant_zeros, 예를 들어:

ActiveSupport::NumberHelper.number_to_rounded(42.0, strip_insignificant_zeros: true)

또는 이렇게 :

42.0.to_s(:rounded, strip_insignificant_zeros: true)

교육 목적으로 제공되는 나의 끔찍한 해킹 적 구현은 다음과 같습니다.

class Float
  def to_int_if_whole(precision = 2)
    ("%.#{precision}f" % self).split(/\./).last == '0' * precision and self.to_i or self
  end
end

puts 1.0.to_int_if_whole # => 1
puts 2.5.to_int_if_whole # => 2.5
puts 1.9999999999999999999923.to_int_if_whole # => 2

Sprintf 스타일 호출을 사용하는 이유는 플로트#라운드 메소드가 경향이있는 플로트 포인트 근사치를 훨씬 더 안정적으로 처리하기 때문입니다.

나는 루비에 대해서도 많이 모른다.

그러나 C ++에서는 다음을 수행 할 것입니다.

bool IsWholeNumber( float f )
{
    const float delta = 0.0001;
    int i = (int) f;
    return (f - (float)i) < delta;
}

그리고 나는 그것을 기반으로 출력 정밀도를 포맷합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top