Por que o número inteiro mais comum é de 32 bits, mas o número de ponto flutuante mais comum é de 64 bits?

Vindo de um background em Java e C #, aprendi a usar int (32 bits) sempre que precisa de um número inteiro e double (64 bits) ao lidar com valores fracionários. A maioria dos métodos de seus respectivos frameworks (JVM e .NET) geralmente espera esses dois tipos.

Minha pergunta é: por que não usamos long e double para consistência? Eu sei que ter 64 bits de precisão em números inteiros não é necessário na maioria das vezes, mas, novamente, normalmente não precisamos de 64 bits de precisão em números de ponto flutuante, ou precisamos?

O que é o raciocínio por trás disso, se houver?

Comentários

  • ” Pode parecer que um carro alegórico ser suficiente para o que qualquer um poderia razoavelmente precisar, mas ‘ não … Na verdade, duplos de 64 bits com seus 15 dígitos decimais não são ‘ t bom o suficiente para muitos aplicativos … ” ( Por que você precisa float / double? )
  • Vindo de uma experiência C, eu ‘ aprendi a usar BigDecimal para números de ponto flutuante, desde arredondamento e comparar valores FP é tão problemático.
  • @TMN I ‘ Não tenho certeza de que um tipo que lança quando você tenta calcular 1/3 é a solução para tudo .

A nswer

Intervalo vs. precisão

Uma coisa é que eu contestaria a ideia de que o número de ponto flutuante mais comum usa uma representação DPFP (ponto flutuante de precisão dupla) de 64 bits.

Pelo menos em real de desempenho crítico campos de tempo como jogos, SPFP (ponto flutuante de precisão única) ainda é muito mais comum, já que a aproximação e a velocidade são preferíveis à precisão máxima.

No entanto, talvez uma maneira de ver isso é que um 32 -bit int representa um intervalo de 2^32 inteiros (~ 4,3 bilhões). O uso mais comum de inteiros provavelmente será como índices para elementos, e essa “uma gama bastante saudável de elementos que seria difícil de exceder sem exceder a memória disponível com o hardware de hoje *.

* Observe que erros de falta de memória podem ocorrer ao alocar / acessar um único bloco contíguo de 4 gigabytes mesmo com 30 gigabytes livres, por exemplo, devido à contiguidade requisitos desse bloco.

Um inteiro de 32 bits nem sempre é mais eficiente no nível de instrução, mas geralmente tende a ser mais eficiente quando agregado em um array, por exemplo, porque requer metade da memória (mais índices que podem caber em uma única linha de página / cache, por exemplo).

Observe também que como Lightness Races in Orbit aponta, não é necessariamente verdade, de uma perspectiva ampla, que inteiros de 32 bits são mais comumente usados. Tenho minha perspectiva limitada vindo de um campo onde ints de 32 bits são frequentemente agregados por centenas de milhares a milhões como índices em outra estrutura – aí, a redução do tamanho pode ajudar a .

Agora, o DPFP de 64 bits pode ser usado muito mais do que inteiros de 64 bits em alguns contextos. Lá, os bits extras estão adicionando precisão ao invés de alcance . Muitas aplicações podem exigir precisão, ou pelo menos ter uma programação de tempo muito mais fácil com precisão extra disponível. É provavelmente por isso que os DPFPs de 64 bits podem ser mais comuns do que inteiros de 64 bits em algumas áreas e porque int ainda pode ser de 32 bits em muitos cenários, mesmo em plataformas de 64 bits.

Comentários

  • Eu ‘ d contesto a ideia que o tipo de dados integral mais comum também tem 32 bits de largura, pelo menos em programas escritos hoje em hardware comum. As plataformas de 64 bits estão muito difundidas agora.
  • @I Ke: Suspeito que muitos softwares apenas usam int e long sem realmente se importar com o intervalo … e tal software, acredito, usa predominantemente inteiros de 64 bits em ambos os casos hoje em dia.
  • Hmm, estou corrigido; aparentemente int geralmente ainda é de 32 bits , principalmente para evitar a introdução de bugs apenas nesse tipo de código. Ok, bem, você ‘ ainda conseguiu size_t e long.
  • @LightnessRacesinOrbit Ah, entendo, ‘ sou extremamente tendencioso, pois geralmente trabalho em bases de código que agregam inteiros em alguma estrutura de dados com uma preocupação sobre o tamanho total da memória. Tentei tornar minha resposta o mais neutra possível.
  • @I ke: Pessoalmente, também faço todos os meus tipos de tamanho explícito.Mas você e eu somos sem dúvida anormais. 🙂

Resposta

Bem, int e double são coisas do Java. Por exemplo, em Objective-C e Swift você usaria NSInteger ou Int, que é de 32 bits em uma máquina de 32 bits e de 64 bits em uma máquina de 64 bits. Grande o suficiente para contar qualquer número de itens que possam estar na memória. O que é definitivamente útil é usar o mesmo tipo em quase todos os lugares, a menos que em uma situação particular você precise de outra coisa.

Java tenta ter código que execute o mesmo em qualquer implementação, então eles acham que você deve usar o mesmo tipo, independente da máquina que está usando, e que o tipo deve ter o mesmo número de bits, independente de a máquina. Objective-C e Swift (e C, C ++ também) têm um ponto de vista diferente.

Os inteiros são usados principalmente para contar coisas, e geralmente você não tem muitas coisas para contar. A aritmética de ponto flutuante precisa de precisão, e o ponto flutuante de 32 bits geralmente não oferece precisão suficiente. Usar o dobro de 64 bits em todos os lugares dá a você a chance de sempre ter precisão suficiente, sem ser um especialista em aritmética de ponto flutuante. float doesn “t.

Mas que consistência o uso de long e double forneceria? Inteiros e números de ponto flutuante não são a mesma coisa. Não há necessidade de eles terem tamanho de bit consistente. Eu uso pontos 2D e retângulos muito. Então, para consistência, eles também deveriam ter 64 bits? Pontos tendo 32 bits por componente e retângulos tendo 16? Claro que não. Não é necessária consistência.

Comentários

  • Esta é uma resposta muito boa explicando o lado JVM de manter o tamanho de cada tipo o mesmo, independentemente da plataforma.

Resposta

short, int, single e double têm o mesmo tamanho em java, pois são na maioria dos compiladores C comuns para plataformas de 32 e 64 bits e C como java claramente considera int como o tipo inteiro principal e double como o tipo principal de ponto flutuante. Acho que é razoável dizer que Java herdou essa convenção dos compiladores C comuns da época.

Inteiros geralmente são usado para c ontrar ou indexar coisas. É muito raro (embora não seja inédito) precisar contar ou indexar mais de 2 bilhões de alguma coisa. Na verdade, antes do C99, você tinha que usar tipos específicos do fornecedor se quisesse um inteiro de 64 bits.

Os números de ponto flutuante são geralmente usados como uma aproximação dos números reais. A precisão simples é boa o suficiente na maior parte do tempo, mas não é difícil encontrar problemas onde ela causa uma quantidade inaceitável de erros de arredondamento. Espero que a demanda da computação científica seja o que levou o suporte a ponto flutuante de precisão dupla a ser onipresente muito antes de 64 bits o suporte para inteiros era.

O que eu acho curioso é que C parece encorajar o uso de double, enquanto o fortran parece encorajar o uso de precisão simples.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *