13

How can one typecast an array of int to an array of float? Thanks.

6 Answers 6

25
#include <algorithm>
#include <iostream>

#define N 50

int main() {
    int intArray[N] = { ... };
    float floatArray[N];
    std::copy(intArray, intArray + N, floatArray);
    std::cout
        << std::boolalpha << std::equal(intArray, intArray + N, floatArray)
        << std::endl;
    return 0;
}
Sign up to request clarification or add additional context in comments.

2 Comments

why define N instead of just int N = 50; ?
Its mostly stylistic anymore. #define is a preprocessor command which defines a value at compile time, all occurrences of which are replaced with literals of the value. It also avoids creating a variable, which can have numerous benefits in more complex programs. Another explanation is here: stackoverflow.com/questions/6004963/…
12

If you have an array of ints, what you basically have is a block of N ints stored contiguously in memory. An array of floats, however, would be N floats stored contiguously in memory, i.e. an entirely different sequence of bits in memory. Additionally, floating point values are represented in binary in an entirely different way than integral values. In fact, you can't even be sure that an int is the same size as a float.

So therefore, you either have to cast each int to a float separately as you process the array, or else create an entirely different array by copying the original array.

For example, you could simply convert each int to a float lazily as you process the array:

int array[100];
// ... fill array with some values

for (int i = 0; i < 100; ++i)
{
  float f = array[i]; // implicit conversion here 
  // now do something with this float
}

1 Comment

Or you could use std::copy and let that implicitly cast for you when it does assignment.
5

If you use vectors instead of arrays you can then use the iterator in the constructor of the vector to do the copy.

std::vector<int> vi;
vi.push_back(1);
vi.push_back(2);
vi.push_back(3);

std::vector<float> vf(vi.begin(), vi.end());
assert(vf.size() == 3);

If you have as input an array, but you can have as output a vector, you could also do this:

int ai[] = {1,2,3};
std::vector<float> vf(ai, ai+3);
assert(vf.size() == 3);

If you need as input and output an array, you can use std::copy, but just make sure your output array is big enough:

int ai[] = {1,2,3};
float af[] = {0, 0, 0};
std::copy(ai, ai+3, af);

Note: std::copy, and the vector constructor will not blindly copy the memory, it will implicitly cast between the 2 types for each element. It performs the assignments *result = *first, *(result + 1) = *(first + 1), and so on...

Comments

3

IMO, Use tranform and convert int vector to float vector.

float convert (int i) { return static_cast<float>(i); }

int main () {
  int first[10];
  float second[10];
    // set some values:
  for (int i=0; i<10; i++) 
      first[i] =  (i*10); 

  transform (first, first + 10, second, convert);

  return 0;
}

2 Comments

The implicit casting that std::copy will do here is sufficient; std::transform works but is unnecessary.
The static_cast is also unnecessary.
1

You cannot.

You will have to create another array, and manually copy elements with a loop.

In C++, compiler typically does not put in loops in resulting binary without having you explicitly see that in your code.

Comments

1

With c++17 and std::array (or any similar class) this problem can be solved generically.

template <typename Y, typename X, std::size_t N, template <typename, std::size_t> typename A, std::size_t... Is>
constexpr A<Y, N> elements_cast(const A<X, N> &a, std::index_sequence<Is...>) {
    return {std::get<Is>(a)...};
}

template <typename Y, typename X, std::size_t N, template <typename, std::size_t> typename A, typename Indices = std::make_index_sequence<N>>
constexpr A<Y, N> elements_cast(const A<X, N> &a) {
    return elements_cast<Y>(a, Indices{});
}

One would use elements_cast like this:

std::array<int, 5> array_of_ints;
auto array_of_floats = elements_cast<float>(array_of_ints);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.