एक डबल में एकाधिक स्याही एनकोड करें

मैं एक डबल में स्याही की एक जोड़ी को एन्कोड करना चाहता हूं। उदाहरण के लिए कहें कि मैं एक समारोह पास करना चाहता था:

foo(int a, int b)

लेकिन इसके बजाय मैं दो इंट्स (यानी) का प्रतिनिधित्व करने के लिए केवल एक डबल चाहता हूं:

foo(double aAndB)

वर्तमान में मैं इसे दशमलव स्थान के दोनों तरफ एक इंट कर रहा हूं (यानी 10 और 15 10.15 बन जाएगा) और फिर इसे स्ट्रिंगस्ट्रीम टोकनिंग और दो नंबरों को निकालने के लिए परिवर्तित कर रहा है।

हालांकि, जब यह 10 और 10 की संख्या की बात आती है तो यह एक स्पष्ट दोष है यानी यह 10.1 हो जाता है।

क्या कुछ मुश्किल गणितीय पद्धति के माध्यम से ऐसा करने का कोई तरीका है ताकि मैं एक समारोह को दो इंच का प्रतिनिधित्व कर सकूं?

धन्यवाद।

0
जोड़ा
विचारों: 1
@ बेन: यह दिलचस्प नहीं है। यह सिर्फ बिट्स और कुछ पॉइंटर हेरफेर की संख्या का सवाल है। या आप एक संघ का उपयोग करते हैं। यदि आपको ऐसा करने की ज़रूरत है तो यह केवल खराब डिज़ाइन है।
जोड़ा लेखक Tobias Langner, स्रोत
आप इसके साथ क्या हासिल करने की कोशिश कर रहे हैं। चूंकि आपके पास एन्कोडिंग के साथ टैग किया गया प्रश्न है, इसलिए मुझे लगता है कि आप दो बिंदुओं को वापस पाने के लिए डबल को डीकोड करना चाहते हैं। इस मामले में क्या आप एन्कोडिंग बेकार होना चाहते हैं?
जोड़ा लेखक Vikas, स्रोत
10.1 के साथ क्या गलत है? मेरा मतलब है कि अगर आप इसे लिखना चाहते हैं, तो आप 10.10 भी नहीं लिखेंगे अगर किसी ने आपको 10 और सौ लिखने के लिए कहा था ...
जोड़ा लेखक RedX, स्रोत
फिर सवाल यह है कि आप int (10) .int (1) और int (10) .int (10) और int (10) के बीच अंतर कैसे करते हैं .int (100) और int (10) .int (001) ? पूछने का एक और तरीका यह है कि दशमलव स्थान की न्यूनतम संख्या क्या हो सकती है?
जोड़ा लेखक RedX, स्रोत
@ वीकास दोनों के लिए हाँ
जोड़ा लेखक Fantastic Mr Fox, स्रोत
मैं चींटियों को डबल की बाइनरी में एन्कोड करके इसे करने की कोशिश कर रहा था
जोड़ा लेखक Fantastic Mr Fox, स्रोत
@RedX लेकिन मैं अपने फ़ंक्शन के लिए एक डबल लेने में सक्षम होने के लिए आईडी चाहता हूं और इसे अपने मूल 2 इन्स पर वापस विभाजित कर सकता हूं। अगर मुझे 10 के बजाय 1 मिलता है तो प्रोग्राम काम नहीं करेगा।
जोड़ा लेखक Fantastic Mr Fox, स्रोत
@ पाओलो 1. यह एक दिलचस्प सवाल है। 2. क्योंकि मेरे पास फैक्ट्री विधि के साथ एक सारणीबद्ध प्रकार है जो केवल युगल लेता है और मुझे 2 इंट्स पास करने की आवश्यकता होती है
जोड़ा लेखक Fantastic Mr Fox, स्रोत
@TobiasLangner यह आपकी राय है, मैं बस यह देखने के लिए कुछ ब्याज की कोशिश कर रहा हूं कि यह किया जा सकता है या नहीं। इतनी नकारात्मकता क्यों?
जोड़ा लेखक Fantastic Mr Fox, स्रोत
उन सभी लोगों के लिए जिन्होंने इस विधि पर हावी होने की कोशिश की, मैं पहले से ही इस तरह से लागू कर रहा था, मैं केवल यह देखना चाहता था कि इस तरह का टिंग वास्तव में संभव था या नहीं। सबकुछ इतनी तेजी से पू-पू को न करने का प्रयास करें। एक और नोट के रूप में, आप सभी को धन्यवाद जिन्होंने उत्तर दिया।
जोड़ा लेखक Fantastic Mr Fox, स्रोत
आप यहां 0 और 1 भी पास नहीं कर सकते क्योंकि 0.1 बिल्कुल सटीक नहीं है।
जोड़ा लेखक David Heffernan, स्रोत
और तुम ऐसा क्यों करोगे?
जोड़ा लेखक Paolo Brandoli, स्रोत

6 उत्तर

चूंकि (आमतौर पर) डबल में 64 बिट्स होते हैं और प्रत्येक int में 32 बिट्स होते हैं, तो आपको लगता है कि आप बिट्स को सीधे डबल में स्टोर कर सकते हैं, उदा .:

int32_t i1 = rand();
int32_t i2 = rand();
int64_t x = (((int64_t)i1)<<32) | ((int64_t)i2);
double theDouble;
memcpy(&theDouble, &x, sizeof(theDouble));

... और वह "लगभग काम करता है" कर रहा है। यही है, यह i1 और i2 के कई संभावित मानों के लिए ठीक काम करता है - लेकिन उन सभी के लिए नहीं। विशेष रूप से, आईईईई 754 फ्लोटिंग पॉइंट प्रारूप के लिए, कोई भी मान जहां एक्सपोनेंट बिट्स को 0x7ff पर सेट किया गया है, को "NaN" इंगित करने के रूप में माना जाएगा, और फ़्लोटिंग पॉइंट हार्डवेयर अलग-अलग NaN- समकक्ष बिट-पैटर्न को इसके पसंदीदा में परिवर्तित कर सकता है (और करता है) एक तर्क के रूप में डबल गुजरते समय NaN बिट-पैटर्न इत्यादि।

इस वजह से, दो 32-बिट पूर्णांक को दोहरे में भरना अधिकांश मामलों में काम करने लगता है, लेकिन यदि आप इसे सभी संभावित इनपुट मानों के साथ परीक्षण करते हैं तो आपको कुछ ऐसे मामले मिलेंगे जहां मूल्यों को अप्रत्याशित रूप से डबल के अंदर उनके प्रवास के दौरान परिवर्तित किया जाता है, और जब आप उन्हें दोबारा डीकोड करते हैं तो अलग-अलग मूल्यों के रूप में बाहर आते हैं।

बेशक, आप केवल डबल के मंटिसा बिट्स को सेट करने के लिए सावधान रहकर इसे प्राप्त कर सकते हैं, लेकिन यह आपको केवल 26 बिट्स प्रति पूर्णांक देगा, इसलिए आप केवल +/- 33,554,432 के पूर्णांक मानों को स्टोर करने में सक्षम होंगे। हो सकता है कि यह ठीक है, आपके उपयोग के मामले के आधार पर।

मेरी सलाह है कि आप जो भी करने की कोशिश कर रहे हैं, उसे करने का एक अलग तरीका ढूंढें। एक फ्लोटिंग पॉइंट वेरिएबल में गैर-फ़्लोटिंग-पॉइंट डेटा संग्रहीत करना परेशानी के लिए पूछ रहा है, खासकर यदि आप चाहते हैं कि आपका कोड सभी पोर्टेबल पर हो।

5
जोड़ा

यदि आप भाग्यशाली हैं और एक आधा डबल है तो आप इस तरह की चींटियों को स्टोर कर सकते हैं:

int a = 10;
int b = 20;
double d;

*(int *)&d = a;
*((int *)&d + 1) = b;

int outa = *((int *)&d);
int outb = *(((int *)&d) + 1);
printf("%d %d\n", outa, outb);

यह आम तौर पर/पोर्टेबिलिटी काम नहीं करता है। यदि एक डबल और int के पास बिट्स की एक ही संख्या है जो आप चाहते हैं असंभव है।

4
जोड़ा
यह 32 बिट पर काम करेगा - शायद सबसे अधिक। लेकिन उपयोगकर्ता 8550 9 के रूप में यह पोर्टेबल नहीं है। लेकिन यहां तक ​​कि यदि आप स्वयं को 32 बिट पूर्णांक प्रकारों तक सीमित करते हैं (यहां कुछ शीर्षलेख हैं जिनके पास है) - यदि आपको ऐसा करने की आवश्यकता है तो यह खराब डिज़ाइन के लिए एक संकेत है।
जोड़ा लेखक Tobias Langner, स्रोत

A double can exactly represent an integer up to 53 bits. If you want to hold a 26-bit and a 27-bit integer, it's very easy: double combined = bits27*67108864.0 + bits26;

ध्यान दें कि 67108864 2 ^ 26 है।

3
जोड़ा

इस तरह के एक संघ को परिभाषित करने का प्रयास करें:

struct two_int {
    int a;
    int b;
};

union encoding {
    struct two_int a;
    double c;
};

लेकिन ऐसा करने से पोर्टेबिलिटी के साथ समस्या हो सकती है। डबल चेक कृपया अपने मामले के लिए उपयुक्त इस दृष्टिकोण को गीला करें।

1
जोड़ा

आप इसे बाइनरी मास्क का उपयोग करके और "डबल" से जानकारी निकालने के द्वारा कर सकते हैं।

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

double encode(int a, int b)
{
    double d = 0;
    d = d | a; 
    d = d | (b << 8);
    return d;
}

double decode(double d)
{
    a = d & 0xFF;
    b = (d >> 8) & 0xFF;
}

भाग एन्कोड में, डबल वैरिएबल डी के निचले 8 बिट्स में होगा, बी डी के उच्च 8 बिट्स में होगा।

1
जोड़ा

यदि आप हमेशा इस पैरामीटर में दो इंट्स गुजर रहे हैं तो इसे डबल पास करने का कोई मतलब नहीं है। इसके बजाय या तो दो स्याही अलग-अलग चींटियों के रूप में पास करें, या उन्हें एक संरचना में लपेटें।

जिस तरह से आप इसे कर रहे हैं, आपको एक वास्तविक डबल और दो चींटियों के बीच अंतर का पता लगाने का कोई मौका नहीं मिलता है। और इसलिए मैंने निष्कर्ष निकाला है कि ऊपर वर्णित करने के द्वारा आप कोई कार्यक्षमता खो देंगे।

0
जोड़ा
अगर उसके पास फैक्ट्री इंटरफ़ेस पर नियंत्रण है तो उसे यह करना चाहिए।
जोड़ा लेखक RedX, स्रोत
यह सवाल का जवाब नहीं है। सलाह के लिए धन्यवाद लेकिन मैं अभी इस तरह से कुछ करने की कोशिश कर रहा हूं।
जोड़ा लेखक Fantastic Mr Fox, स्रोत
असल में यह न तो, यदि आप इस प्रश्न के तहत टिप्पणी पढ़ते हैं, तो मैंने इसे एक और तरीके से लागू किया है और मेरे पास हमेशा विकल्प था। मैं जानना चाहता था कि यह संभव था। मेरी माफ़ी है लेकिन आपका जवाब इस सवाल का जवाब नहीं है कि यह सिर्फ एक टिप्पणी है।
जोड़ा लेखक Fantastic Mr Fox, स्रोत
@ बेन यह वह जवाब नहीं हो सकता है जिसे आप सुनना चाहते हैं लेकिन शायद यह आपकी समस्या का समाधान है
जोड़ा लेखक David Heffernan, स्रोत