18
Is there any native function, or other practical way, to get a number on float
and convert to full number?
Example:
//input: 2.000,00
//output: dois mil
18
Is there any native function, or other practical way, to get a number on float
and convert to full number?
Example:
//input: 2.000,00
//output: dois mil
13
Native function does not exist, but there goes a recursive implementation.
<?php
function convert_number_to_words($number) {
$hyphen = '-';
$conjunction = ' e ';
$separator = ', ';
$negative = 'menos ';
$decimal = ' ponto ';
$dictionary = array(
0 => 'zero',
1 => 'um',
2 => 'dois',
3 => 'três',
4 => 'quatro',
5 => 'cinco',
6 => 'seis',
7 => 'sete',
8 => 'oito',
9 => 'nove',
10 => 'dez',
11 => 'onze',
12 => 'doze',
13 => 'treze',
14 => 'quatorze',
15 => 'quinze',
16 => 'dezesseis',
17 => 'dezessete',
18 => 'dezoito',
19 => 'dezenove',
20 => 'vinte',
30 => 'trinta',
40 => 'quarenta',
50 => 'cinquenta',
60 => 'sessenta',
70 => 'setenta',
80 => 'oitenta',
90 => 'noventa',
100 => 'cento',
200 => 'duzentos',
300 => 'trezentos',
400 => 'quatrocentos',
500 => 'quinhentos',
600 => 'seiscentos',
700 => 'setecentos',
800 => 'oitocentos',
900 => 'novecentos',
1000 => 'mil',
1000000 => array('milhão', 'milhões'),
1000000000 => array('bilhão', 'bilhões'),
1000000000000 => array('trilhão', 'trilhões'),
1000000000000000 => array('quatrilhão', 'quatrilhões'),
1000000000000000000 => array('quinquilhão', 'quinquilhões')
);
if (!is_numeric($number)) {
return false;
}
if (($number >= 0 && (int) $number < 0) || (int) $number < 0 - PHP_INT_MAX) {
// overflow
trigger_error(
'convert_number_to_words só aceita números entre ' . PHP_INT_MAX . ' à ' . PHP_INT_MAX,
E_USER_WARNING
);
return false;
}
if ($number < 0) {
return $negative . convert_number_to_words(abs($number));
}
$string = $fraction = null;
if (strpos($number, '.') !== false) {
list($number, $fraction) = explode('.', $number);
}
switch (true) {
case $number < 21:
$string = $dictionary[$number];
break;
case $number < 100:
$tens = ((int) ($number / 10)) * 10;
$units = $number % 10;
$string = $dictionary[$tens];
if ($units) {
$string .= $conjunction . $dictionary[$units];
}
break;
case $number < 1000:
$hundreds = floor($number / 100)*100;
$remainder = $number % 100;
$string = $dictionary[$hundreds];
if ($remainder) {
$string .= $conjunction . convert_number_to_words($remainder);
}
break;
default:
$baseUnit = pow(1000, floor(log($number, 1000)));
$numBaseUnits = (int) ($number / $baseUnit);
$remainder = $number % $baseUnit;
if ($baseUnit == 1000) {
$string = convert_number_to_words($numBaseUnits) . ' ' . $dictionary[1000];
} elseif ($numBaseUnits == 1) {
$string = convert_number_to_words($numBaseUnits) . ' ' . $dictionary[$baseUnit][0];
} else {
$string = convert_number_to_words($numBaseUnits) . ' ' . $dictionary[$baseUnit][1];
}
if ($remainder) {
$string .= $remainder < 100 ? $conjunction : $separator;
$string .= convert_number_to_words($remainder);
}
break;
}
if (null !== $fraction && is_numeric($fraction)) {
$string .= $decimal;
$words = array();
foreach (str_split((string) $fraction) as $number) {
$words[] = $dictionary[$number];
}
$string .= implode(' ', $words);
}
return $string;
}
echo '<pre>';
echo "123456789\n";
echo convert_number_to_words(123456789);
echo "\n\n";
echo "123456789.123\n";
echo convert_number_to_words(123456789.123);
echo "\n\n";
echo "-1922685.477\n";
echo convert_number_to_words(-1922685.477);
echo "\n\n";
echo "123456789123.12345\n";
echo convert_number_to_words(123456789123.12345); // rounds the fractional part
echo "\n\n";
echo "123456789123.12345\n";
echo convert_number_to_words('123456789123.12345'); // does not round
echo '</pre>';
Function adapted from http://www.karlrixon.co.uk/writing/convert-numbers-to-words-with-php/
9
There is no native php function for this, even because it would need an i18n to be able to fully describe values from other languages, I believe the most advisable in this case is to use a class for this, in Extreme knowledge has a function that solves this problem.
Example:
class Monetary {
private static $unidades = array("um", "dois", "três", "quatro", "cinco", "seis", "sete", "oito", "nove", "dez", "onze", "doze",
"treze", "quatorze", "quinze", "dezesseis", "dezessete", "dezoito", "dezenove");
private static $dezenas = array("dez", "vinte", "trinta", "quarenta", "cinqüenta", "sessenta", "setenta", "oitenta", "noventa");
private static $centenas = array("cem", "duzentos", "trezentos", "quatrocentos", "quinhentos",
"seiscentos", "setecentos", "oitocentos", "novecentos");
private static $milhares = array(
array("text" => "mil", "start" => 1000, "end" => 999999, "div" => 1000),
array("text" => "milhão", "start" => 1000000, "end" => 1999999, "div" => 1000000),
array("text" => "milhões", "start" => 2000000, "end" => 999999999, "div" => 1000000),
array("text" => "bilhão", "start" => 1000000000, "end" => 1999999999, "div" => 1000000000),
array("text" => "bilhões", "start" => 2000000000, "end" => 2147483647, "div" => 1000000000)
);
const MIN = 0.01;
const MAX = 2147483647.99;
const MOEDA = " real ";
const MOEDAS = " reais ";
const CENTAVO = " centavo ";
const CENTAVOS = " centavos ";
static
function numberToExt($number, $moeda = true) {
if ($number >= self::MIN && $number <= self::MAX) {
$value = self::conversionR((int) $number);
if ($moeda) {
if (floor($number) == 1) {
$value. = self::MOEDA;
} else if (floor($number) > 1)
$value. = self::MOEDAS;
}
$decimals = self::extractDecimals($number);
if ($decimals > 0.00) {
$decimals = round($decimals * 100);
$value. = " e ".self::conversionR($decimals);
if ($moeda) {
if ($decimals == 1) {
$value. = self::CENTAVO;
} else if ($decimals > 1)
$value. = self::CENTAVOS;
}
}
}
return trim($value);
}
private static
function extractDecimals($number) {
return $number - floor($number);
}
static
function conversionR($number) {
if (in_array($number, range(1, 19))) {
$value = self::$unidades[$number - 1];
} else if (in_array($number, range(20, 90, 10))) {
$value = self::$dezenas[floor($number / 10) - 1].
" ";
} else if (in_array($number, range(21, 99))) {
$value = self::$dezenas[floor($number / 10) - 1].
" e ".self::conversionR($number % 10);
} else if (in_array($number, range(100, 900, 100))) {
$value = self::$centenas[floor($number / 100) - 1].
" ";
} else if (in_array($number, range(101, 199))) {
$value = ' cento e '.self::conversionR($number % 100);
} else if (in_array($number, range(201, 999))) {
$value = self::$centenas[floor($number / 100) - 1].
" e ".self::conversionR($number % 100);
} else {
foreach(self::$milhares as $item) {
if ($number >= $item['start'] && $number <= $item['end']) {
$value = self::conversionR(floor($number / $item['div'])).
" ".$item['text'].
" ".self::conversionR($number % $item['div']);
break;
}
}
}
return $value;
}
}
echo Monetary::numberToExt(500.00);
Entree:
echo Monetary::numberToExt(500.00);
Exit:
quinhentos reais
Thanks, but the code contains bugs for value 100, below 0.99 and a few numbers over a thousand
0
Source: https://recursosdophp.blogspot.com.br/2012/04/ola-seguidores-do-php-bom-eu-fiz.html
That was the best job I could find. You can test with all possible values, if you find an error, warns there.
function extenso($valor = 0, $maiusculas = false) {
if(!$maiusculas){
$singular = ["centavo", "real", "mil", "milhão", "bilhão", "trilhão", "quatrilhão"];
$plural = ["centavos", "reais", "mil", "milhões", "bilhões", "trilhões", "quatrilhões"];
$u = ["", "um", "dois", "três", "quatro", "cinco", "seis", "sete", "oito", "nove"];
}else{
$singular = ["CENTAVO", "REAL", "MIL", "MILHÃO", "BILHÃO", "TRILHÃO", "QUADRILHÃO"];
$plural = ["CENTAVOS", "REAIS", "MIL", "MILHÕES", "BILHÕES", "TRILHÕES", "QUADRILHÕES"];
$u = ["", "um", "dois", "TRÊS", "quatro", "cinco", "seis", "sete", "oito", "nove"];
}
$c = ["", "cem", "duzentos", "trezentos", "quatrocentos", "quinhentos", "seiscentos", "setecentos", "oitocentos", "novecentos"];
$d = ["", "dez", "vinte", "trinta", "quarenta", "cinquenta", "sessenta", "setenta", "oitenta", "noventa"];
$d10 = ["dez", "onze", "doze", "treze", "quatorze", "quinze", "dezesseis", "dezesete", "dezoito", "dezenove"];
$z = 0;
$rt = "";
$valor = number_format($valor, 2, ".", ".");
$inteiro = explode(".", $valor);
for($i=0;$i<count($inteiro);$i++)
for($ii=strlen($inteiro[$i]);$ii<3;$ii++)
$inteiro[$i] = "0".$inteiro[$i];
$fim = count($inteiro) - ($inteiro[count($inteiro)-1] > 0 ? 1 : 2);
for ($i=0;$i<count($inteiro);$i++) {
$valor = $inteiro[$i];
$rc = (($valor > 100) && ($valor < 200)) ? "cento" : $c[$valor[0]];
$rd = ($valor[1] < 2) ? "" : $d[$valor[1]];
$ru = ($valor > 0) ? (($valor[1] == 1) ? $d10[$valor[2]] : $u[$valor[2]]) : "";
$r = $rc.(($rc && ($rd || $ru)) ? " e " : "").$rd.(($rd &&
$ru) ? " e " : "").$ru;
$t = count($inteiro)-1-$i;
$r .= $r ? " ".($valor > 1 ? $plural[$t] : $singular[$t]) : "";
if ($valor == "000")$z++; elseif ($z > 0) $z--;
if (($t==1) && ($z>0) && ($inteiro[0] > 0)) $r .= (($z>1) ? " de " : "").$plural[$t];
if ($r) $rt = $rt . ((($i > 0) && ($i <= $fim) && ($inteiro[0] > 0) && ($z < 1)) ? ( ($i < $fim) ? ", " : " e ") : " ") . $r;
}
if(!$maiusculas){
$return = $rt ? $rt : "zero";
} else {
if ($rt) $rt = ereg_replace(" E "," e ",ucwords($rt));
$return = ($rt) ? ($rt) : "Zero" ;
}
if(!$maiusculas){
return ereg_replace(" E "," e ",ucwords($return));
}else{
return strtoupper($return);
}
}
Example:
$valor = 405.63;
$dim = extenso($valor);
$valor = number_format($valor, 2, ",", ".");
echo "R$ ".$valor." = ".$dim;
Exit
R$ 405,63 = Four hundred and five reais and sixty-three cents
It is the same that had already been posted here: http://answall.com/a/106224/70 with the difference that it was cited the origin, and warned that it is for financial values. In addition, the code containing the link to this answer has already been mentioned in the comments of the question. I always suggest copying code from somewhere, citing the source, giving due credit to the original author or site..
Well, in the code posted I made some changes. I just posted the source.
0
But if you just need something simple and have control of input values, try this:
function numero_extenso($numero=0){
if($numero){
$dicionario = array(
1 => 'um',
2 => 'dois',
3 => 'três',
4 => 'quatro',
5 => 'cinco',
6 => 'seis',
7 => 'sete',
8 => 'oito',
9 => 'nove',
10 => 'dez',
11 => 'onze',
12 => 'doze',
13 => 'treze',
14 => 'quatorze',
15 => 'quinze',
16 => 'dezesseis',
17 => 'dezessete',
18 => 'dezoito',
19 => 'dezenove',
20 => 'vinte',
30 => 'trinta',
40 => 'quarenta',
50 => 'cinquenta',
100 => 'cento');
return $dicionario[$numero];
}
}
Browser other questions tagged php
You are not signed in. Login or sign up in order to post.
It doesn’t exist, but there must be something out there that someone did, probably done wrong, but it should work. But it is very rare to want the extension of a number with floating point, does it want?
– Maniero
by default I believe not, but there are several sources on the internet that propose to do this, from a look here http://codigofonte.uol.com.br/codigos/conversao-de-valor-numerico-para-extenso-em-php and search on google before posting here on the forum
– Cristian Urbainski
http://www.dirceuresende.com/blog/escrevendo-numero-por-extenso-no-php/
– Gabriel Rodrigues
@Cristianurbainski This is interesting content for the site. I recommend you read that. Incidentally, the Stack Overflow in English is not a forum.
– Jéf Bueno
Related to the algorithm: How to modify VBA function to write in full a number greater than 1 trillion in EXCEL cell?
– rray
Besides the answers below, it is interesting this answer duplicated question. It explains the use of the class
NumberFormatter
packageintl
PHP. Seems to me a more "canonical".– nunks