text: /*
   * Copyright (c) 2015-2016, Fred Morcos <fred.morcos@gmail.com>
   *
   * Permission to  use, copy,  modify, and/or distribute  this software
   * for any  purpose with  or without fee  is hereby  granted, provided
   * that the above  copyright notice and this  permission notice appear
   * in all copies.
   *
   * THE  SOFTWARE IS  PROVIDED "AS  IS"  AND THE  AUTHOR DISCLAIMS  ALL
   * WARRANTIES  WITH  REGARD TO  THIS  SOFTWARE  INCLUDING ALL  IMPLIED
   * WARRANTIES OF  MERCHANTABILITY AND FITNESS.  IN NO EVENT  SHALL THE
   * AUTHOR   BE  LIABLE   FOR   ANY  SPECIAL,   DIRECT,  INDIRECT,   OR
   * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
   * OF  USE,  DATA  OR  PROFITS,  WHETHER IN  AN  ACTION  OF  CONTRACT,
   * NEGLIGENCE  OR  OTHER  TORTIOUS  ACTION,   ARISING  OUT  OF  OR  IN
   * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   */
  
  #include <assert.h>
  #include <limits.h>
  #include <math.h>
  #include <stdlib.h>
  #include "num.h"
  
  unsigned int ndigits(unsigned long long val) {
    unsigned int len = 0;
  
    do {
      val /= 10;
      len++;
    } while (val);
  
    return len;
  }
  
  void ulltoa(char *str, unsigned long long val, const unsigned int len) {
    assert(str != NULL);
    assert(len > 0);
  
    double res = pow(10, len - 1);
  
    assert(res > 0);
    assert(res <= LLONG_MAX);
  
    unsigned long long div = (unsigned long long) llround(res);
  
    for (unsigned long long digit = 0; div > 0; div /= 10) {
      digit = val / div;
      *(str++) = (char) ('0' + digit);
      val -= digit * div;
    }
  }
  