इंट बनाम फ्लोर तक कास्ट


120

क्या इनमें कोई अंतर है:

float foo1 = (int)(bar / 3.0);
float foo2 = floor(bar / 3.0);

जैसा कि मैं समझता हूं कि दोनों मामलों का परिणाम समान है। संकलित कोड में कोई अंतर है?


1
के साथ थोड़ा बेहतर है floor, लेकिन खबरदार कि यह doubleनहीं के लिए है float। C99 भी है floorfके लिए float
जेन्स गस्टेड

2
इसलिए उनका एक ही परिणाम है जब तक कि बार सकारात्मक है
Zac

1
(नोट: C ++ में कृपया #include<cmath>और उपयोग करें std::floor)
user202729

किस प्रकार का है bar?
chux -

@chux कोई फर्क नहीं पड़ता, 3.0 से विभाजित यह वैसे भी दोगुना कर देगा
kaalus

जवाबों:


193

एक इंट को कास्टिंग शून्य की ओर छोटा कर देगा। floor()नकारात्मक अनंत की ओर छंटनी करेगा। यह आपको अलग-अलग मूल्य देगा यदि barनकारात्मक थे।


15
मुझे लगता है कि आपने यहां सिर पर कील ठोक दी। एक और अंतर, अगर floor()इरादा है, अगर मूल्य में barफिट होने के लिए बहुत बड़ा है int
फ्रेड लार्सन

क्या आपके पास उस कथन का कोई स्रोत है?
हैलोगौडबी

1
परिणाम सकारात्मक होने पर भी इसकी गारंटी नहीं है। यह और यह देखें ।
user202729

27

जैसा कि पहले कहा गया था, सकारात्मक संख्याओं के लिए वे समान हैं, लेकिन वे नकारात्मक संख्याओं के लिए भिन्न हैं। नियम यह है कि इंट 0 की ओर गोल होता है, जबकि फर्श नकारात्मक अनंत की ओर गोल होता है।

floor(4.5) = (int)4.5 = 4
floor(-4.5) = -5 
(int)(-4.5) = -4

यह कहा जा रहा है, निष्पादन समय में भी अंतर है। मेरे सिस्टम पर, मैंने टाइमिंग की है कि कास्टिंग फर्श से कम से कम 3 गुना तेज है।

मेरे पास कोड है जो नकारात्मक संख्याओं सहित मूल्यों की एक सीमित श्रृंखला के फर्श संचालन की आवश्यकता है। और इसे बहुत कुशल बनाने की आवश्यकता है, इसलिए हम इसके लिए निम्नलिखित फ़ंक्शन का उपयोग करते हैं:

int int_floor(double x) 
{ 
    return (int)(x+100000) - 100000; 
}

बेशक, यह x के बहुत बड़े मूल्यों के लिए विफल हो जाएगा (आप कुछ अतिप्रवाह के मुद्दों में चलेंगे) और -100000 से नीचे के नकारात्मक मूल्यों के लिए, आदि, लेकिन मैंने इसे फर्श से कम से कम 3 गुना तेज होने के लिए देखा है, जो वास्तव में महत्वपूर्ण था हमारे आवेदन के लिए। इसे नमक के दाने के साथ लें, इसे अपने सिस्टम पर परीक्षण करें, लेकिन यह आईएमएचओ पर विचार करने के लायक है।


"मैंने इसे फर्श से कम से कम 3 गुना तेज देखा है" -> ओपी उपयोग कर रहा है float, न कि double- शायद doubleआपका आवेदन था। यदि C में है, तो s के floorf()साथ प्रयोग करना सुनिश्चित करें float
चुक्स - मोनिका

@ मुझे लगता है कि एकमात्र कारण कोई अंतर है कि कलाकार एक संकलन-समय अनुकूलन के लिए अनुमति देता है। ताकि रूपांतरण वास्तव में निष्पादन के दौरान पूरी तरह से हटा दिया गया हो।
क्लाइड.गॉस्ट

9

एसओ 101, लोगों द्वारा आपके प्रश्न का उत्तर देने के बाद अपना प्रश्न न बदलें, इसके बजाय एक नया प्रश्न लिखें।

आपको क्यों लगता है कि उनके पास एक ही परिणाम होगा?

float foo = (int)(bar / 3.0) //will create an integer then assign it to a float

float foo = fabs(bar / 3.0 ) //will do the absolute value of a float division

bar = 1.0

foo1 = 0;
foo2 = 0.33333...

1
आपका क्या मतलब है fabs? सवाल था floor। की मंजिल है 0.33333... है 0
एरॉन फ्रेंक

2
@AaronFranke मूल प्रश्न को संशोधित किया गया है। लगता है 8 साल में बहुत कुछ हो सकता है ;-) अन्य उत्तरों का एक ही आधार है
AndersK

4

EDIT: क्योंकि बीच में भ्रम के कारण प्रश्न को संशोधित किया जा सकता है fabs()और floor()

मूल प्रश्न उदाहरण लाइनों को देखते हुए:

1.  float foo = (int)(bar / 3.0);

2.  float foo = fabs(bar / 3.0);

अंतर यह है कि यदि बार नकारात्मक है तो परिणाम पहले के साथ नकारात्मक होगा लेकिन दूसरे के साथ सकारात्मक होगा। पहले को एक पूर्णांक में काट दिया जाएगा और दूसरा आंशिक अंश सहित पूर्ण दशमलव मान लौटाएगा।


3

हाँ। fabsअपने तर्क के निरपेक्ष मान को लौटाता है, और इंट टू कास्ट डिवीजन के ट्रंकेशन (निकटतम इंट के नीचे) का कारण बनता है, इसलिए परिणाम लगभग हमेशा अलग होंगे।


2

दो मुख्य अंतर हैं:

  1. जैसा कि दूसरों ने बताया है, पूर्णांक पर कास्टिंग शून्य की ओर कम हो जाएगी, जबकि floor()हमेशा नकारात्मक अनंत की ओर छंटनी होगी; यह एक नकारात्मक ऑपरेंड के लिए अलग व्यवहार है।

  2. किसी को भी (अभी तक) ने एक और अंतर नहीं बताया है - यदि आपका तर्क इससे अधिक MAX_INT+1(या उससे कम -MAX_INT-1) के बराबर है, तो intवसीयत में कास्टिंग करने से शीर्ष-बिट बिट्स गिराया जाएगा (सी, शायद) या अपरिभाषित व्यवहार ( C ++ और संभवतः C)। ईजी अगर आपके int32 बिट्स हैं, तो आपके पास केवल साइन बिट प्लस 31 बिट्स डेटा होगा। अतः इसका उपयोग doubleबड़े आकार के साथ करने से अनायास ही परिणाम सामने आने वाले हैं।


2.a. रूपांतरण के लिए intअतिप्रवाह की सही स्थिति यह है कि तर्क 1 से अधिक या बराबर है INT_MAX। सममित रूप से, अंडरफ्लो की स्थिति यह है कि तर्क कम या INT_MIN-1 के बराबर है ।
पास्कल क्यूक

1
2.b. फ्लोटिंग-पॉइंट से पूर्णांक तक रूपांतरण में अतिप्रवाह C ++ में अपरिभाषित व्यवहार है। यह "शीर्ष-सबसे बिट्स गिराए जाने के परिणामस्वरूप" नहीं होता है। देखें (हालाँकि यह C के लिए लिखा गया है): blog.frama-c.com/index.php?post/2013/10/09/……
पास्कल कुक्कू

0

(int) xके पूर्णांक भाग को रखने का अनुरोध है x(यहां कोई राउंडिंग नहीं है)

fabs(x)= | एक्स | ताकि यह हो >= 0;

Ex: (int) -3.5रिटर्न -3; fabs(-3.5)रिटर्न 3.5;

सामान्य तौर पर, fabs (x) >= xसभी एक्स के लिए;

x >= (int) x अगर x >= 0

x < (int) x अगर x < 0


x = -3 फ़ैब्स (-3) = 3 (int) -3 = -3; मुझे लगता है कि अंतिम असमानताएं हैं। क्या आप इस बारे में अधिक विस्तार से बता सकते हैं कि यह गलत क्यों है?
पॉल होआंग

क्षमा करें, मेरा मतलब -3.5 है, आपने जो उदाहरण दिया है। -3> -3.5
डेनिस ज़िकफोज़ जूले

3
अंतिम कथन अभी भी "x <= int (x) यदि x <0" होना चाहिए, और "x <(int) x नहीं तो x <0": नकारात्मक पूर्णांक समान रहते हैं।
टॉमस गैंडर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.