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 floatfloat,intint et doubledouble.
Vous êtes destiné pour comportement non défini lorsque le type source ne correspond pas à la destination tapez, comme copier à partir de longchar ou floatdouble. 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); });