Инициализация массива с плавающей точкой с помощью memset - PullRequest
10 голосов
/ 24 июня 2009

Это код, который я хочу попробовать написать:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

int main(int argc, char *argv[])
{
    float arry[3] = {0};

    memset(arry, (int) 10.0, 3*sizeof(float));

    return 0;
}

Моя проблема в том, что я хочу посмотреть, возможно ли использовать memset, чтобы каждая запись массива была числом, отличным от 0. Однако после перехода по этой строке содержимое массива меняется на очень маленькое число ( 0). Интересно, что я делаю не так в этом случае с использованием функции memset (). Я надеюсь, что это не дублирующее сообщение, поскольку ни один из предложенных связанных вопросов, поскольку я печатаю это, кажется, не является.

Ответы [ 5 ]

15 голосов
/ 24 июня 2009

Memset принимает целое число, но преобразует его в беззнаковый символ, а затем заполняет каждый байт с плавающей запятой (sizeof (float), вероятно, 4) с этим битовым шаблоном. Если это c ++, вместо заполните вместо:

#include <algorithm>
using namespace std;

//...

fill (arry,arry+3,10.0);
10 голосов
/ 24 июня 2009

При преобразовании типа double к int просто создается двоичное число 00001010 (10 в двоичном виде), и это значение, заданное в memset'е. Поскольку это символ, каждый из ваших поплавков фактически получает битовую комбинацию 00001010 00001010 00001010 00001010.

8 голосов
/ 24 июня 2009

Нет. memset берет один байт и записывает его в массив. Число с плавающей запятой является многобайтовым типом.

РЕДАКТИРОВАТЬ: Да, я знаю, что memset принимает Int. Но для заполнения используется только неподписанный символ (один байт).

4 голосов
/ 25 июня 2009

Почему бы не просто for цикл?

3 голосов
/ 24 июня 2009

На самом деле ваша попытка немного вводит в заблуждение, memset работает на байтах ... на самом деле использование значения с плавающей запятой для значения memset не имеет никакого смысла!

Формат с плавающей запятой имеет только 23 + 1 бит для мантиссы и 8 бит для экспоненты. Когда вы записываете необработанные байтовые значения (используя memset) внутри плавающей запятой, вы не знаете, что получаете, потому что вы устанавливаете значения, которые будут быть интерпретированным по-другому!

В вашем фрагменте вы также приводите его к (int), превращая 4-байтовое число с плавающей запятой, содержащее 10,0f, в 4-байтовое целое число, содержащее значение 10 ... но, как уже было сказано, если вы устанавливаете значение с плавающей запятой с 10 (= 0x0a) в итоге вы получите 0x0A0A0A0A, который не равен 10.0f в формате с плавающей запятой, это может быть любое значение (также очень близкое к 0, как в вашем случае).

На самом деле memset полезно, когда вы хотите инициализировать массив символов (поскольку вы эффективно получаете это значение для каждого символа, потому что они имеют длину 1 байт) или когда вы хотите установить все в 0 (NULL), который работает для всех основных типов данных ..

...