C Fast Casting Data Type

I have a problem when try to change data type form one to another in C. For example, I try to casting float data type to integer or from double to integer. In the last time, I use command (int)float_number. Because this process is slow, I try to searching about fast casting data type. We can use command lrint (convert from double to integer) and lrintf (convert from float to integer). This is my simple code to compare my old casting data and use fast casting data type (from c library). Create a new file (give name tes_casting.c). Copy this code to that file :

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

void float_method1(float *fa, int *ia, int nx);  /* casting with (float) */
void float_method2(float *fa, int *ia, int nx); /* casting with lrintf */
void double_method1(double *fa, int *ia, int nx);  /* casting with (double) */
void double_method2(double *fa, int *ia, int nx); /* casting with lrint */

int main(int argc, char **argv)
{
  time_t t1, t2, t3, t4;          /* time variable */
  div_t divresult1, divresult2;
  float *fa;	/* array of float as input data */
  double *da;   /* array of double  as input data*/
  int *ia;	    /* array of int as output data */
  int narray;	/* length of array */
  int nloop;	/* number of iteration to chect speed of two method casting */
  int i;

  if(argc!=3){  /* help function */
    printf("usage : ./castmethod array_size n_loop \n");
    return (0);
  }

  narray = atoi(argv[1]); /* get length of array */
  nloop = atoi(argv[2]);  /* get number of loop */

  ia = (int*) calloc(narray, sizeof(int));     /*allocate array */
  fa = (float*) calloc(narray, sizeof(float));
  da = (double*) calloc(narray, sizeof(double));

  for(i=0; i<narray; i++)	/* fiil array */
  {
    fa[i] = (float) i;
	da[i] = (double) i;
  }

  /* ----------------------------------------------------------------------------------*/
  /* Process casting with function (float) */
  t1 = time(NULL);
  for(i=0; i<nloop; i++)
    float_method1(fa, ia, narray);
  t2 = time(NULL);

  /* Process casting with function lrintf */
  t3 = time(NULL);
  for(i=0; i<nloop; i++)
    float_method2(fa, ia, narray);
  t4 = time(NULL);

  /* show speed time of two function casting */
  fprintf(stderr," --- COMPARE FLOAT CASTING ---\n");
  divresult1 = div (t2-t1, 60);
  fprintf(stderr,"          casting I = %d min %d sec\n", divresult1.quot, divresult1.rem);

  divresult2 = div (t4-t3, 60);
  fprintf(stderr,"casting II (lrintf) = %d min %d sec\n", divresult2.quot, divresult2.rem);

  /* ----------------------------------------------------------------------------------*/
  /* Process casting with function (double) */
  t1 = time(NULL);
  for(i=0; i<nloop; i++)
    double_method1(da, ia, narray);
  t2 = time(NULL);

  /* Process casting with function lrintf */
  t3 = time(NULL);
  for(i=0; i<nloop; i++)
    double_method2(da, ia, narray);
  t4 = time(NULL);

  /* show speed time of two function casting */
  fprintf(stderr,"\n --- COMPARE DOUBLE CASTING ---\n");
  divresult1 = div (t2-t1, 60);
  fprintf(stderr,"          casting I = %d min %d sec\n", divresult1.quot, divresult1.rem);

  divresult2 = div (t4-t3, 60);
  fprintf(stderr," casting II (lrint) = %d min %d sec\n", divresult2.quot, divresult2.rem);

  /* deallocate array */
  free(ia);
  free(fa);
  free(da);

  return(1);
}

void float_method1(float *fa, int *ia, int nx)
{
  int i;
  for(i=0; i<nx; i++)
    ia[i] = (int) fa[i];
}

void float_method2(float *fa, int *ia, int nx)
{
  int i;
  for(i=0; i<nx; i++)
    ia[i] = lrintf(fa[i]);
}

void double_method1(double *fa, int *ia, int nx)
{
  int i;
  for(i=0; i<nx; i++)
    ia[i] = (int) fa[i];
}

void double_method2(double *fa, int *ia, int nx)
{
  int i;
  for(i=0; i<nx; i++)
    ia[i] = lrint(fa[i]);
}

Compile this code with command :

gcc tes_casting.c -lm -o tes_casting

This is how to use and output from this program :

E:\tmp\tmp1>tes_casting.exe 10000 100000
 --- COMPARE FLOAT CASTING ---
          casting I = 0 min 15 sec
casting II (lrintf) = 0 min 8 sec

 --- COMPARE DOUBLE CASTING ---
          casting I = 0 min 15 sec
 casting II (lrint) = 0 min 13 sec

You can see, lrintf and lrint can speed up your casting algorithm. Converting float to integer with or without lrintf command can 100% faster than (int)float_numb.

Source:
http://www.mega-nerd.com/FPcast/

Add a Comment

Your email address will not be published. Required fields are marked *

 

This site uses Akismet to reduce spam. Learn how your comment data is processed.