C++ memcpy de double tableau de float array
c'Est possible de faire memcpy à partir d'un tableau double pour un float array en toute sécurité?
5 réponses
Dépend de ce que vous voulez. Les valeurs ne seront certainement pas préservées. Si vous avez besoin, utilisez std::copy
.
#include <algorithm>
int main()
{
double a[] = {1.618, 3.1416, 2.7, 0.707, 1.0};
float b[5];
std::copy(a, a + 5, b);
}
le problème est qu'il n'y a aucune garantie que la représentation binaire d'un double
est la représentation équivalente d'un float
. Afin d'utiliser memcpy
pour les types à plusieurs octets, la représentation sous-jacente doit être la même (même disposition). Vous pouvez copier float
float
,int
int
et double
double
.
Vous êtes destiné pour comportement non défini lorsque le type source ne correspond pas à la destination tapez, comme copier à partir de long
char
ou float
double
. memcpy
la fonction ne fait aucune conversion ou n'exécute aucune promotion. Il copie seulement.
comme beaucoup d'autres ont répondu, en utilisant memcpy
ne fonctionne pas puisque les deux types sont (généralement) de taille différente. Pour en savoir plus http://en.cppreference.com/w/cpp/language/types, ou plus précisément:
virgule Flottante types
float - à point flottant de précision simple. Généralement la norme IEEE-754 32 bits à virgule flottante de type
double - double précision type à virgule flottante. Généralement la norme IEEE-754 64 bits à virgule flottante de type
long double - de précision étendue à virgule flottante. Ne correspond pas nécessairement aux types prescrits par IEEE-754. Habituellement le type à virgule flottante x87 de 80 bits sur les architectures x86 et x86-64.
en utilisant std::copy
vous donnera un avertissement de compilateur (au moins pour moi sur le compilateur VS2015/VS2017) puisque le compilateur ne permet pas la perte implicite de précision de la double à flotter via std::copy, sans avertissement, le développeur à ce sujet. Et si vous avez l' treat warnings as errors
indicateur est défini, vous obtiendrez une erreur de compilation.
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xutility(2316): error C2220: warning treated as error - no 'object' file generated
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xutility(2335): note: see reference to function template instantiation '_OutIt std::_Copy_unchecked1<_InIt,_OutIt>(_InIt,_InIt,_OutIt,std::_General_ptr_iterator_tag)' being compiled
1> with
1> [
1> _OutIt=float *,
1> _InIt=double *
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xutility(2354): note: see reference to function template instantiation '_OutIt *std::_Copy_unchecked<_InIt,float*>(_InIt,_InIt,_OutIt)' being compiled
1> with
1> [
1> _OutIt=float *,
1> _InIt=double *
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xutility(2364): note: see reference to function template instantiation '_OutIt std::_Copy_no_deprecate1<double*,_OutIt>(_InIt,_InIt,_OutIt,std::random_access_iterator_tag,std::random_access_iterator_tag)' being compiled
1> with
1> [
1> _OutIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<float>>>,
1> _InIt=double *
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xutility(2373): note: see reference to function template instantiation '_OutIt std::_Copy_no_deprecate<_InIt,_OutIt>(_InIt,_InIt,_OutIt)' being compiled
1> with
1> [
1> _OutIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<float>>>,
1> _InIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<double>>>
1> ]
1>test.cpp(153): note: see reference to function template instantiation '_OutIt std::copy<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<double>>>,std::_Vector_iterator<std::_Vector_val<std::_Simple_types<float>>>>(_InIt,_InIt,_OutIt)' being compiled
1> with
1> [
1> _OutIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<float>>>,
1> _InIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<double>>>
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xutility(2316): warning C4244: '=': conversion from 'double' to 'float', possible loss of data
a la place, je recommande d'utiliser le std::transform
fonction, combinée avec un lamda exécutant le moulage spécifique. Cela montre aussi plus clairement qu'une perte de précision explicite est effectivement en cours.
std::vector<double> doubles = { 5.0, 10.0, 242.130, 42.0 };
std::vector<float> floats(doubles.size());
std::transform(std::begin(doubles), std::end(doubles), std::begin(floats), [&](const double& value) { return static_cast<float>(value); });