2014-10-02 6 views
18

मैं इन पढ़ लिया है:फ़्लोटिंग पॉइंट ऑपरेशंस कुछ भाषाओं में अलग क्यों दिखते हैं?

वे समझाने "कैसे"। मैं जानना चाहता हूं कि यह इन भाषाओं में अलग क्यों है। मुझे उम्मीद है कि समान इनपुट दिए गए समान परिणाम।

test.js

#!/usr/bin/env node 

var nine = 9.0; 
var pointOhOhOne = 0.001; 
var result = nine * pointOhOhOne; 
console.log(result); 

test.java

public class test { 

    public static void main(String[] argv) { 
    double nine = 9.0d; 
    double pointOhOhOne = 0.001d; 
    double result = nine * pointOhOhOne; 
    System.out.println(result); 
    } 

} 

test.c

#include "stdio.h" 

int main() { 
    double nine = 9.0; 
    double pointOhOhOne = 0.001; 
    double result = nine * pointOhOhOne; 
    printf("%f", result); 
} 

test.rb

#!/usr/bin/env ruby 

nine = 9.0 
pointOhOhOne = 0.001 
result = nine * pointOhOhOne 

print result 

test.py

#!/usr/bin/env python 

nine = 9.0 
pointOhOhOne = 0.001 
result = nine * pointOhOhOne 

print result 

परिणाम:

ruby  0.009000000000000001 
python 0.009 
node  0.009000000000000001 
java  0.009000000000000001 
c  0.009000 

सार: https://gist.github.com/reklis/6694ad5fb01991a79a1a

+19

शायद अलग-अलग भाषाओं में सभी _do_ समान उत्तर प्राप्त करते हैं, लेकिन जिस तरह से वे इसे प्रदर्शित करते हैं, वह अलग है। उदाहरण के लिए, आप 'दशमलव' मॉड्यूल का उपयोग कर पाइथन में अधिक मुद्रित सटीकता प्राप्त कर सकते हैं। 'दशमलव आयात करें; प्रिंट दशमलव। दशमलव (9.0 * 0.001) '0.00 9 000000000000001054711873393898713402450084686279296875' देता है। – Kevin

+2

चूंकि आप वास्तव में परीक्षण नहीं करते हैं कि किसी भी मूल्य में विशेष रूप से किसी भी चीज़ के बराबर * बराबर * है, क्या आपका प्रश्न वास्तव में है कि * प्रतिनिधित्व * अलग क्यों हैं? – DSM

+3

यह डिफ़ॉल्ट रूप से सी/सी + जैसा दिखता है [प्रिंट 6 महत्वपूर्ण अंक] (http://stackoverflow.com/questions/20135901/c-cout-double-not-printing-decimal-places)। – rgettman

उत्तर

15

@ouah स्थापित करता है कि भाषाएं सभी समान व्यवहार कर रही हैं। मेरा जवाब यह बताने का लक्ष्य है कि वे अलग क्यों दिखाई देते हैं। केवल दो भाषाओं में "अलग" आउटपुट हैं सी और पायथन हैं।

स्पष्ट रूप से, सी और पायथन के अलावा हर भाषा केवल फ्लोट वैल्यू को जितना संभव हो उतना दशमलव स्थान पर प्रिंट कर रही है।

सी व्याख्या करना आसान है। आप स्पष्ट परिशुद्धता मान निर्दिष्ट किए बिना printf("%f", result) का उपयोग करते हैं। सी मानक के अनुसार, f विनिर्देशक की परिशुद्धता 6 तक डिफ़ॉल्ट होती है। इस प्रकार, वास्तव में छह दशमलव स्थान मुद्रित होते हैं, जो आप देखते हैं। @उह नोट्स के रूप में, परिशुद्धता को 18 तक सेट करने से "अपेक्षित" आउटपुट मिलेगा। यह हानिकारक है: 7 वें दशमलव स्थान से अलग होने वाले युगल समान रूप से मुद्रित किए जाएंगे, और इसलिए %f के आउटपुट को मूल फ्लोट को बिल्कुल पुनर्निर्मित करने के लिए भरोसा नहीं किया जा सकता है।

पायथन थोड़ा सा ट्रिकियर है। पाइथन 3.1 ने डेविड गे द्वारा किए गए काम के आधार पर एक नया फ़्लोटिंग-पॉइंट repr एल्गोरिदम प्रस्तुत किया। सुविधा के अनुरूप पाइथन मुद्दा यहां है: http://bugs.python.org/issue1580। यह सुविधा पायथन 2.7 पर भी बैकपोर्ट की गई थी।

इस नई सुविधा के इरादे दोनों चल बिन्दु से अधिक भ्रम को कम करने के लिए (कि हालांकि dubiously उपयोगी है), और अधिक महत्वपूर्ण बात यह राउंड ट्रिप व्यवहार को प्रभावित किए बिना चल बिन्दु संख्या के छोटे अभ्यावेदन, अधिक मानव पठनीय प्रदान करना था ; यानी, float(repr(x)) हमेशा x के बराबर है, भले ही repr(x) इस एल्गोरिदम के कारण छोटा हो। इसलिए, एल्गोरिदम "लापरवाही" शेष रहते हुए एक छोटे फ्लोटिंग-पॉइंट प्रस्तुति का उत्पादन करने का प्रबंधन करता है: जीत-जीत!

आधिकारिक वर्णन इतना कहते हैं:

रेपर (1.1) के लिए नए एल्गोरिथ्म होशियार है और रिटर्न '1.1'। प्रभावी रूप से, यह सभी समकक्ष स्ट्रिंग प्रस्तुतियों की खोज करता है (वे जो समान अंतर्निहित फ्लोट मान के साथ संग्रहीत होते हैं) और सबसे कम प्रतिनिधित्व देता है।

+2

आपने लिखा "सी और पायथन के अलावा हर भाषा सिर्फ फ्लोट वैल्यू को जितना संभव हो उतना दशमलव स्थान पर प्रिंट कर रही है" लेकिन यह वास्तव में सच नहीं है। जावा और जावास्क्रिप्ट, उदाहरण के लिए, किसी भी तरफ से इस विशेष डबल-परिशुद्धता संख्या को अलग करने के लिए, जितनी आवश्यकता हो उतनी दशमलव स्थानों को मुद्रित करें। मैं रुबी पर एक विशेषज्ञ नहीं हूं, लेकिन ऐसा लगता है कि यह वही काम कर रहा है। बेशक, इनमें से कोई भी भाषा प्रश्न के तहत केविन की टिप्पणी के अनुसार - कई और दशमलव स्थानों को मुद्रित कर सकती है। –

+0

वह पायथन व्यवहार बहुत अजीब है ... और दिलचस्प है। मैं इसे एक उपलब्ध उपकरण के रूप में रखना चाहता हूं, हालांकि डिफ़ॉल्ट के रूप में नहीं। –

+1

@MooingDuck: पायथन का व्यवहार इतना असामान्य नहीं है: जावा का 'डबल.टोस्ट्रिंग' अनिवार्य रूप से वही काम करता है, और टीसीएल और (मुझे विश्वास है) रूबी> = 1.9 दोनों कुछ समान करते हैं। –

17
अपने सिस्टम पर

सी में:

print("%.18f" % result) 

0.009000000000000001 
:

printf("%.18f\n", result); 

0.009000000000000001 
अपने सिस्टम पर

अजगर में

सी या अन्य भाषाओं की तरह पायथन उनके प्रिंट कार्यों के साथ डिफ़ॉल्ट रूप से दशमलव अंकों की संख्या सीमित कर देता है।

संबंधित मुद्दे