ฉันมีเรื่องจะสารภาพ ฉันเกลียดตัวเลขทศนิยม แน่นอนว่ามีประโยชน์หากคุณเป็นคอมพิวเตอร์ แต่ถ้าคุณเป็นมนุษย์ คุณก็จะเกาหัวในสถานการณ์เช่นนี้:
129.95 * 100
# => 12994.999999999998
สิ่งนี้ไม่เพียงแค่ต้องเผชิญกับความกลมกลืนทางคณิตศาสตร์เท่านั้น แต่ยังเป็น UX ที่แย่อีกด้วย
หากสูตรบอกให้คุณตวงแป้ง 0.37211927843 ถ้วย คุณอาจจะหัวเราะเยาะตัวเองว่าผู้เขียนเป็นคนงี่เง่าอะไร และตวงแป้งไปหนึ่งในสามส่วน
คนส่วนใหญ่สามารถคิดเกี่ยวกับเศษส่วนได้ง่ายกว่าที่พวกเขาคิดเกี่ยวกับตัวเลขทศนิยมตามอำเภอใจ ดังนั้น หากแอปของคุณพยายามสื่อสารตัวเลขกับผู้คน การสำรวจวิธีการแสดงตัวเลขเหล่านี้เป็นเศษส่วนอาจเป็นเรื่องที่สมเหตุสมผล
Rational
ของทับทิม class เป็นเครื่องมือที่ยอดเยี่ยมสำหรับการทำงานกับจำนวนตรรกยะ ไม่เพียงแต่ช่วยให้คุณทำคณิตศาสตร์แบบมีเหตุมีผลเท่านั้น แต่ยังช่วยให้คุณหาเศษส่วนง่ายๆ ที่ใกล้เคียงกับตัวเลขทศนิยม มาดูกัน!
เหตุผลคืออะไร
สำหรับจุดประสงค์ของเรา "จำนวนตรรกยะ" เป็นเพียงวิธีแฟนซีในการพูดว่า "เศษส่วน" มีสองส่วน:ตัวเศษและส่วน
1/2 # Numerator is 1. Denominator is 2.
5 # Numerator is 5. Denominator is 1.
ใน Ruby ตัวเลขตรรกยะจะมีประเภทข้อมูลของตัวเอง เช่นเดียวกับจำนวนเต็มและเลขทศนิยม มีสองวิธีในการสร้างเหตุผลใหม่:
3/2r # This syntax was introduced in Ruby 2.1
1.5.to_r # Floats can be converted to rationals via `to_r`
"3/2".to_r # ...so can strings
Rational('3/2') # This is how we had to do things in the olden days
Rational(3, 2) # ...see how hard life was?
คณิตศาสตร์อย่างง่าย
เมื่อคุณบวก ลบ คูณ หรือหารจำนวนตรรกยะสองจำนวน ผลลัพธ์จะเป็นจำนวนตรรกยะด้วย
2/3r + 1/3r
# => (1/1)
2/3r - 1/3r
# => (1/3)
2/3r * 1/3r
# => (2/9)
(2/3r) / (1/3r) # We need parens here to avoid confusing the interpreter
# => (2/1)
ตัวดำเนินการทางคณิตศาสตร์อื่นๆ ทั้งหมดทำเหมือนที่คุณคาดหวังเช่นกัน:**
, >
, <
, ฯลฯ..
กฎทั่วไปคืออินพุตทั้งสองต้องเป็นเศษส่วนเพื่อให้ผลลัพธ์เป็นเศษส่วน ข้อยกเว้นเดียวที่ฉันพบได้คือจำนวนเต็ม เนื่องจากจำนวนเต็มทั้งหมดเป็นจำนวนตรรกยะ Ruby จึงทำสิ่งที่ฉลาดและถือว่าทุกคนเป็นผลลัพธ์ที่มีเหตุผล:
2/3r + 2
# => (8/3)
ค่าประมาณ
สิ่งหนึ่งที่มีประโยชน์มากที่สุดเกี่ยวกับจำนวนตรรกยะคือช่วยให้เราสามารถประมาณค่าและคำนวณได้อย่างง่ายดายในหัวของเรา เพื่อใช้ประโยชน์จากสิ่งนี้ เราต้องทำให้เศษส่วนของเราง่าย 3/2
แทน 3320774221237909/2251799813685248
.
โชคดีที่ Ruby มีวิธีง่ายๆ ในการแปลงตัวเลขที่แม่นยำแต่น่าเกลียดเหล่านี้เป็นตัวเลขโดยประมาณแต่ก็สวยงาม ฉันกำลังพูดถึง rationalize
วิธีการ
นี่คือลักษณะ:
# Precise but ugly
(1.47472).to_r
=> (3320774221237909/2251799813685248)
# Less precise, but pretty
(1.47472).to_r.rationalize(0.05)
=> (3/2)
วิธีการหาเหตุผลเข้าข้างตนเองมีหนึ่งอาร์กิวเมนต์ ระบุค่าความคลาดเคลื่อน – ปริมาณความแม่นยำที่คุณต้องการแลกเปลี่ยนเพื่อความเรียบง่าย
วิธีนี้จะค้นหาตัวเลขที่มีตัวส่วนต่ำที่สุดในเกณฑ์ความคลาดเคลื่อนของคุณ ฉันหมายถึงอะไร:
# What's the number with the lowest denominator between 5/10 and 7/10?
(6/10r).rationalize(1/10r)
# => (1/2)
# What's the number with the lowest denominator between 11/20 and 13/20?
(6/10r).rationalize(1/20r)
=> (3/5)
# ..and between 1/10 and 11/10?
(6/10r).rationalize(1/2r)
=> (1/1)
การประมาณน้ำมันดิบ
หากสิ่งที่คุณต้องทำคือหาจำนวนเต็มหรือเลขทศนิยมที่ตรงกับเศษส่วน คุณมีหลายทางเลือก
# Return the nearest integer.
(6/10r).round
# => 1
# Round down
(12/10r).to_i
# => 1
ข้อจำกัดของเหตุผล
มีข้อ จำกัด บางประการที่ต้องระวังเมื่อทำงานกับจำนวนตรรกยะและทับทิม แน่นอนว่าคุณไม่สามารถหารด้วยศูนย์ได้:
4/0r
ZeroDivisionError: divided by 0
และคุณจะพบกับพฤติกรรมแปลก ๆ หากคุณพยายามถือว่าจำนวนอตรรกยะเป็นจำนวนตรรกยะ
# Umm, isn't the square root of 2 irrational?
Rational(Math.sqrt(2))
# => (6369051672525773/4503599627370496)
# And I'm pretty sure PI is irrational as well.
Rational(Math::PI)
# => (884279719003555/281474976710656)
เราอาจคาดหวังว่าการขอให้ Ruby ปฏิบัติกับจำนวนอตรรกยะเป็นจำนวนตรรกยะจะทำให้เกิดข้อยกเว้นบางประเภท แต่น่าเสียดายที่ Ruby ดูเหมือนจะไม่ฉลาดพอที่จะทำเช่นนี้ แต่จะแปลงค่าประมาณทศนิยมของจำนวนอตรรกยะเหล่านี้เป็นตรรกยะแทน มันไม่ใช่ปัญหาใหญ่แต่เป็นสิ่งที่ต้องระวัง