7

नमूना कोड:फ़्लोटिंग वैल्यू को पूर्ण सटीक सटीक सटीकता से 123.3443 से 1233443 तक कैसे परिवर्तित करें?

int main() { 
    float f = 123.542; 
    int i = (int)f; 
    printf("%d\n",i); 
} 
+2

यदि संख्या '1.999999999999' है तो क्या होगा? संकेत: आप जो कोशिश कर रहे हैं वह संभव नहीं है। (या कम से कम इसे बाइनरी फ़्लोटिंग-पॉइंट के साथ खराब परिभाषित किया गया है) – Mysticial

+0

शायद आप जो चाहते हैं वह कुछ हिस्सों के बाईं ओर एक फ्लोट प्राप्त करना है जो शून्य के करीब है (कुछ सहिष्णुता के साथ)? – markw

+0

@ मिस्टिकियल: यह वास्तव में फ्लोटिंग-पॉइंट के साथ हमेशा संभव है, क्योंकि एफपी एक्सपोनेंट 2 की शक्ति है। परिणाम आमतौर पर आप जो चाहते हैं वह नहीं होंगे (उदाहरण के लिए, यह केवल सटीक बाइनरी भिन्नताओं के लिए काम करेगा)। – duskwuff

उत्तर

2
int i = (int) (f * 10000 + 0.5); 
+2

वास्तव में आम तौर पर सहायक उत्तर नहीं है (हालांकि पूछताछकर्ता ठीक वही होगा जो उसने मांगा था)। यह शायद (बहुत) शायद वह नहीं था जो उसके मन में था। – AoeAoe

0

गुणा 10^x द्वारा floatx वह जगह है जहाँ कितने अंक दशमलव के बाद आप चाहते हैं और फिर int लिए डाली।

+0

यह काम करेगा, लेकिन आपको लगता है कि आप दशमलव स्थानों की संख्या को पहले से जानते हैं। – PeterAllenWebb

10

123.3443 32-बिट फ्लोट में एक फ़्लोटिंग-पॉइंट नंबर द्वारा बिल्कुल प्रतिनिधित्व नहीं किया जा सकता है, इसे प्रभावी रूप से 16166984/131072 के रूप में दर्शाया गया है, जो वास्तव में 123.34429931640625 है, 123.3443 नहीं। (यह लगभग 6.8 x 10^-7 से बंद है।)

यदि वास्तव में यह परिणाम आप चाहते हैं (जो शायद यह नहीं है), तो देखें कि आईईईई -754 कैसे काम करता है, और अपने पसंदीदा मनमानी- परिशुद्धता गणित सूट। एक बार जब आप समझते हैं कि "दृश्यों के पीछे" क्या हो रहा है, तो सटीक प्रतिनिधित्व उत्पन्न करना भी कठिन नहीं होना चाहिए। एक "करीबी पर्याप्त" गोलाकार प्रतिनिधित्व उत्पन्न करना वास्तव में बहुत कठिन है। :)

-1
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int f2i(float v, int size, int fsize){ 
    char *buff, *p; 
    int ret; 
    buff = malloc(sizeof(char)*(size + 2)); 
    sprintf(buff, "%*.*f", size, fsize, v); 
    p = strchr(buff, '.'); 
    while(*p=*(p+1))p++; 
    ret = atoi(buff); 
    free(buff); 
    return ret; 
} 

int main(){ 
    float f = 123.3443; 

    printf("%d\n", f2i(f, 7, 4)); 

    f=123.542; 
    printf("%d\n", f2i(f, 6, 3)); 
    return 0; 
} 
0

आप परिवर्तित नंबर के किसी भी दोहराव प्रसंस्करण करने की ज़रूरत नहीं है और केवल एक पूर्णांक में संख्या परिवर्तित करने के लिए देख रहे हैं, सबसे आसान तरीका sprintf उपयोग करने के लिए है, तो साथ दशमलव के योग है 10 नियमों की शक्ति का उपयोग कर लूप के लिए। यदि आपको गणित के लिए "सटीक सटीकता" की आवश्यकता है, तो बीसीडी का उपयोग करें। निम्नलिखित एल्गोरिदम आपको "सटीक परिशुद्धता" के लिए अंकों की संख्या को कम करने की अनुमति देगा।

#include "math.h" 

long ConvertToScaledInteger (float value, int significantDigits = -1) 
{ 
    // Note: for 32-bit float, use long return and for double use long long. 

    if (significantDigits < 1) // Ditch the '-' and the '.' 
     significantDigits += 2; 
    else 
     ++significantDigits;  // Ditch the '.' 

    char* floatingPointString = malloc(sizeof (char) * (4 + FLT_MANT_DIG - FLT_MIN_EXP)); 
    /*< This solution is for a 32-bit floating point number. Replace FLT 
     with DBL, and it will produce the max number of chars in a 64-bit 
     float string. */ 

    if (significantDigits < 0) //< Then use all of the float's digits. 
    { 
     sprintf (floatingPointString , "%f", floatingPointNumber); 
    } 
    else //< Then truncate the number of decimal places. 
    { 
     char decimalPlaceString[9]; 
     char percentString = "%\0"; 
     sprintf (decimalPlaceString, "%s%if", percentString , significantDigits); 
     sprintf (floatingPointString , decimalPlaceString, value); 
    } 

    int stringLength = strlen (floatingPointString), 
     index; 
    long returnValue = 0; 
    double powerOfTen = 10.0, 
     currentValue; 

    // Find if we have an ending of .0, and backtrack. 
    if (floatingPointString[stringLength - 1] == '0' && floatingPointString[stringLength - 2] == '.') 
     index = stringLength - 3; 
    else 
     index = stringLength - 1; 

    for (; index > 0; --index) 
    { 
     if (floatingPointString[index] == '.') 
      --index; 

     // Subtract ASCII '0' converts ASCII to integer. 

     currentValue = (double) floatingPointString[index] - '0'; 
     returnValue += (long) currentValue * pow (10.0, powerOfTen); 

     powerOfTen += 1.0; 
    } 

    if (floatingPointString[0] == '-') 
     returnValue *= -1; 

    return returnValue; 
} 
+0

सी पोस्ट के लिए सी ++ कोड के साथ उत्तर क्यों दें? सी – chux

+0

'4 + FLT_MANT_DIG - FLT_MIN_EXP' को पोर्टिंग की अनुशंसा करना बहुत छोटा है। देखें [टिप्पणी] (http://stackoverflow.com/questions/9644327/how-to-convert-floating-value-to-integer-with-exact-precision-like-123-3443-to-1#comment53280321_32674012) – chux

+0

'" \ %% अगर "अमान्य भागने अनुक्रम। – chux

0

एक float संख्या modff() का उपयोग कर f

float f=123.456; 

बनाया जा सकता है की पूर्णांक बराबर

float integral, fractional; 
char str[50], temp[20]; 
fractional = modff(f, &integral); 
अब

integral तरह पूर्णांक भाग (१२३.००००००) की तरह है और fractional आंशिक है भाग (0.456000 की तरह)।

तो फ्लोटिंग बिंदु संख्या (इस मामले में f) नकारात्मक रहे थे, दोनों integral और fractional नकारात्मक होगा।

आप

if(fractional<0) 
{ 
    fractional = -fractional; 
} 

उपाय करने ऐसा कर सकते हैं।

अब,

sprintf(temp, "%g", fractional); 

%g फॉर्मेट स्पेसिफायर अनुगामी शून्य निकाल देंगे और temp अब "0.456" होगा।

sprintf(str, "%g%s", integral, temp[1]=='.'?temp+2:""); 

temp[1]=='.'? किया जाता है क्योंकि अगर आंशिक हिस्सा 0 थे, वहाँ कोई दशमलव बिंदु गया would'v fractional0 के रूप में यह किया गया है जाएगा और नहीं 0.000000 प्रिंट करते समय। यदि temp में दूसरा अक्षर . नहीं है, fractional शून्य है और हमें इसके साथ परेशान करने की आवश्यकता नहीं है।

अब हमारे मामले में, str"123456" होगा। लेकिन यह एक स्ट्रिंग के रूप में है। हमें इसे एक पूर्णांक में बदलने की जरूरत है। इसके लिए strtol() का उपयोग करें।

long l=strtol(str, NULL, 10); 
if(l>INT_MAX || errno==ERANGE) 
{ 
    printf("\noverflow"); 
} 
else 
{ 
    printf("\n%d", strtol(str, NULL, 10)); 
} 

आप (errno.h से। जाँच करें कि क्या यह ERANGE है) strtol() के रिटर्न मान और errno की है कि जाँच कर सकते हैं अगर अतिप्रवाह हुआ देखने के लिए। यदि परिणामी मूल्य एक int में संग्रहित किया जा सकता

देखने के लिए, पहली बार एक long int में strtol() द्वारा दिए गए मान की दुकान और है कि यदि एक से अधिक INT_MAX है देखते हैं (यह limits.h में है)।

यह ध्यान दिया जाना चाहिए कि परिणाम की सटीकता सटीकता पर निर्भर करेगी जिसके साथ बाइनरी में फ़्लोटिंग पॉइंट नंबर का प्रतिनिधित्व किया जाता है।