JShade01
JShade01

Reputation: 153

Why doesn't my program work with float variables, but it does with int variables?

I am trying to program a method that determines if a given number is an armstrong number. An armstrong number can be found by the steps below:

  1. Take base digits ie 456 => 4, 5, 6
  2. Power to the number of digits ie 456 has 3 digits, so pow = 3
  3. Power each base by the pow ie 4^3, 5^3, 6^3
  4. Total all sums ie 64 + 125 + 216 = 405
  5. If sum equals original number, is armstrong ie 405 != 456, so not armstrong.

    int armstrong(float number){
    
      if(number < 1){
        return 0;
    }
    else{
        float *pointer = malloc(sizeof (float)), *temp;
        if(pointer == NULL){
            printf("Error allocating memory: math::armstrong.\nReturn value 0.");
            return 0;
        }
        else{
            int temp_boolean = 1, index = 0;
            float sum = 0, original_number = number;
    
            while(temp_boolean == 1){
                if(number / 10 == 0){
                    temp_boolean = 0;
                }
                else{
                    temp = realloc(pointer, ((sizeof pointer / sizeof (float)) + 1) * sizeof (float));
                    pointer = temp;
                }
                pointer[index] = fmod(number, 10.0);
                //pointer[index] = number % 10;
                number /= 10;               
                ++index;
            }
            int i;
            for(i = 0; i < index; ++i){
                float temp_e = pointer[i];
                sum += pow(temp_e, index);
            }
            free(pointer);
            if(sum == original_number){
                return 1;
            }
            else{
                return 0;
            }
        }       
    }
    

    }

My program returns 1 if given number is an armstrong number or 0 if it is not. Now, this works fine when i have the variables and params as an int, but i want to be able to recieve bigger numbers, which is why my code has variables in float. But for some reason, it is not giving any output. It compiles fine with gcc with the -Wall option, so i don't know what im doing wrong.

I'm using notepad++ to write my program, and gcc to compile.

Upvotes: 1

Views: 1476

Answers (2)

DevSolar
DevSolar

Reputation: 70213

Using float because you "want to store bigger numbers" is a bad idea. float has only ~6 digits of precision, so once you start storing millions, you're losing precision in the ones already. The double type, which is the "default" floating point size anyway, has ~15 digits of precision, but still its not the solution if you want to handle "really big integer numbers".

There are plenty of bignum libraries out there, gmplib being among them.

Other libraries sometimes include bignum support for their own purposes which you could also use, like the BN_ functions of OpenSSL. Just be on the lookout, and resist the temptation of reinventing the wheel -- bignum implementations are easy to find, and quite mature.

Aside from that, I see sum == original_number in your code -- since floating point numbers are not precise, checking them for equality is not a good idea either. (GCC's -Wfloat-equal can warn you of this, I suggest you add it to your list of enabled warnings.)

Upvotes: 3

Peter
Peter

Reputation: 36597

Variables of type float support a larger range of values but achieve this by not representing every possible value in a range. For example, assuming a float is of size 32 bits and an int is 32 bits, there are some integral values that an int can represent but a float cannot.

Your code relies on an assumption, made by you, that a float can represent every integral value. In cases where that assumption is incorrect - which will at least some larger integral values - your function will malfunction.

If you want your function to work for large values, try finding a way to represent larger integral values(in the sense of exceeding the range a built in type can represent). There are many options for doing this, but one way is to pass an array of char, where every element in the array represents an integral digit (say, 0-9). The trade-off with that is that you will need to simulate all operations you use (division, modulo, summation, multiplying by a power of ten, etc) on your chosen representation.

Upvotes: 4

Related Questions