Jump to content

Inteiros


ville

Recommended Posts

o numero é uma variavel, declarada como float (portanto tanto pode ser inteiro como racional).

Essa variavel muda durante um ciclo, e eu preciso de verificar em cada instancia se a variável é um numero inteiro (ex:2.000) ou racional (2.012)

No google encontrei esta funçao - lsInt(variavel). Mas não reconhece, secalhar é preciso alguma lib.

Link to comment
Share on other sites

Experimenta fazer o resto da divisão inteira por 1, não sei grande coisa de C++, em C seria qualquer coisa como:

int isInteiro(float variavel)
{
return variavel%1 == 0;
}

C++ deve ser parecido 😉

tens a certeza que isso funciona? acho que a divisão inteira só funciona com inteiros...

usando o 'round' deve funcionar...

#include <math.h>

int isInteiro(float var)
{
  return round(var)==var;
}
Link to comment
Share on other sites

  • 2 weeks later...

oi.

Eu tive k fazer uma calculadora para a faculdade e andei a procura dessa mesma função acabei por não encontrar nenhuma função. A lsInt penso que é de java e que não existe em C++. Eu como lia os valores como string fiz um if, onde verificava se o atoi(string) era igual ao atof(string). Rui Carlos podias me explicar  como pretendias usar o round.

bjs.

Link to comment
Share on other sites

Desculpa não tinha visto. O meu compilador não corre com o round, esclarece-me o round arredonda para cima ou para baixo ou depende??

A tua ideia pode resultar com o comando ceil que arredonda sempre para cima.

bjs.

Em que biblioteca é que se encontra o round?

Já agora, será que isto serve:

#include <stdio.h>

int isInt(float n)
{
    return ((int)n)==n;
}

int main(void)
{
    float test = 2932.48;
    printf("%d", isInt(test));
    return 0;
}

Atenção que não podes usar um número maior que o máximo que o int suporta.

<3 life

Link to comment
Share on other sites

Desculpa não tinha visto. O meu compilador não corre com o round, esclarece-me o round arredonda para cima ou para baixo ou depende??

A tua ideia pode resultar com o comando ceil que arredonda sempre para cima.

o 'round', 'ceil', 'floor', etc. estão na biblioteca 'math.h'.

podemos usar qualquer uma destas funções que irá funcionar. se o número for fraccionário qualquer umas dessas funções devolve um valor inteiro, logo será diferente do valor original (fraccionário).


Só uma questão que me intriga um pouco.

O float cobre o int por completo? se bem me lembro a resolução do float perto dos limites diminuia...

ints que não podem ser representados como floats e floats que não podem ser representados como ints.

os floats têm 23 bits para a mantissa, logo, para valores superiores a 2^23, os ints têm mais precisão (é claro que o limite dos floats é muito maior).

Link to comment
Share on other sites

mas repara que ao passares de um float para int só perdes precisão se o float tiver casas décimais (facto que te permite saber se o número é inteiro ou não). as funções 'round', etc. não dão problemas porque elas devolvem um float. nos castings para int, pela razão que indiquei atrás, penso que não dará problemas de precisão (apenas poderá ter problemas de overflow, como o Triton já referiu).

Link to comment
Share on other sites

Encontrei isto:

/*******************************************************************************
Rounding from a float to the nearest integer can be done several ways.
Calling the ANSI C floor() routine then casting to an int is very slow.
Manually adding 0.5 then casting to an int is also somewhat slow because
truncation of the float is slow on Intel FPUs. The fastest choice is to
use the FPU 'fistp' instruction which does the round and conversion
in one instruction (not sure how many clocks). This function is almost
10x faster than adding and casting.

Caller is expected to range check 'v' before attempting to round.
Valid range is INT_MIN to INT_MAX inclusive.
*******************************************************************************/
__forceinline int Round( double v )
{
    ASSERT( v >= INT_MIN && v <= INT_MAX );
    int result;
    __asm
    {
        fld    v      ; Push 'v' into st(0) of FPU stack
        fistp  result ; Convert and store st(0) to integer and pop
    }

    return result;
}

/*******************************************************************************
  Same behavior as Round, except that PRound returns and unsigned value
  (and checks 'v' for being positive in debug mode). This method can
  be used for better type safety if 'v' is known to be positive.

Caller is expected to range check 'v' before attempting to round.
Valid range is 0 to UINT_MAX inclusive.
*******************************************************************************/
__forceinline unsigned PRound( double v )
{
    ASSERT( v >= 0 && v <= UINT_MAX );
    unsigned result;
    __asm
    {
        fld    v      ; Push 'v' into st(0) of FPU stack
        fistp  result ; Convert and store st(0) to integer and pop
    }

    return result;
}

aqui. Não sei se é mais ou menos preciso do que as soluções já apresentadas, mas, pelo que está nos comentários, é muito mais rápido. Utiliza a instrução fistp do x86 para converter de float para int.

Desaparecido.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.