/*
   ###########################################################################
   This functions returns the formal name of a large numeric value string.
   ONLY the integer part is used.  Any decimal part is ignored.

   EXAMPLE:
   Given a signed numerical string argument like:
   BigIntStr = '7,805,769,880,904,240,738,817,015,808'
   or
   BigNumStr = '78057691843657209880904240738817015808'

   If there is any decimal part of BigNum, it will be
   removed. Only the integer part counts here.

   The function returns the formal designation:
   '7.81 octillion'

   ERRORS:
   No special error checking is done.

   NO DEPENDENCIES
   ###########################################################################
*/

   function BC_Big_Num_Name ($BigNumStr, $Decimals=2)
{

/* -------------------------------------------------------------
   Filter out any commas or negative sign and use absolute value
   of big number by removing any preceding numerical +/- sign.
*/
   $BigNum = Str_Replace(',', '', Str_Replace(' ' ,'', trim($BigNumStr)));

// -------------------------------
// Preserve any numerical +/- sign
// to reattach to output.

   $NumSign = '';
   if (substr($BigNum,0,1) == '-') {$NumSign = '-';}
   if (substr($BigNum,0,1) == '+') {$NumSign = '+';}
   $BigNum = Str_Replace('+', '', Str_Replace('-', '', $BigNum));

/* ---------------------------------
   Count number number of raw digits
   in the filtered numeric string.
*/
   $DigitsCount = StrLen($BigNum);

// ------------------------------------
// Error if big integer is non-numeric.

   if (!Is_Numeric($BigNum)) {return 'ERROR: Cannot resolve as a valid number value.';}

/* --------------------------------------------------
   Cut off any decimal part of the big number string.
   Only the big integer part counts here.
*/
   $i = StrPos($BigNum, '.');   if ($i === FALSE) {$BigNum = "$BigNum.0";}
   $i = StrPos($BigNum, '.');   $BigNum = substr($BigNum, 0, $i);

// -----------------------------------------------
// Set number of decimals to use in output string.
// This usually just 1 to 3 decimals.

   $decimals = abs(IntVal(trim($Decimals)));

   if ($decimals == 0) {$decimals = 1;}

/* ----------------------------------------
   Define an array of formal integer names.

   https://en.wikipedia.org/wiki/Names_of_large_numbers
*/
   $DigitGroupsStr = '';

   $BigNum = StrRev($BigNum);

// ***************
// ***************

   $groups[1]  = '';
   $groups[2]  = 'thousand';
   $groups[3]  = 'million';
   $groups[4]  = 'billion';
   $groups[5]  = 'trillion';
   $groups[6]  = 'quadrillion';
   $groups[7]  = 'quintillion';
   $groups[8]  = 'sextillion';
   $groups[9]  = 'septillion';
   $groups[10] = 'octillion';
   $groups[11] = 'nonillion';
   $groups[12] = 'decillion';
   $groups[13] = 'undecillion';
   $groups[14] = 'duodecillion';
   $groups[15] = 'tredecillion';
   $groups[16] = 'quattuordecillion';
   $groups[17] = 'quindecillion';
   $groups[18] = 'sexdecillion';
   $groups[19] = 'septendecillion';
   $groups[20] = 'octodecillion';
   $groups[21] = 'novemdecillion';
   $groups[22] = 'vigintillion';
   $groups[23] = 'unvigintillion';
   $groups[24] = 'duovigintillion';
   $groups[25] = 'trevigintillion';
   $groups[26] = 'quattuorvigintillion';
   $groups[27] = 'quinvigintillion';
   $groups[28] = 'sexvigintillion';
   $groups[29] = 'septenvigintillion';
   $groups[30] = 'octovigintillion';
   $groups[31] = 'novemvigintillion';
   $groups[32] = 'trigintillion';
   $groups[33] = 'untrigintillion';
   $groups[34] = 'duotrigintillion';

// ----------------------------------------
// Break up big integer into spaced 3-digit
// groups and count the number of groups.

   for($i=0;   $i < $DigitsCount;   $i++)
  {
   $DigitGroupsStr .= substr($BigNum,$i,1);

   if (($i+1) % 3 == 0) {$DigitGroupsStr .= ' ';}
  }
   $DigitGroupsStr = trim(StrRev($DigitGroupsStr));

   $DigitGroupsCount = 1 + Substr_Count($DigitGroupsStr, ' ');

// -------------------
// Get top group name.

   $TopNameStr = $groups[$DigitGroupsCount];

// ------------------------------------
// Make number into decimal value (x).

   $w = StrRev($DigitGroupsStr);
   $n = StrRev(StrRChr($w, ' '));
   $L = StrLen($n);
   $w = StrRev($w);
   $w = trim($n).'.'.substr(Str_Replace(' ','',$w), $L-1, StrLen($w));
   $w = SPrintF("%1.$decimals" . "f", $w);

   unset($groups);

// Done.
   return "$NumSign$w $TopNameStr";

} // End of  BC_Big_Num_Name (...)