पहले दशमलव स्थान पर प्रिंटफ़ राउंड हाफ़ कैसे होता है?


11

मैं printfअपने सिस्टम पर दो अलग-अलग कार्यान्वयन का परीक्षण कर रहा हूं: printf (GNU coreutils) 8.26और संस्करण के साथ बंडल किया गया zsh 5.3.1। मैं परीक्षण कर रहा हूं कि कैसे आधे नंबर राउंड किए जाते हैं, यानी 1.5, 2.5, 3.5,… 9.5।

$ for i in {1..9}; do /usr/bin/printf '%.0f\n' "${i}.5"; done
2
2
4
4
6
6
8
8
10
$ for i in {1..9}; do printf '%.0f\n' "${i}.5"; done
2
2
4
4
6
6
8
8
10

यहाँ, दोनों स्पष्ट रूप से आधे से भी गोल । हालांकि, जब मैं पहले दशमलव स्थान पर गोलाई का परीक्षण करता हूं, तो चीजें भ्रमित हो जाती हैं। यही है, मैं 1.15, 1.25, 1.35,… 1.95 के लिए परीक्षण कर रहा हूं।

$ for i in {1..9}; do /usr/bin/printf '%.1f\n' "1.${i}5"; done
1.1
1.2
1.4
1.5
1.5
1.6
1.8
1.9
2.0
$ for i in {1..9}; do printf '%.1f\n' "1.${i}5"; done
1.1
1.2
1.4
1.4
1.6
1.6
1.8
1.9
1.9

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

जवाबों:


19

जीएनयू printf का उपयोग करता हैlong double , जबकि zsh नियमित उपयोग करता doubleरों । आपके द्वारा देखा जाने वाला गोलाई व्यवहार ऐसा है (क्योंकि) 1.45 को 2 की शक्तियों के योग के रूप में प्रस्तुत नहीं किया जा सकता है, जो कि IEEE 754 फ़्लोटिंग-पॉइंट प्रतिनिधित्व कार्य करता है, और निकटतम सन्निकटन सटीक के अनुसार बदलता रहता है। यह थोड़ा और अधिक (80 बिट्स के साथ) या कम (64 बिट्स के साथ) है, इस प्रकार आप ऊपर या नीचे देखते हैं।

हमेशा की तरह, यदि आप सटीक मानव-स्तरीय प्रतिनिधित्व और गोलाई की परवाह करते हैं, तो फ़्लोटिंग-पॉइंट का उपयोग न करें।


1
बस ध्यान दें कि x.25 और x.75 (उपयुक्त रूप से छोटे x के लिए) में दूसरों के विपरीत सटीक बाइनरी अभ्यावेदन होते हैं।
टॉबी स्पीट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.