Em idiomas que não permitem sublinhados em literais inteiros , é uma boa ideia criar uma constante para 1 bilhão? por exemplo, em C ++:
size_t ONE_BILLION = 1000000000;
Certamente, não devemos criar constantes para números pequenos como 100. Mas com 9 zeros, é sem dúvida fácil deixar um zero ou adicionar um extra no código como este:
tv_sec = timeInNanosec / 1000000000;
tv_nsec = timeInNanosec % 1000000000;
coding-style
Martin C. Martin
fonte
fonte
1e9
,10^9
ou1_000_000_000
se o idioma que você estiver usando o suportar.Respostas:
A maioria dos idiomas apresenta algum tipo de notação exponencial. Um milhão é
1e6
(significando 1 vezes 10 à potência de 6). Isso basicamente resolve o problema ainda melhor do que a maioria das proposições aqui.Em muitas linguagens C, a notação científica está definindo um tipo de ponto flutuante , o que é lamentável se você realmente precisa de um int. No entanto, você pode facilmente converter essa constante para evitar conversões implícitas no seu formulário.
n / int(1e9)
dividiria por um bilhão.No seu exemplo, lidando com quantidades físicas (tempo em nanossegundo), eu geralmente me perguntava se número inteiro é o tipo certo. De fato, um ponto flutuante
double
pode ser mais adequado ao lidar com quantidades mensuráveis (embora haja casos em que você preferirialong long
).fonte
long long
intervalo.Crie um chamado NANOSECONDS_IN_ONE_SECOND como o que ele representa.
Ou um nome melhor e mais curto, se você puder pensar em um.
fonte
Nanoseconds_Per_Second
mas esta é, na minha opinião, a resposta correta.NANOSECONDS
não teria sentido, pois você não pode dizer a que deve se aplicar. Da mesma forma,NANOSECONDS_PER_MICROSECOND
é uma constante válida semelhante que faz sentido.1mm/1m = 1000
, que é exatamente o ponto do que está sendo feito aqui.NS_PER_SEC
deve ser óbvio para quem deveria lidar com nanossegundos.As constantes são destinadas a dar significado aos números. Não há nenhum significado adicional em
ONE_BILLION
para1000000000
. Na verdade, isso fica mais confuso, porque em diferentes idiomas naturais, um bilhão significa algo diferente (mil milhões ou milhões)! Se você quiser escrever mais curto, há uma boa chance de sua linguagem de programação permitir o uso de notação científica, ou seja1e9
. Caso contrário, eu concordo com @JohnB, que esse número realmente significa o número de nanossegundos em um segundo, então nomeie isso.fonte
Para um ou dois usos, eu usaria a convenção:
É perfeitamente auto-explicativo, é compilado para uma constante e é difícil de estragar.
Além disso, é muito útil em casos como:
onde é fácil ver que estamos falando de um dia em segundos.
fonte
instance.Time = ...
, mas então eu o emburreci ...(1000 * 1000 * 1000)
é do tipoint
, que requer apenas 16 bits, para que possa estourar. Você pode escrever(1000L * 1000L * 1000L)
para evitar isso.O comprimento do valor não é o que define se uma constante é necessária ou não.
Você usa constantes para evitar números mágicos , não para digitar.
Por exemplo, estas são constantes perfeitamente válidas:
Usar:
(as amostras de código estão em Java, traduzem para o seu idioma favorito)
fonte
Um bilhão americano ou europeu?
(ou em termos técnicos, um bilhão em pequena ou longa escala - um é de 1000 milhões, o outro é um milhão).
Dada essa confusão, então eu diria que sim - faz sentido defini-la uma vez e continuar com ela, da mesma forma se aplica a qualquer constante em que você precisa concordar com a definição - defina-a uma vez.
fonte
Razões para não
Primeiro, aqui está uma razão para não escrever sublinhados ou usar qualquer truque para simulá-lo: torna as constantes mais difíceis de encontrar no código. Suponha que algum programa exiba, em algum lugar de sua operação, o valor codificado 1500000 para algum parâmetro. Quero saber onde isso realmente ocorre no código-fonte do programa, por isso espero o código
1500000
e não encontro nada. Por quê? Pode estar em hexadecimal (mas por que, para um número decimal tão redondo). Sem o meu conhecimento, a constante é realmente escrita como1_500_000
. Eu precisava do regex1_?500_?000
.Caracteres orientadores no comentário
Só porque um tipo de auxílio visual não está disponível, ou não queremos usá-lo pelo motivo acima, não significa que não possamos tirar proveito das duas dimensões do arquivo de texto para criar um auxílio visual alternativo:
Com isso, podemos facilmente nos convencer de que existem três grupos de três zeros. No entanto, ainda podemos
1000000000
encontrar e encontrar o código-fonte .Coloração de sintaxe
Um editor de texto com coloração de sintaxe programável pode ser feito para grupos de dígitos de cores em constantes numéricas com cores alternadas para melhor legibilidade. Não precisamos fazer nada no código.
Pré-processamento: C, C ++, Objetivo C
Agora, se realmente queremos vírgulas entre dígitos, em C e C ++, podemos usar algum pré-processamento:
Funciona para números como
TH(1,234,567,890)
.Uma macro semelhante ao TH também pode trabalhar com colagem de token em vez de aritmética. No pré-processador C, o
##
operador binário ("pasta de token") pode ser usado em um corpo de macro para colar dois operandos em um único token. Um ou ambos os operandos podem ser argumentos de macro. A desvantagem aqui (criando um risco para nós) é que, se a catenação resultante não for um token válido, o comportamento será indefinido.Agora
Existem programas C que colam identificadores e usam os resultados para nomear variáveis e funções globais e são difíceis de trabalhar porque são impermeáveis a ferramentas como GNU id-utils e ctags.
fonte
Sim, isso parece uma ideia razoável. Erros DIGIT de um por um são ainda piores do que os infames erros de um por um. No entanto, isso pode criar confusão para outras pessoas (incluindo seu futuro eu) lerem o código.
Um nome mais explicativo como NANOSEC_PER_SEC parece bom, pois adicionaria clareza onde é usado durante o tempo. No entanto, não faz sentido usar em contextos diferentes do tempo e seria impraticável criar 1.000.000.000 separados para cada situação.
O que você realmente quer fazer, por mais bobo que pareça, é 'dividir por segundo'. Isso deixa o NANO_PER, que não é apenas independente do idioma (10 ^ 9 na América e na Europa), mas também independente da situação (sem limitações nas unidades), e é fácil digitar e ler.
fonte
Em geral, é uma má idéia usar constantes escalares para conversões de unidades e, se você se encontrar criando constantes para essas coisas, está convertendo em muitos lugares.
Quando você tem uma quantidade de uma unidade (digamos, 10 segundos) e deseja converter para outra unidade (ou seja, nanossegundos); este é precisamente o momento de usar o sistema de tipos do seu idioma para garantir que as unidades sejam realmente dimensionadas conforme você deseja.
Fazer a sua função ter um
Nanoseconds
parâmetro e fornecer aos operadores de conversão e / ou construtores em que a classe deSeconds
,Minutes
ou que-ter-você. É aqui que o seuconst int
ou#define
ou1e9
visto em outras respostas pertence.Isso evita ter variáveis de unidades ambíguas flutuando em torno do seu código; e evita faixas inteiras de bugs de onde a multiplicação / divisão errada foi aplicada, ou já foi aplicada, ou a quantidade era realmente a distância em vez do tempo, ou ...
Além disso, nessas classes, é bom criar uma construção a partir de escalares simples e usar um "MakeSeconds (int)" estático ou semelhante para desencorajar o uso desleixado de números opacos.
Mais especificamente para o seu exemplo, em C ++, verifique Boost.Chrono .
fonte
Eu, pessoalmente, não consideraria uma boa prática criar uma constante, a menos que precise ser uma constante. Se for em vários lugares e tê-lo definido na parte superior do arquivo para modificação / teste será útil, então absolutamente.
Se é apenas porque é difícil de digitar? então não.
Pessoalmente, se eu obtive o código de outra pessoa com uma constante definida, geralmente considero esse um aspecto importante do código. Por exemplo, tcp mantém temporizadores ativos, número máximo de conexões permitido. Se eu tivesse que depurá-lo, provavelmente prestaria muita atenção desnecessária a ele, tentando descobrir por que / onde está sendo usado.
fonte
Quando você pensa sobre o motivo de ter escrito "1 bilhão" em vez de "1000000000" no título da sua pergunta, perceberá porque a resposta é sim.
fonte
Não crie uma constante para seus grandes literais. Você precisaria de uma constante para cada um desses literais, o que é (na minha opinião) uma piada completa. Se você precisar desesperadamente tornar seus literais mais claros sem a ajuda de coisas como destaque de sintaxe, você poderá (embora eu não o faça) criar funções ou macros para tornar sua vida "mais fácil":
fonte
Eu faria isso:
ou
const int
SciMega = 1000 * 1000; const intSciGiga = 1000 *SciMega;Em relação ao número de nanossegundos por segundo: nano é o "inverso" de giga.
Observe o "Sci" - para científico, como em computadores, os significados de quilo, mega, giga etc. são diferentes: 1024 (2 ^ 10), 1024 * 1024 (2 ^ 20) etc. 2 megabytes não são 2.000.000 bytes .UPDATE Commenter apontou que existem termos especiais para expoentes digitais de 2: http://en.wikipedia.org/wiki/Mebibyte
fonte