2012-05-28 22 views
5

गुड मॉर्निंग सभी में प्रेसिजन साथ जारी करना,रूबी फ्लोटिंग प्वाइंट मठ - योग कैल्क

मैं चल बिन्दु गणित के साथ कुछ समस्याएं आ रही हैं, और मिल गया पूरी तरह से ".to_f" में खो दिया है की, "* 100" और ".0" है!

मुझे उम्मीद थी कि कोई मेरी विशिष्ट समस्या के साथ मेरी मदद कर सकता है, और यह भी समझा सकता है कि उनका समाधान क्यों काम करता है ताकि मैं अगली बार इसे समझ सकूं। एक का मान सेट -,

  1. योग दशमलव की एक सूची में यदि वे वास्तव में 1.0
  2. योग 1.0 के बीच एक अंतर और संख्याओं का योग का निर्धारण का निर्धारण:

    मेरे कार्यक्रम दो काम करने की जरूरत है योग बराबर 1.0 बनाने के लिए सटीक अंतर के लिए परिवर्तनीय।

उदाहरण के लिए:

  1. [0.28, 0.55, 0.17] ->, 1.0 करने के लिए योग करना चाहिए लेकिन मैं 1.xxxxxx जा रहे हैं। मैं निम्नलिखित फैशन में योग को लागू कर रहा हूँ:

    sum = array.inject(0.0){|sum,x| sum+ (x*100)}/100 
    
  2. कारण मैं इस कार्यक्षमता की जरूरत है कि मैं दशमलव कि एक्सेल से आते हैं का एक सेट में पढ़ रहा हूँ है। वे 100% सटीक नहीं हैं (उनमें कुछ दशमलव बिंदुओं की कमी है) इसलिए आमतौर पर योग 0.999 999xxxxx या 1.000xxxxx से बाहर आता है। उदाहरण के लिए, मैं निम्नलिखित की तरह मूल्य मिलेगा:

    0.568887955,0.070564759,0.360547286 
    

इसे ठीक करने के, मैं पहले n-1 संख्याओं का योग लेने, और फिर अंतिम नंबर बदलने से थोड़ा तो ठीक हूँ के सभी कि संख्याओं को एक साथ योग 1.0 (उपरोक्त समीकरण का उपयोग करके सत्यापन को पूरा करना होगा, या जो कुछ भी मैं समाप्त करता हूं)। इस प्रकार मैं इस समय इस लागू करने हूँ:

  sum = 0.0 
      array.each do |item| 
      sum += item * 100.0 
      end 
      array[i] = (100 - sum.round)/100.0 

मैं जानता हूँ कि मैं सुई के साथ ऐसा कर सकता है, लेकिन इसके साथ खेलने के लिए क्या काम करता है देखने के लिए कोशिश कर रहा था। मुझे लगता है कि यह आम तौर पर काम कर रहा है (आउटपुट की जांच से), लेकिन यह हमेशा उपरोक्त सत्यापन योग को पूरा नहीं करता है। तो अगर जरूरत हो तो मैं इसे भी समायोजित कर सकता हूं। ध्यान दें कि मुझे इन संख्याओं में केवल दो दशमलव परिशुद्धता की आवश्यकता है - यानी 0.56 0.5623225 नहीं। मैं प्रस्तुति के समय या फिर इस गणना के दौरान उन्हें गोल कर सकता हूं ... इससे कोई फर्क नहीं पड़ता।

आपकी मदद के लिए बहुत बहुत धन्यवाद!

उत्तर

8

यदि आपके लिए सटीकता महत्वपूर्ण है, तो आपको फ्लोटिंग पॉइंट मानों का उपयोग नहीं करना चाहिए, जो परिभाषा के अनुसार सटीक नहीं हैं।रूबी में अंकगणित करने के लिए कुछ सटीक डेटा प्रकार हैं जहां सटीकता महत्वपूर्ण है। वे वास्तव में गणना करने की आवश्यकता के आधार पर, मेरे सिर के शीर्ष से BigDecimal, Rational और Complex हैं।

ऐसा लगता है कि आपके मामले में, जो आप खोज रहे हैं वह BigDecimal है, जो मूल रूप से अंकों की एक निश्चित संख्या के साथ एक संख्या है, जिसमें दशमलव बिंदु के बाद अंकों की निश्चित संख्या होती है (इसके विपरीत फ़्लोटिंग पॉइंट, जिसमें दशमलव बिंदु के बाद अंक की मनमानी संख्या है)।

जब आप Excel से पढ़ते हैं और जानबूझकर उन स्ट्रिंग्स को "0.9 9 77" जैसे फ़्लोटिंग पॉइंट्स पर डालते हैं, तो आप स्ट्रिंग में निहित सटीक मान को तुरंत खो देते हैं।

require "bigdecimal" 
BigDecimal("0.9987") 

यह मान सटीक है। यह 0.9 9 7 है। 0.9, या इसके करीब कुछ भी नहीं, लेकिन 0.9 9 77। आप इस पर सभी सामान्य अंकगणितीय परिचालनों का उपयोग कर सकते हैं। बशर्ते आप अंकगणितीय परिचालनों में अस्थायी बिंदुओं को मिश्रण न करें, वापसी मूल्य सटीक बने रहेंगे।

अपने सरणी कच्चे तार आप Excel से मिला हैं (यानी आप #to_f 'नहीं किया है उन्हें d), तो यह आप के लिए एक BigDecimal है कि उनमें से योग और 1.

1 - array.map{|v| BigDecimal(v)}.reduce(:+) 
के बीच अंतर है दे देंगे
+0

धन्यवाद! उपयोगी जवाब – Brandon

2

कोई एक:

  • तैरता अपने योग का उपयोग कर और round(2) जारी रखने के लिए: 12.341.round(2) # => 12.34

  • उपयोग पूर्णांकों (यानी सेंट बजाय डॉलर)

  • उपयोग BigDecimal और आप की जरूरत नहीं होगी उन्हें संक्षेप में गोल करने के बाद, जब तक आप केवल दो दशमलव के साथ बिगडिसिल के साथ शुरू करते हैं।

0

मुझे लगता है कि एल्गोरिदम के पास एक और प्रतिनिधित्व पर आईईईई फ्लोटिंग पॉइंट की पसंद से सटीकता और सटीकता के साथ बहुत कुछ करना है।

लोग सटीकता और सटीक मुद्दों से निपटने के दौरान कुछ अच्छी गणना करते थे। वे एल्गोरिदम का प्रबंधन करके ऐसा करेंगे और समझेंगे कि कार्यों को और अधिक गहराई से कैसे पेश किया जाए। मुझे लगता है कि आप एक तरफ फेंक कर गलती कर सकते हैं कि बेहतर समझ और यह मानते हुए कि एक और प्रतिनिधित्व समाधान है।

उदाहरण के लिए, किसी फ़ंक्शन का बहुपद प्रतिनिधित्व किसी एसिम्पटोट या एकवचन के साथ ठीक से निपटने वाला नहीं होगा।

फ़्लोटिंग पॉइंट को इतनी जल्दी न छोड़ें। मैं हो सकता हूं कि आप जिस तरह से उपयोग करते हैं उसके बारे में समझदार होने के नाते बस ठीक होगा।