Astronomical computing - Ep 3 - Ruby의 각도
21309 단어 rubyprogrammingastronomy
Ruby 라이브러리를 향한 첫 번째 단계로 각도와 단위를 조작하는 것으로 시작할 것입니다.
Bundler 및 해당 명령
$ bundle gem astronoby
을 사용하여 만든 보석 생성 및 스켈레톤을 전달하겠습니다.개체 유형
이 책은 우리에게 다음과 같이 알려줍니다.
To convert an angle from degrees to radians, multiply it by π/180.
Ruby에서는 다음과 같이 작성됩니다.
Math::PI / 180
Math::PI
은 표준 라이브러리에서 가져오고 Float
를 반환합니다.(Math::PI / 180).class
# => Float
Math::PI / 180
# => 0.017453292519943295
A
Float
는 조작하기 쉽습니다. 또한 사용 가능한 정밀도가 0 다음의 18자리로 매우 흥미로운 것처럼 보입니다.그러나 이것은 나에게 충분하지 않습니다. 각도는 이 전체 라이브러리에서 가장 중요하고 사용되는 데이터 중 하나가 될 것입니다. 그들은 크게 번성하고 나누어질 것입니다. 정의에 따라 a
Float
는 π를 조작할 때 완전히 정확하지 않습니다.약간의 정확성을 잃어도 괜찮은 순간이 있을 수 있지만 의도적으로가 아니라 선택에 의한 것이었으면 합니다.
또한 π를 신경 쓰지 않고
Float
는 부정확성이 있으므로 정확도를 신경 쓸 때 사용해서는 안 됩니다.0.1 + 0.2
# => 0.30000000000000004
1.1 * 0.1
# => 0.11000000000000001
따라서
BigDecimal
숫자 값, 특히 BigMath.PI
을 사용해야 합니다.require "bigdecimal/math"
BigMath.PI(10).class
# => BigDecimal
BigMath.PI(10)
# 0.3141592653589793238462643388813853786957412e1
BigMath.PI(10) / 180
# 0.17453292519943295769236907715632521038652289e-1
퍼스트 클래스
우리는 3개의 수업으로 기본을 시작합니다:
Angle
모든 각도, 모든 단위Degree
도 단위로 초기화된 각도 조작용Radian
라디안으로 초기화된 각도 조작용각도
Angle
는 몇 가지 기본 사항을 구현하지만 더 중요한 것은 각도를 다른 단위로 변환할 수 있다는 것입니다. 우리는 #to_degrees
와 #to_radians
를 다른 단위로 Angle
의 새로운 인스턴스로 변환하기 위해 각도에서 사용할 수 있기를 원합니다.관련 사양을 작성해 보겠습니다.
RSpec.describe Astronoby::Angle do
describe "::as_degrees" do
subject { described_class.as_degrees(180) }
it "returns an Angle object" do
expect(subject).to be_a(described_class)
end
it "returns an Angle in Degree" do
expect(subject).to be_a(Astronoby::Degree)
end
end
describe "::as_radians" do
subject { described_class.as_radians(BigMath.PI(10)) }
it "returns an Angle object" do
expect(subject).to be_a(described_class)
end
it "returns an Angle in Radian" do
expect(subject).to be_a(Astronoby::Radian)
end
end
end
Angle
는 하위 클래스에서 처리할 단위 변환 계산을 관리하지 않습니다.실제 각도 값을
@value
속성에 저장하고 unit
매개변수를 사용하여 값의 단위를 지정합니다.상위
Angle
클래스의 첫 번째 구현은 다음과 같습니다.module Astronoby
class Angle
UNITS = [
DEGREES = :degrees,
RADIANS = :radians
].freeze
def self.as_degrees(angle)
Astronoby::Degree.new(angle)
end
def self.as_radians(angle)
Astronoby::Radian.new(angle)
end
def initialize(angle, unit:)
@angle = BigDecimal(angle)
@unit = unit
end
def value
@angle
end
def to_degrees
raise NotImplementedError, "#{self.class} must implement #to_degrees method."
end
def to_radians
raise NotImplementedError, "#{self.class} must implement #to_radians method."
end
end
end
각도를 조작하거나 변환할 때 정밀도를 유지하기 위해 각도 값을 자동으로
BigDecimal
로 변환합니다.도
Degree
클래스는 도 단위의 각도에 대한 특정 논리를 처리하는 것을 목표로 합니다.지금 우리가 구현해야 하는 유일한 논리는 도에서 라디안으로 변환하는 것입니다. 여기에서 "곱하기 π/180"규칙을 작성합니다.
먼저 이 새 클래스가 어떻게 작동해야 하는지 정의하는 테스트부터 시작하겠습니다. 우리는
#to_degrees
가 각도를 그대로 유지하고 #to_radians
가 적절한 클래스의 새 인스턴스를 반환하고 해당 값을 변환하는지 확인하려고 합니다.RSpec.describe Astronoby::Degree do
let(:instance) { described_class.new(180) }
describe "#value" do
subject { instance.value }
it "returns the angle's numeric value in the current unit" do
expect(subject).to eq(180)
end
end
describe "#to_degrees" do
subject { instance.to_degrees }
it "returns itself" do
expect(subject).to eq(instance)
end
end
describe "#to_radians" do
subject { instance.to_radians }
it "returns a new Radian instance" do
expect(subject).to be_a(Astronoby::Radian)
end
it "converted the degrees value into radians" do
expect(subject.value).to eq(BigMath.PI(10))
end
end
end
Degree
따라서 구현은 매우 간단합니다.module Astronoby
class Degree < Angle
def initialize(angle)
super(angle, unit: DEGREES)
end
def to_degrees
self
end
def to_radians
self.class.as_radians(@angle / 180 * PI)
end
end
end
마지막으로 우리가 한동안 이야기해 온 전환입니다.
라디안
동일한 구조에서
Radian
에는 라디안 단위의 각도를 도로 변환하는 논리가 포함됩니다.RSpec.describe Astronoby::Radian do
let(:instance) { described_class.new(BigMath.PI(10)) }
describe "#value" do
subject { instance.value }
it "returns the angle's numeric value in the current unit" do
expect(subject).to eq(BigMath.PI(10))
end
end
describe "#to_degrees" do
subject { instance.to_degrees }
it "returns a new Degree instance" do
expect(subject).to be_a(Astronoby::Degree)
end
it "converted the degrees value into degrees" do
expect(subject.value).to eq(180)
end
end
describe "#to_radians" do
subject { instance.to_radians }
it "returns itself" do
expect(subject).to eq(instance)
end
end
end
module Astronoby
class Radian < Angle
def initialize(angle)
super(angle, unit: RADIANS)
end
def to_degrees
self.class.as_degrees(@angle * 180 / PI)
end
def to_radians
self
end
end
end
결론
첫 번째 단계는 각도를 조작하고 각도를 라디안으로 변환할 수 있는 Astronoby라는 작동하는 보석입니다.
다음은 gem 사용 예입니다.
require "astronoby"
Astronoby::Angle
.as_degrees(180)
.to_radians
.value == BigMath.PI(10)
# => true
소스 코드는 현재 Github에서 사용할 수 있으며 gem은 RubyGems에서 다운로드할 수 있고 새로운 버전version이 출시되었습니다.
다음 단계에서는 시간, 특히 캘린더와 표준 시간대에 대한 또 다른 기본 주제를 살펴보겠습니다.
즐거운 해킹
출처
Reference
이 문제에 관하여(Astronomical computing - Ep 3 - Ruby의 각도), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/rhannequin/astronomical-computing-ep-3-lbf텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)