Tuesday, November 16, 2010

format numeric

<?php
$arr = array(
  0,
 0.00,
  0.001,
  0.0001,
 1118,
 1118.0,
 1118.00,
 1118.000,
 1118.001,
  1118.0001,
 1118.3,
 1118.30,
 1118.301,
  1118.305,
  1118.3001,
 1118.5,
 1118.50,
 1118.500,
 1118.501,
 1118.578,
  '0',
 '0.00',
  '0.001',
  '0.0001',
 '1118',
 '1118.0',
 '1118.00',
 '1118.000',
 '1118.001',
  '1118.0001',
 '1118.3',
 '1118.30',
 '1118.301',
  '1118.305',
  '1118.3001',
 '1118.5',
 '1118.50',
 '1118.500',
 '1118.501',
 '1118.5786',
 'dd',
);

foreach ($arr as $val) {
  echo _format_numeric_iphone($val, 2) . PHP_EOL;
}


/**
 * If it's a whole number (including 0, 1, 2, N.00), 
 * it will be formatted without decimals.
 *
 * Example: 
 * 0.00 => 0
 * 1234.00 => 1234
 * 1234 => 1234
 * '0.00' => 0
 * '1234.00' => 1234
 * '1234' => 1234
 *
 * Else, it will be formatted with two decimals.
 * @param 
 * @return 
 */
function _format_numeric_iphone($num, $decimals = 0) {
  if (is_numeric($num)) {
    // check if it's a whole number.
    // _is_digit() is matching:
    // 0, 0.00, 1234, 1234.00, '0', '1234'
    if (_is_digit($num)) {
      return $num;
    }
    else {
      // formatted to two decimals first.
      $num = number_format($num, $decimals, '.', '');

      if (_has_decimal_trailing_zeros($num)) {
        return number_format($num, 0, '.', '');
      }
    }
  }

  return $num;
}

/**
 * check if a number contains only "digits" (including negative number)
 * @param 
 * @return 
 */
function _is_digit($num) {
  return preg_match('/^[+-]?[0-9]+$/', $num);
}

/**
 * This function will not catch 123.00, since PHP convert that to 123 internally.
 * However, it will catch '123.00'.
 * @param 
 * @return 
 */
function _has_decimal_trailing_zeros($num) {
  return preg_match('/\.0+$/', $num);
}

?>

No comments: