2011-12-15 4 views
4

Возможный дубликат:
Float to binary in C++Точное бинарное представление двойной

У меня есть очень маленький двойной вар, и когда я печатаю это я -0. (используя C++). Теперь для того, чтобы получить более высокую точность, я попытался с помощью

cout.precision(18); \\i think 18 is the max precision i can get. 
cout.setf(ios::fixed,ios::floatfield); 
cout<<var;\\var is a double. 

, но он просто пишет -0,00000000000 ...

Я хочу, чтобы увидеть точное бинарное представление вар.

Другими словами, я хочу посмотреть, какое двоичное число записано в стеке/регистр стека для этого var.

+0

Вы могли бы просто использовать отладчик. – Bashwork

ответ

4
union myUnion { 
    double dValue; 
    uint64_t iValue; 
}; 

myUnion myValue; 
myValue.dValue=123.456; 
cout << myValue.iValue; 

Update:

версия выше будет работать для большинства целей, но она предполагает 64-разрядные двойников. Эта версия не делает никаких предположений и генерирует двоичное представление:

double someDouble=123.456; 
    unsigned char rawBytes[sizeof(double)]; 

    memcpy(rawBytes,&someDouble,sizeof(double)); 

    //The C++ standard does not guarantee 8-bit bytes 
    unsigned char startMask=1; 
    while (0!=static_cast<unsigned char>(startMask<<1)) { 
     startMask<<=1; 
    } 

    bool hasLeadBit=false; //set this to true if you want to see leading zeros 

    size_t byteIndex; 
    for (byteIndex=0;byteIndex<sizeof(double);++byteIndex) { 
     unsigned char bitMask=startMask; 
     while (0!=bitMask) { 
      if (0!=(bitMask&rawBytes[byteIndex])) { 
       std::cout<<"1"; 
       hasLeadBit=true; 
      } else if (hasLeadBit) { 
       std::cout<<"0"; 
      } 
      bitMask>>=1; 
     } 
    } 
    if (!hasLeadBit) { 
     std::cout<<"0"; 
    } 
1

Try:

printf("0x%08x\n", myFloat); 

Это должно работать для переменной с 32 битным, чтобы отобразить его в шестнадцатеричном формате. Я никогда не пытался использовать эту технику, чтобы увидеть переменную в 64 битах, но я думаю, что это:

printf("%016llx\n", myDouble); 

EDIT: протестировали 64-битную версию, и она, безусловно, работает на Win32 (я, кажется, припоминаю необходимость в верхнем регистре LL на НКУ .. возможно)

EDIT2: если вы действительно хотите двоичная, то лучше использовать один из других ответов, чтобы получить версию uint64_t от своего двойника, а затем цикл:

for (int i = 63; i >= 0; i--) 
{ 
    printf("%d", (myUint64 >> i) & 1); 
} 
+0

Благодарим вас за ответ. он не дает двоичного числа. для номера 2.0, который он пишет: 0x00000000 он должен поставить 10, нет? – user690936

+0

Я просто попробовал это на своем ПК, и он работал, как ожидалось. Этот код печатает в шестнадцатеричном формате, а не в двоичном формате. Кроме того, ваш комментарий предполагает, что вы не понимаете разницу между целым представлением 2 и версией с плавающей запятой. int со значением 2 имеет двоичное представление 10, но float полностью отличается – Hybrid

+0

Я знаю, что существует разница между целым представлением 2 и версией с плавающей запятой. , но мне все еще нужно двоичное представление. представление {0,1} – user690936

2

Этот способ гарантированно работает на стандартном d:

double d = -0.0; 
uint64_t u; 
memcpy(&u, &d, sizeof(d)); 
std::cout << std::hex << u; 
+1

Гарантированное предоставление 'sizeof (double) == sizeof (uint64_t)', конечно. И это довольно безопасная догадка, что это так. Также предоставлено 'uint64_t' в реализации, которое достаточно безопасно, но вы должны предоставить заголовок, который сам определяет его в более старых версиях MSVC. –

+0

благодарю за ответ, но это дает мне шестнадцатеричное представление, мне нужен двоичный файл. – user690936

+0

@ user690936: каждая шестнадцатеричная цифра представляет 4 бита, вероятно, лучше всего научиться читать гекс. Но вы можете написать цикл для печати 1 бит за раз как '0' /' 1', или вы можете использовать calc.exe (для Windows) для преобразования. –

Смежные вопросы