kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

cg_x64_fp_format_fixed_digits.c (1565B)


      1 typedef unsigned long size_t;
      2 
      3 typedef struct {
      4   char* buf;
      5   size_t cap;
      6   size_t len;
      7 } Out;
      8 
      9 static void out_ch(Out* out, char ch) {
     10   if (out->cap && out->len + 1U < out->cap) out->buf[out->len] = ch;
     11   out->len++;
     12 }
     13 
     14 static double pow10_u(unsigned n) {
     15   double value = 1.0;
     16   while (n-- > 0) value *= 10.0;
     17   return value;
     18 }
     19 
     20 static void format_fixed_abs(Out* out, double value, unsigned prec) {
     21   double rounded;
     22   double pow10 = 1.0;
     23   int emitted = 0;
     24 
     25   rounded = value + 0.5 / pow10_u(prec);
     26   if (rounded >= 1.0) {
     27     for (;;) {
     28       double next = pow10 * 10.0;
     29       if (!(next > pow10) || next > rounded) break;
     30       pow10 = next;
     31     }
     32   }
     33 
     34   while (pow10 >= 1.0) {
     35     int digit = (int)(rounded / pow10);
     36     if (digit < 0) digit = 0;
     37     if (digit > 9) digit = 9;
     38     out_ch(out, (char)('0' + digit));
     39     rounded -= (double)digit * pow10;
     40     pow10 /= 10.0;
     41     emitted = 1;
     42   }
     43   if (!emitted) out_ch(out, '0');
     44 
     45   out_ch(out, '.');
     46   for (unsigned i = 0; i < prec; i++) {
     47     int digit;
     48     rounded *= 10.0;
     49     digit = (int)rounded;
     50     if (digit < 0) digit = 0;
     51     if (digit > 9) digit = 9;
     52     out_ch(out, (char)('0' + digit));
     53     rounded -= (double)digit;
     54   }
     55 }
     56 
     57 int test_main(void) {
     58   char buf[16];
     59   Out out;
     60   out.buf = buf;
     61   out.cap = sizeof(buf);
     62   out.len = 0;
     63   format_fixed_abs(&out, 12.375, 2);
     64   buf[out.len] = '\0';
     65   if (buf[0] != '1') return 20;
     66   if (buf[1] != '2') return 21;
     67   if (buf[2] != '.') return 22;
     68   if (buf[3] != '3') return 23;
     69   if (buf[4] != '8') return 24;
     70   if (out.len != 5) return 25;
     71   return 42;
     72 }