Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

SceL

[Resolvido] Problema com intval do PHP

Recommended Posts

Peço que quem ainda não viu de uma olhada também neste tópico. http://forum.imasters.com.br/topic/429036-in-array-problema-curioso/

 

Agora o outro problema curioso do PHP (talvêz um bug)

 

Fiz a seguinte programação:

um campo determinado onde o usuário digita um valor qualquer maior que zero e menor que 999.

Com até 2 casas decimais.

 

Ao enviar o formulário com esse número, é substituido virgula por ponto, e detectado se o valor digitado é numerico (pois caso seja digitado 2 pontos 12.10.1 ou 12,10,1 deixaria de ser numérico)

Então com o valor já transformado para decimal e sendo numérico tenho eu:

 

if (intval($_POST['unica']*100) == $_POST['unica']*100) $_POST['unica'] = $_POST['unica'] * 100;
				else echo intval($_POST['unica']* 100) . " " . $_POST['unica']*100 . "Valor inválido, o numero de casas decimais não pode ser superior a 2";

 

Ou seja se o número multiplicado por 100 (para retirar as duas casas decimais) forem iguais a parte inteira do número multiplicado do numero multiplicado por 100 ele retornaria o resultado como sucesso!

Deixa eu exemplificar pra entenderem melhor.

 

Se eu digitei o numero 10,1

O sistema substituirá a virgula pelo ponto ficando 10.1 se tornando numérico e o multiplicaria por 100 ficando 1010 ficando um nmero inteiro.

E compararia com o valor inteiro dele multiplicado por 100, ou seja, a parte inteira do valor 1010.

Sendo iguais não retornaria erro.

 

Mas caso o usuário digitasse 10,111

Substituiria a virgula por . ficando 10.111 se tornando numerico e o multiplicaria por 100 ficando 1011.1 sendo assim esse número real com 1 casa decimal.

E compararia o valor inteiro dele multiplicado por 100, ou seja, a parte inteira do valor 1011.1 que seria 1011.

Como os valores seriam difierente 1011.1 e 1011 o sistema retornaria erro.

 

para os numeros maiores que 1 ( 2, 3, 4, ... 999) funciona NORMAL e perfeitamente.

Mas para os números reais de 1 não funciona sempre retorna erro;

O código segue aqui:

 

<?php

$numero = "1,1";
$numero = str_replace(",",".",$numero);
if (is_numeric($numero))
{
   if (intval($numero * 100) == $numero * 100) 
{
	echo intval($numero * 100) . ":" . $numero * 100 . "<br/>"; //Exibirá a comparação como 110:110 (iguais)
	echo "Numero cadastrado com sucesso";
}
   else 
{
	echo intval($numero * 100) . ":" . $numero * 100 . "<br/>"; //Exibirá a comparação como 110:110 (iguais)
	echo "O numero deve conter no máximo 2 casas decimais";
}
}
else
{
   echo "O número digitado deve conter no máximo duas casas decimais e não pode conter caracteres que não sejam número , ou .";
}

?>

Saída:

110:110
O numero deve conter no máximo 2 casas decimais

 

Tentando o mesmo código com o número 2,1 teremos:

<?php

$numero = "2,1";
$numero = str_replace(",",".",$numero);
if (is_numeric($numero))
{
   if (intval($numero * 100) == $numero * 100) 
{
	echo intval($numero * 100) . ":" . $numero * 100 . "<br/>"; //Exibirá a comparação como 210:210 (iguais)
	echo "Numero cadastrado com sucesso";
}
   else 
{
	echo intval($numero * 100) . ":" . $numero * 100 . "<br/>"; //Exibirá a comparação como 210:210 (iguais)
	echo "O numero deve conter no máximo 2 casas decimais";
}
}
else
{
   echo "O número digitado deve conter no máximo duas casas decimais e não pode conter caracteres que não sejam número , ou .";
}

?>

Saída:

210:210
Numero cadastrado com sucesso

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não funcionou =)

 

Para funcionar atribuí uma variavel chamada desejada e outra encontrada, fiz a variável virar uma string concatenando com um espaço.

$desejada = intval($variavel * 100) . " ";
$esperada = $variavel * 100 . " ";

 

Faço a comparação de strings da certo.

Depois multiplico por 1 e volta a ser float para inserir no banco de dados.

Contornei como não era para ter sido contornado mas funcionou!

Compartilhar este post


Link para o post
Compartilhar em outros sites

você testou como eu falei? aqui deu certo para os dois valores que você testou.

você já viu o que retorna usando esse tipo de converção para string?

<?php
$number = '1,1';
$variavel = str_replace(',','.',$number);
$desejada = intval($variavel * 100) . " ";
$esperada = $variavel * 100 . " ";
var_dump($desejada,$esperada);
var_dump(is_numeric($desejada),is_numeric($esperada));
?>

Compartilhar este post


Link para o post
Compartilhar em outros sites

Segue problema corrigido:

 

<?php
$n = (int)(str_replace(',','.','1,1')*100);
if (is_int($n)) {
   echo $n . ':' . $n . '<br />';
   echo 'Numero cadastrado com sucesso';
} else {
   echo "O número digitado deve conter no máximo duas casas decimais e não pode conter caracteres que não sejam número , ou .";
}
?>

 

110:110

Numero cadastrado com sucesso

 

O erro estava no uso do intval no momento errado. Compare com o script acima. (A ordem do processo)

 

:thumbsup:

 

EDIT

 

Só pra explicar melhor:

 

<?php
$numero = '1,1';
$numero = str_replace(',','.',$numero);

var_dump( intval($numero * 100), $numero * 100);

 

int(110) float(110)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Matheus, entendi o que você quis dizer, mas somente era pra dar problema se usasse comparação com === onde compararia a igualdade dos valores e o tipo de variável.

Enviei o bug para o php.net e me explicaram, que o numero quando decimal se eu uso o intval ele tem um valor exato de 110.00000000000000000 (para 1,1) já o numero multiplicado por 100 sem o intval ele possui valor 110.00000000000001421085.

 

Faz-se o teste utilizando

echo sprintf("%.20f %.20f\n", 110., 1.1 * 100);

 

com exibição :

110.00000000000000000000 110.00000000000001421085

 

Sendo assim eu tenho a explicação do primeiro tópico e do segundo que é este.

 

Peço assim para colocarem o tópico como resolvido e agradeço tentarem ajudar!

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.