2016-10-05 4 views
4

좌표로 계산할 필요가 있으며 (적어도 나를 위해) 이상한 행동을 보았습니다. 누군가 이런 일이 발생하는 이유를 설명 할 수 있습니까?왜 Mod 계산시 Ruby가 정밀도/숫자를 추가합니까?

$ long 
=> 49.0126760222489 
$ long % long.floor 
=> 0.012676022248896857 

나는 long의 기간 이후에 바로 자리에 평가하는 마지막 줄을 기대하지만, 대신 마지막에 압정으로 고정 추가 6857가되었다.

왜 자릿수가 추가됩니까?

출처는 어디입니까?

+0

어떻게 길 값을 계산 했습니까? – sokkyoku

+0

데이터베이스에서 오는 것 – Flip

+0

사용중인 Ruby 버전은 무엇입니까? – quetzalcoatl

답변

2

우리는 단순히 float의 imprecions를 본다고 가정합니다. 즉 0.0126760222489 % 1.01.0126760222489 % 1.0을 참조하십시오. 결과가 같아야한다고 생각 하겠지만, IEEE754 부동 소수점/복소수는 완벽한 결과를 보장하지는 않으며 기본적으로 부동 소수점 값을 저장하기 위해 Ruby에서 사용됩니다.

심지어 다소 in the docs

6543.21.modulo(137)  #=> 104.21 
6543.21.modulo(137.24) #=> 92.9299999999996 

두 번째 결과는 작은 오류가있는 것을 볼 수 있습니다을 표시합니다. 눈에 보이는 항상

pry(main)> 6543.21.modulo(137) 
=> 104.21000000000004 

그것은 반드시 모듈 관련이없는 것, 그리고 :

[30] pry(main)> 10.0126760222489 - 0.0 
=> 10.0126760222489 
[31] pry(main)> 10.0126760222489 - 1.0 
=> 9.0126760222489 
[32] pry(main)> 10.0126760222489 - 2.0 
=> 8.0126760222489 
[33] pry(main)> 10.0126760222489 - 3.0 
=> 7.0126760222489 
[34] pry(main)> 10.0126760222489 - 4.0 
=> 6.0126760222489 
[35] pry(main)> 10.0126760222489 - 5.0 
=> 5.0126760222489 
[36] pry(main)> 10.0126760222489 - 6.0 
=> 4.0126760222489 
[37] pry(main)> 10.0126760222489 - 7.0 
=> 3.0126760222489004 

표준을 사용하는 소프트웨어의 모든 조각이 필요 수레 사실, 루비 2.3.1에 나는 첫 번째 줄을 실행하고있어 이러한 작은 오류를 설명합니다. 당신이 어떤 이유로 그것을 처리 할 수없는 경우에, 당신은 'BigDecimal를'이 느려질 수 있습니다 것을 명심 bigdecimal (이미 루비에 포함되어야한다), 고정 소수점, 또는 유사한 숫자 라이브러리

require 'bigdecimal' 

BigDecimal('6543.21').modulo(137).to_s 
=> "0.10421E3" 

BigDecimal('6543.21').modulo(137).to_f 
=> 104.21 

를 사용할 수 있습니다 더 많은 메모리를 사용할 수 있습니다.

+0

이전에 물어 보았지만 답변을 받았음에도 불구하고 답변 해 주셔서 감사합니다. – Flip

3

루비 자체와는 아무 상관이없는 것 같다,하지만 :

부동 소수점 숫자가 바이트의 X 번호로 제한하고 있기 때문에 일반적으로 오류를 반올림의이 유형에서 고통, 그리고 일반적으로 십진수를 완벽하게 저장할 수 없습니다. 하나 위의 문서에서

Documentation

또한 기본 플로트 문제를 해결 얻기위한 몇 가지 옵션을 얻을 수 있습니다. 위의 문서는 ruby-doc.org에서 제공하는 공식 문서로 간주 할 수 있습니다.

+3

이것은 "보다 정확한"결과는 아니며 * 덜 * 정확한 결과.끝 부분에 '0000'을 추가하면 정확 해지고, '6857'을 추가하면 작은 마진으로 결과가 잘못 표시됩니다. – meagar

+0

'long.floor'을 변환하면 Fixnum 값은 나에게 적합하지 않습니다.'long' 자체는 이미 부동 소수점이므로. 나는 float % fixnum에서 아무런 결과도 얻지 못하고 float을 발견합니다. 나는 우리가 단순히 float의 imprecions를 본다고 가정합니다. 즉, '0.0126760222489 % 1.0'및 '1.0126760222489 % 1.0'을 참조하십시오. – quetzalcoatl