2015-05-30 4 views
4

Я пытаюсь создать double, добавив двоичные представления двух int s. Это то, что я сейчас:Создайте double путем добавления двоичных представлений двух ints

int i = arc4random(); 
*(&i+1) = arc4random(); 
double d = *(double*)&i; 

Я надеялся, что double указатель будет также использовать значение в &i+1 адрес, и это действительно так. Когда я печатаю двоичные представления i и *(&i+1) и сравниваю их с двоичным представлением d, d состоит из добавления *(&i+1) и i. Итак, *(&i+1) на первом месте ?! Почему это так?

EDIT: также ознакомьтесь с ответами Хуана Каталанца и Марка Сегала, чтобы узнать, как правильно делать то, что я сделал с помощью профсоюзов.

+5

НЕ СДЕЛАТЬ ЭТО! Вы вызываете неопределенное поведение, используя память, не выделенную для переменных. –

+0

[Двоичные операции в парном разряде в C] (http://stackoverflow.com/q/20458125). Также имейте в виду, что с помощью этой схемы вы можете создать «NaN». –

+0

Если вам действительно нужно создать NaN, 'strtod (« NaN »)'. 'strtod (" inf ")' тоже полезен. –

ответ

1

При печати двоичных представлений I и * (& я + 1) и сравнить их к двоичному представлению D, D состоит путем добавления * (& г + 1), и я. Итак * (& i + 1) на первом месте! Почему это так?

Фактическое упорядочение байтов зависит от «Endian-ness» базовой аппаратной архитектуры.

с маленькой архитектуры Endian:

1) the lowest address byte contains the least significant 8 bits of the total variable 
2) the highest address byte contains the most significant 8 bits of the total variable. 
4

Вместо этого используйте union. Вы все еще можете генерировать NaN, но не будут иметь проблем с управлением памятью.

Это целая цель union, разделить блок памяти между несколькими различными типами.

Убедитесь в вашей архитектуре sizeof(double) равно дважды sizeof(int)

2

Вы можете использовать либо союз, как это:

typedef union { 
    double d; 
    struct { 
     int a; 
     int b; 
    } integers; 
} double_generator; 

int main(void) { 
    double_generator g; 
    g.integers.a = arc4random(); 
    g.integers.b = arc4random(); 

    // g.d is now a "randomly generated double" 

    return 0; 
} 

Или «вручную», возможно, ненадежно, сделать работу самостоятельно:

int main(void) { 
    double d; 
    *((int *)&d) = arc4random(); 
    *(((int *)&d) + 1) = arc4random(); 
    printf("%f", d); 
    return 0; 
} 

В обоих случаях, вы просто решить ту же память, как если бы он был int или double , Это может генерировать все возможные значения double, включая NaN или Infinity.

Однако этот код предполагает, что sizeof(double) является (не менее) дважды sizeof(int). Если это не так, вы должны ввести другой код для его обработки.

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

  • Нет связанных вопросов^_^