/**
  * @see http://www.bzarg.com/p/how-to-pronounce-hexadecimal/
  * @param IntegerNumber $number
  * @return string
  */
 public function pronounce(IntegerNumber $number)
 {
     $numberPart = $number->getValue();
     if (strlen($numberPart) > 6) {
         throw new \InvalidArgumentException("Only 3-byte hexadecimals can be pronounced.");
     }
     $outputParts = [];
     if ($numberPart === "0") {
         return self::SINGLE[$numberPart];
     }
     // negative
     if (!$number->isPositive()) {
         $outputParts[] = "negative";
     }
     $powerNames = [3 => "halfy", 2 => "bitey", 1 => ""];
     foreach ($powerNames as $power => $powerName) {
         if (strlen($numberPart) < $power * 2 - 1) {
             continue;
         }
         // retrieve big-endian byte part (2-characters), which could be only one character (nibble)
         if ($power == 1) {
             $bytePart = substr($numberPart, $power * -2);
         } else {
             $bytePart = substr($numberPart, $power * -2, $power * -2 + 2);
         }
         $outputParts[] = trim($this->pronounceByte($bytePart, false, $powerName));
     }
     // remove empty output parts to allow for halfy bitey's
     $outputParts = array_filter($outputParts, function ($part) {
         return (bool) $part;
     });
     return trim(implode(" ", $outputParts));
 }
 /**
  * @param IntegerNumber $number
  * @return string
  */
 public function pronounce(IntegerNumber $number)
 {
     $numberPart = $number->getValue();
     $outputParts = [];
     if (strlen($numberPart) > 15) {
         throw new \InvalidArgumentException("Only 15-digit decimals can be pronounced.");
     }
     if ($numberPart === "0") {
         return self::SINGLE[$numberPart];
     }
     // negative
     if (!$number->isPositive()) {
         $outputParts[] = "negative";
     }
     $periodNames = [5 => "trillion", 4 => "billion", 3 => "million", 2 => "thousand", 1 => ""];
     foreach ($periodNames as $period => $periodName) {
         if (strlen($numberPart) < $period * 3 - 2) {
             continue;
         }
         // retrieve 3-character period, which could be less than 3 (e.g. 2 in 2000)
         if ($period == 1) {
             $periodPart = substr($numberPart, $period * -3);
         } else {
             $periodPart = substr($numberPart, $period * -3, $period * -3 + 3);
         }
         $outputParts[] = $this->pronounceTriplet($periodPart, $periodName);
     }
     // remove empty output parts
     $outputParts = array_filter($outputParts, function ($part) {
         return (bool) $part;
     });
     return trim(implode(" ", $outputParts));
 }
 /**
  * @dataProvider provider
  */
 public function testNegativePronunciations($input, $expected)
 {
     $number = new IntegerNumber($input, IntegerNumber::BASE_HEX);
     $number->setIsPositive(false);
     $pronouncer = new HexPronouncer();
     $pronunciation = $pronouncer->pronounce($number);
     $this->assertEquals("negative " . $expected, $pronunciation);
 }