복붙노트

[RUBY-ON-RAILS] 액티브의 진수 대 플로트

RUBY-ON-RAILS

액티브의 진수 대 플로트

때때로, 액티브 데이터 유형은 나를 혼란스럽게. ERR, 자주. 나의 영원한 질문 중 하나는 주어진 경우에,이다,

: 소수점 대 : 나는 종종, 액티브 링크 건너 한 플로트?하지만 대답은 내가 확신 할 매우 분명 충분하지 않습니다 :

여기에 몇 가지 예제의 경우는 다음과 같습니다

과거에 소수점을,하지만 난 BigDecimal를가 플로트에 비해 불필요하게 어색 루비 객체를 다루는 발견 : 내가 사용하고 있습니다. 나는 또한 사용할 수 있습니다 알고 정수를 예를 들어, 돈 / 센트를 표현하기 위해,하지만 수량이있는 정밀도가 시간이 지남에 따라 변경 될 수 있습니다 때 아주 예를 들어, 다른 경우에 적합하지 않습니다.

해결법

  1. ==============================

    1.내 CompSci 교수는 통화 사용 수레에 절대 말을하지 기억한다.

    내 CompSci 교수는 통화 사용 수레에 절대 말을하지 기억한다.

    는 IEEE 사양을 정의 바이너리 형식으로 수레 어떻게 그 이유이다. 기본적으로, 기호, 분수와 플로트를 대표하는 지수를 저장합니다. 그것은 바이너리에 대한 과학적 표기법처럼 (+ 1.43 * 10 ^ 2 같은). 그 때문에, 정확히 플로트에서 분수와 소수를 저장하는 것은 불가능합니다.

    진수 형식이 이유입니다. 이 작업을 수행하는 경우 :

    irb:001:0> "%.47f" % (1.0/10)
    => "0.10000000000000000555111512312578270211815834045" # not "0.1"!
    

    당신은 그냥 할 경우 반면

    irb:002:0> (1.0/10).to_s
    => "0.1" # the interprer rounds the number for you
    

    당신이 합성 이익, 또는 어쩌면 위치 정보와 같은 작은 분수를 처리하는 경우 소수점 형식 1.0 / 10 정확히 0.1이기 때문에 그래서, 내가보기 엔, 진수 형식을 추천 할 것입니다.

    그러나, 덜 정확한 임에도 불구 수레 빨리 처리하는 것을 주목해야한다. 여기에 벤치 마크는 다음과 같습니다

    require "benchmark" 
    require "bigdecimal" 
    
    d = BigDecimal.new(3) 
    f = Float(3)
    
    time_decimal = Benchmark.measure{ (1..10000000).each { |i| d * d } } 
    time_float = Benchmark.measure{ (1..10000000).each { |i| f * f } }
    
    puts time_decimal 
    #=> 6.770960 seconds 
    puts time_float 
    #=> 0.988070 seconds
    

    당신은 너무 많은 정밀 걱정하지 않는다 사용 플로트. 예를 들어, 일부 과학적 시뮬레이션과 계산은 3 개 또는 4 유효 숫자까지해야합니다. 이 속도에 대한 정확성을 거래하는 데 유용합니다. 그들은 속도만큼 정밀도를 필요로하지 않기 때문에, 그들은 플로트를 사용합니다.

    사용 소수점이 필요 정확하고 (합성 관심과 돈에 관련된 일 등) 정확한 수를 합계하는 것을 숫자를 처리하는 경우. 기억하십시오 : 당신이 정밀도를 필요로하는 경우에, 당신은 항상 소수를 사용해야합니다.

  2. ==============================

    2.레일 3.2.18에서 :에 소수점 회전 : 정수의 SQLServer를 사용하는 경우,하지만 SQLite는에서 잘 작동합니다. 전환 : 플로트는 우리를 위해이 문제를 해결했다.

    레일 3.2.18에서 :에 소수점 회전 : 정수의 SQLServer를 사용하는 경우,하지만 SQLite는에서 잘 작동합니다. 전환 : 플로트는 우리를 위해이 문제를 해결했다.

    배운 교훈은 "항상 균일 개발 및 배포 데이터베이스를 사용!"입니다

  3. ==============================

    3.레일 4.1.0, 나는 MySQL 데이터베이스에 위도와 경도를 저장하여 문제를 직면했다. 그것은 부동 소수점 데이터 형식의 많은 부분 번호를 저장할 수 없습니다. 그리고 진수 데이터 유형을 변경하고 나를 위해 작동합니다.

    레일 4.1.0, 나는 MySQL 데이터베이스에 위도와 경도를 저장하여 문제를 직면했다. 그것은 부동 소수점 데이터 형식의 많은 부분 번호를 저장할 수 없습니다. 그리고 진수 데이터 유형을 변경하고 나를 위해 작동합니다.

      def change
        change_column :cities, :latitude, :decimal, :precision => 15, :scale => 13
        change_column :cities, :longitude, :decimal, :precision => 15, :scale => 13
      end
    
  4. from https://stackoverflow.com/questions/8514167/float-vs-decimal-in-activerecord by cc-by-sa and MIT license