0
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <crtdbg.h>

int main(void)
{
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF |_CRTDBG_LEAK_CHECK_DF);
    int request = 0;
    printf("How many powers of two? ");
    scanf("%d", &request);
    float* p_array = 0;

    p_array = malloc(sizeof(float)*request);

    for (int k = 0; k < request; ++k)
    {
        p_array[k] = (powf(2, k));
    }
    
    for (int k = 0; k < request; ++k)
    {
        printf("%f\n", p_array[k]);
    }

    free(p_array);
    p_array = 0;

    return 0;
}

This is an exercise I've been stuck on for a while and am not sure how to approach, I keep getting this error for line 20 - source.c(20):

Warning C4244: 'function': conversion from 'int' to 'float', possible loss of data.

This is p_array[k] = (powf(2, k));.

I have no clue how to fix this.

Any help would be greatly appreciated.

GSerg
  • 76,472
  • 17
  • 159
  • 346
  • 1
    Both arguments to the [`powf`](https://en.cppreference.com/w/c/numeric/math/pow) function should be `float`. You're passing `int`. Try casting `k` to a `float` in the call, to make the conversion explicit rather than implicit. – Some programmer dude Oct 16 '20 at 08:43
  • 2
    Does this answer your question? [int to float conversion produces a warning?](https://stackoverflow.com/questions/7775129/int-to-float-conversion-produces-a-warning) – GSerg Oct 16 '20 at 08:45
  • Since `k` is an integer, the result of two to the power of `k` will *always* be an integer. Why are you using `float` as data type for the results? Also, if `request` is limited to be between `0` and `63` then you can use `unsigned long long` as the type and use bit-shifting to get the result. And by the way, you don't need the array to store results, you can print the result directly in the loop where you calculate the value. – Some programmer dude Oct 16 '20 at 09:11

2 Answers2

2

The warning is given because (in theory, at least) an int data type can hold more significant digits (typically, up to 10 for a 32-bit integer) than can be represented by a float data type (typically only around 7 or 8).

The implicit conversion in your code is in the second argument to powf: your integer k index will be converted to a float, as is required.

You can silence the warning simply by adding an explicit cast to the k argument (it is also good practice to clearly mark the first argument as a float constant, as well):

    p_array[k] = (powf(2.0f, (float)(k)));
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • It worked, thanks! I was using a type cast for the power lol. – UltraInstinctMessi Oct 16 '20 at 08:47
  • 2
    Because we're talking about powers of 2, we're effectively setting the exponent of a float. The exponent range of IEEE single-precision floating pointers numbers (what your machine probably uses for `float`) is -126..+127, which is well within the range that floats can represent without error. So the warning is spurious (and thus can be ignored or silenced) for reasonable inputs. This does suggest that you could check that the input is reasonable... – ikegami Oct 16 '20 at 08:57
  • @ikegami Yes - your modified comment make far more sense, but I wouldn't call the warning "spurious" - you can't expect the compiler to know *everything* about how you are using your code; all it sees is an `int` variable being used where a `float` argument is expected. – Adrian Mole Oct 16 '20 at 09:06
  • I didn't say it was *always* spurious and can *always* be ignored; I said it was spurious and can be ignored *in this situation* ("for reasonable inputs" were my exact words, which I established was integers in the range -126..+127). – ikegami Oct 16 '20 at 09:10
0

Note that powf() expects two float values, while you are passing 2 and k, which are both integers. Try out powf(2.f, (float)k).

Beltway
  • 508
  • 4
  • 17
  • 2
    The cast just silences the warning rather than address it. This is acceptable in this situation, but you should explain why that is. – ikegami Oct 16 '20 at 08:52