Advertisement
Guest User

float to decimal string

a guest
Jan 19th, 2017
427
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.73 KB | None | 0 0
  1. /*  float to decimal string, exact conversion; tested for all possible inputs against mingw 4.0 sprintf with define _XOPEN_SOURCE 1
  2. */
  3.  
  4.  
  5. void f32_to_str(float f32, char *str){
  6.     f_un fun;
  7.     uint32_t uv[10], mlsft, m, x, a, b, z, c;
  8.     int i;
  9.     char *pp, *pe, swap;
  10.     union {
  11.         uint64_t u64;
  12.         uint32_t u32[2];
  13.     } u6432;
  14.     union {
  15.         uint32_t u32;
  16.         uint16_t u16[2];
  17.     } d, t;
  18.  
  19.     fun.f = f32;
  20.     if(fun.x == 0xFF){
  21.         if(fun.m == 0){
  22.             if(fun.s)
  23.                 *str++ = '-';
  24.             strcpy(str, "inf");
  25.         } else {
  26.             strcpy(str, "nan");
  27.         }
  28.         return;
  29.     }
  30.     if(fun.s)
  31.         *str++ = '-';
  32.  
  33.     x = fun.x - 127;
  34.     m = fun.m;
  35.     if(fun.x){
  36.         m = fun.m | 1 << 23;
  37.     } else {
  38.         x++;
  39.     }
  40.     mlsft = x + 160 - 23;
  41.     for(i = 0; i < 10; i++){
  42.         uv[i] = 0;
  43.     }
  44.  
  45.     a = mlsft >> 5;
  46.     b = mlsft & 0x1F;
  47.     uv[a] = m << b;
  48.     if(b)
  49.         uv[a + 1] = m >> (32 - b);
  50.  
  51.     pp = str;
  52.     b = a + 1;
  53.     do {
  54.         for(i = b, c = z = 0; i >= 5; i--){
  55.             t.u32 = uv[i];
  56.             d.u16[1] = c;
  57.             d.u16[0] = t.u16[1];
  58.             t.u16[1] = d.u32 / 10;
  59.             c = d.u32 % 10;
  60.  
  61.             d.u16[1] = c;
  62.             d.u16[0] = t.u16[0];
  63.             t.u16[0] = d.u32 / 10;
  64.             c = d.u32 % 10;
  65.  
  66.             uv[i] = t.u32;
  67. /*
  68.             u6432.u32[1] = c;
  69.             u6432.u32[0] = uv[i];
  70.             uv[i] = u6432.u64 / 10;
  71.             c = u6432.u64 % 10;
  72. */
  73.  
  74.             if(i == b && uv[i] == 0)
  75.                 b--;
  76.             z |= uv[i];
  77.         }
  78.         *str++ = c + '0';
  79.     } while(z);
  80.  
  81.     pe = str - 1;
  82.     while(pe > pp){
  83.         swap = *pe;
  84.         *pe-- = *pp;
  85.         *pp++ = swap;
  86.     }
  87.  
  88.     *str++ = '.';
  89.  
  90.     b = a;
  91.     do {
  92.         for(i = b, c = z = 0; i < 5; i++){
  93.             u6432.u64 = (uint64_t) uv[i] * 10;
  94.             uv[i] = u6432.u32[0] + c;
  95.             c = u6432.u32[1];
  96.             if(uv[i] < u6432.u32[0])
  97.                 c++;
  98.             if(i == b && uv[i] == 0)
  99.                 b++;
  100.             z |= uv[i];
  101.         }
  102.         *str++ = c + '0';
  103.     } while(z);
  104.  
  105.     *str = 0;
  106. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement