# Type casting

Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 08-18-2005
Lionmane
Type casting
I have a prime number calculator program that uses type casting. The type casting occurs in my "prime_calculator" function, under "Discard remaining composite numbers".

If I run it without type casting it, I get an error msg "conversion from double to unsigned long; possible loss of data".

I was just wondering where/what is the "double"?

mw

Code:

```#include<stdio.h> #include<stdlib.h> #include<math.h> #include<malloc.h> /* This program calculates prime numbers using the Eratosthenes Sieve algorithm.  It will find the prime numbers between 2 & "max".  It overwrites the prime numbers to the file "prime_numbers.txt" in the same folder. Definitions: 1) Prime Number: a number with only 2 divisibles (itself & 1); the number "1" is not considered a prime number in this program 2) Composite Number: a number with more than 2 divisibles Variable key: discard = this is used to calculate composite numbers count = a variable I use to count with prime[max] = a pointer array that stores all of the numbers in the "max" range max = the maximum range of prime numbers to calculate highest = input from the user that is passed to "max" An in-depth explanation of the Eratosthenes Sieve can be found on the internet. */ //prototypes void start (void); void prime_calculator (unsigned long max); int main (void) {         start ();         return 0; } void start (void) {         unsigned long highest;         do         {                 //input from user                 printf ("\nType '0' to quit.");                 printf ("\n\nPlease specify a max range to calculate prime numbers (up to 9000011).\n");                 scanf ("%d", &highest);                 //check input from user                 if (highest < 0 || highest == 1 || highest > 9000011)                 {                         printf ("\n(Setting max range to 100)\n\n");                         highest = 100;                 }                                 //if user doesn't enter zero, call prime_calculator                 if (highest != 0)                 {                         prime_calculator (highest);                 }         } while (highest != 0); }        void prime_calculator (unsigned long max) {                 unsigned long discard;         unsigned long count;         //Open & overwrite file for output         FILE *fp = fopen ("prime_numbers.txt", "w");         //Initialize the array         int *prime = malloc ((max+1)*sizeof(*prime));         if (!prime)         {                 puts ("\n\nERROR! Not enough Memory!\n\n");                 exit (1);         }         //initialize prime[max]         for (count = 0; count <= max; count++)         {                 prime[count] = 1;         }         count = 0;         printf ("\nFinished initializing array.");         //Discard even composite numbers         for (discard = 4; discard <= max; discard = discard + 2)         {                 prime[discard] = 0;         }         discard = 0;         printf ("\n\nFinished even discards.");         //Discard remaining composite numbers         count = 3;         do         {                 for (discard = (int) pow(count,2); discard <= max; discard = discard + count * 2)                 {                         if (prime[discard] > 0)                         {                                 prime[discard] = 0;                         }                 }                 count++;         } while (pow(count,2) <= max);         count = 0;         discard = 0;         printf ("\n\nFinished all other discards.");         //Output         printf ("\n\nPrime Numbers between 2 and %d...\n", max);         for (count = 2; count <= max; count++)         {                 if (prime[count] == 1)                 {                         printf ("%d ", count);                         fprintf (fp,"\t%d", count);                 }         }         count = 0;         fclose (fp);         free (prime);         printf ("\n\n"); }```
• 08-18-2005
cboard_member
I'm ........ at math, but I'll give it my best shot - someone please correct me ;)

discard is long, and you're casting the return value of pow to and int (the same effect as abs()?). This would cause the loss of everything after the decimal place?

Always willing to learn :)

I think the double occurs when you pow count?
• 08-18-2005
quzah
Just pay attention to the return values of the functions you use. pow's man page

Quzah.
• 08-18-2005
Lionmane
I hope I'm not using decimals in prime number calculations... :-)

Ok, I changed the type casting to (unsigned long) and still don't get any errors. I guess what I'm really wondering is why do I have to type cast at all?

'count' is already declared as an unsigned long so it seems redundant to have to type cast it as the same data type when I take it to a power...

mw
• 08-18-2005
Lionmane
Oh, I get it! The 'pow' function assumes a double data type. I would need to use 'powl' to get a long double data type (which I guess is as close as I'll get).

My program will calculate prime numbers up to 9000011 (which is near the limit of my computer). Why was I able to type cast the 'pow' function as an 'int' and still get accurate calculations? I didn't verify all 900011 of the prime numbers, but I randomly verified the high-level numbers and they seemed to be correct.

C is quite a bit too fast and loose for me... :-(

mw
• 08-18-2005
quzah
Casting a floating point number to an integeral type will truncate anything past the decimal place, assuming the rest of the number is in range to fit in the integeral type.

Quzah.
• 08-18-2005
Lionmane
Ok, I understand the concept of truncation, but I thought 'unsigned long' has a range of 0 to 4,294,967,295. I chose this data type because I wanted integer numbers that were greater than zero (ie: no decimals and no negative numbers).

What am I missing? And why does using an 'int' data type give me correct calculations when it SHOULD be truncating? I just noticed that my pointer array is an 'int'?! An 'int' pointer array that has over 9 million elements should have some kind of truncation, right?

mw

PS: Why are you guys mentioning "everything past the decimal"? I'm not using decimals at all... ('powf' is a floating point, but that's not in my program)
• 08-18-2005
quzah
Quote:

Originally Posted by Lionmane
PS: Why are you guys mentioning "everything past the decimal"? I'm not using decimals at all... ('powf' is a floating point, but that's not in my program)

No one said anything about powf. We've already told you more than once, and even provided a link. You still aren't paying attention:

pow returns a double And you most definately are using that in your program:
Code:

```do         {                 for (discard = (int) pow(count,2); discard <= max; discard = discard + count * 2)                 {                         if (prime[discard] > 0)                         {                                 prime[discard] = 0;                         }                 }                 count++;         } while (pow(count,2) <= max);```

Quzah.
• 08-18-2005
Lionmane
Ok, I can understand that.

That still doesn't answer why I can declare '*prime' as an int and have over 9 million elements without any problems. Or why I can typecast 'pow' as an int (using calculations in the millions) without any data loss.

The problem I'm having is not that I'm getting errors; it's that I'm NOT getting errors when I think I should be.

mw
• 08-18-2005
quzah
Quote:

That still doesn't answer why I can declare '*prime' as an int and have over 9 million elements without any problems.
If malloc doesn't fail, then it has allocated the space you've requested. If it fails, it hasn't. If it hasn't, and you've requested a huge amount of space, it simply means you either have enough ram, or enough swap space, or a combination of both, for the allocation.

There's no real limitation as far as the C language itself goes on what you're allowed to try and allocate in a single chunk. The only limitation is your hardware, and I suppose that of the data type. (You can't try and allocate 500,000,000,000,000,000,000,000,000,000,000,000,00 0,000,000 objects, because that doesn't fit in the data type (size_t). If nine million fits in size_t, and you've got enough resources, it'll allocate nine million bytes (or objects or whatever). Why shouldn't it work if it meets the above requirements?
Quote:

Or why I can typecast 'pow' as an int (using calculations in the millions) without any data loss.
Of course there's going to be data loss. What do you expect to happen to anything past the decimal point? Integers don't have decimal places. It has to go some place, so it's lost in the assignment.

Quzah.
• 08-18-2005
Dave_Sinkula
FWIW
Code:

```#include <stdio.h> #include <limits.h> int main() {   double value  = INT_MAX - 1.0 / 3.0;   int    result = value; /* truncates fractional portion */   printf("INT_MIN  = %11d, ",  INT_MIN);   printf("INT_MAX  = %11d, ",  INT_MAX);   printf("UINT_MAX  = %11u\n",  UINT_MAX);   printf("LONG_MIN  = %11ld, ", LONG_MIN);   printf("LONG_MAX  = %11ld, ", LONG_MAX);   printf("ULONG_MAX = %11lu\n", ULONG_MAX);   printf("value = %18.6f, result = %11d\n", value, result);   value  = INT_MIN * 10.0 / 3.0;   result = value; /* value not representable in an int */   printf("value = %18.6f, result = %11d\n", value, result);   return 0; } /* my output INT_MIN  = -2147483648, INT_MAX  =  2147483647, UINT_MAX  =  4294967295 LONG_MIN  = -2147483648, LONG_MAX  =  2147483647, ULONG_MAX =  4294967295 value =  2147483646.666667, result =  2147483646 value = -7158278826.666667, result =  1431655766 */```
• 08-18-2005
Lionmane
Guys, I appreciate the info but I'm *not* using decimals (regardless of which data type 'pow' is). My calculations do not produce decimals, so truncation to the right of the decimal doesn't matter.

According to my reference book, an 'int' data type has a range of -32,767 to 32,767. So how am I able to calculate numbers in the millions with an 'int' data type without any problems?

This is the type of truncation I was referring to (in QBasic it would truncate anything past the leftmost range).

mw
• 08-18-2005
Dave_Sinkula
Quote:

Originally Posted by Lionmane
According to my reference book, an 'int' data type has a range of -32,767 to 32,767. So how am I able to calculate numbers in the millions with an 'int' data type without any problems?

Try the code I posted above to see what your actual implementation limits are.

Also, whether or not the double value calculated by pow is representable as an int is an issue.
Code:

```#include <stdio.h> #include <limits.h> #include <math.h> int main() {   double power;   for (power = 2; power < 40; power += 2)   {       double value  = pow(2.0, power);       int    result = value; /* truncates fractional portion */       printf("value = %15.0f, result = %d\n", value, result);   }   return 0; } /* my output value =              4, result = 4 value =              16, result = 16 value =              64, result = 64 value =            256, result = 256 value =            1024, result = 1024 value =            4096, result = 4096 value =          16384, result = 16384 value =          65536, result = 65536 value =          262144, result = 262144 value =        1048576, result = 1048576 value =        4194304, result = 4194304 value =        16777216, result = 16777216 value =        67108864, result = 67108864 value =      268435456, result = 268435456 value =      1073741824, result = 1073741824 value =      4294967296, result = 0 value =    17179869184, result = 0 value =    68719476736, result = 0 value =    274877906944, result = 0 */```
• 08-18-2005
Prelude
>an 'int' data type has a range of -32,767 to 32,767
That's a minimum required range. Chances are very good that you're on a 32-bit system, where the range of int is just over four billion. If you want to be strictly portable then you can use long int, which is required to be at least 32-bits.
• 08-18-2005
Lionmane
Thanks Dave!

mw
Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last