Guest User

float to decimal string

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