Qual é o valor máximo de uma variável shell bash numérica?

11

Estou curioso para saber o que acontece quando uma variável numérica no bash é incrementada sem parar propositalmente. Quão grande o número pode chegar? Será que vai transbordar e se tornar negativo e apenas continuar a incrementar para sempre? Será que vai quebrar e derrapar até parar em algum momento?

Estou usando um processador AMD x86_64, mas eu ficaria feliz em ouvir respostas 32bit também, apenas especifique o que você está falando. Estou executando o Fedora21 64bit.

Eu pesquisei por toda a parte, mas não encontrei este artigo específico por algum motivo estranho. Parece que seria uma informação básica em todos os manuais e tal.

    
por Max Power 22.01.2016 / 22:05

3 respostas

14

Pode ser a versão do bash, do sistema operacional e da arquitetura da CPU. Por que você não tenta você mesmo? Defina uma variável para (2 ^ 31) -1, depois incremente-a, ajuste-a para 2 ^ 32, depois a incrementa, ajusta-a para 2 ^ 64, depois incrementa-a, etc.

Aqui, eu tentei eu mesmo no meu Core i7 Mac rodando OS X "El Capitan" v10.11.3, e parece que o bash está usando números inteiros de 64 bits assinados.

$ uname -a
Darwin Spiff.local 15.3.0 Darwin Kernel Version 15.3.0: Thu Dec 10 18:40:58 PST 2015; root:xnu-3248.30.4~1/RELEASE_X86_64 x86_64
$ bash --version
bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)
Copyright (C) 2007 Free Software Foundation, Inc.
$
$ ((X=2**16)); echo $X
65536                        <-- okay, at least UInt16
$ ((X=2**32)); echo $X
4294967296                   <-- okay, at least UInt32
$ ((X=2**64)); echo $X
0                            <-- oops, not UInt64
$ ((X=(2**63)-1)); echo $X
9223372036854775807          <-- okay, at least SInt64
$ ((X++)); echo $X
-9223372036854775808         <-- overflowed and wrapped negative. Must be SInt64
    
por 22.01.2016 / 22:29
3

Eu configurei um loop. %código% Eu iniciei logo abaixo de 2 ^ 31, deixei passar tanto 2 ^ 31 quanto 2 ^ 32 sem nenhum problema, parei com isso, então configurei o valor inicial para pouco menos de 2 ^ 63. O resultado foi que ele rolou de 9.22e18 para -9.22e18 e continuou a incrementar positivamente. (para zero)

Só para verificar se meu while return status is 0 increment a variable with addition and print the variable to stdout estava realmente usando o status de saída dos comandos dentro do loop while, não usando o status de saída do script anterior ou alguma estranheza, também o executei com um comando extra dentro do loop projetado para criar um status de saída diferente de zero em incrementos específicos.

Por isso, ele é assinado, ele será alternado em vez de parar no valor máximo, e será feito sem nenhuma mensagem de erro. Então é possível acabar em um loop verdadeiramente infinito. Ele não limita o hardware de 64 bits e o sistema operacional Linux de 64 bits a um padrão antigo de 16 ou 32 bits.

    
por 23.01.2016 / 01:19
0

bash usa um inteiro de 64 bits. Então, se você aumentar após a variável atingir seu número máximo, a variável irá estourar. Abaixo está o meu teste com int não assinado e inteiro assinado.

MAX_UINT = 18446744073709551615
MAX_INT = 9223372036854775807

$ printf "%llu\n" $((2**64))
0
$ printf "%llu\n" $((2**64-1))
18446744073709551615

$ printf "%lld\n" $((2**63-1))
9223372036854775807
$ printf "%lld\n" $((2**63))
-9223372036854775808
$ printf "%lld\n" $((2**64-1))
-1
    
por 13.07.2018 / 06:55