Rust: Adicionar suporte para literais flutuantes hexadecimais

Criado em 5 jan. 2012  ·  17Comentários  ·  Fonte: rust-lang/rust

Precisamos ser capazes de analisar a saída de% a de printf para suporte adequado de constantes matemáticas sem perda de precisão
(ou seja, sintaxe 0x1.fffffffffffffp + 1023_f64)

A-frontend E-easy

Comentários muito úteis

Os flutuadores hexadecimais são bastante populares entre as bibliotecas matemáticas C. E eu adoraria usá-los no Rust também.

Vejo que o float hexadecimal foi implementado na ferrugem como uma extensão, depois movido para uma caixa separada e agora está em rust-deprecated e não consegue compilar com a ferrugem noturna.

Qual é o futuro deste recurso?

Todos 17 comentários

Eu brinquei com esse problema e concluí que infelizmente ele reaviva o problema nº 1306. O lexer atual proíbe qualquer caractere alfa após . por causa disso. Podemos escolher permiti-los seletivamente quando o padrão 0x<digits>. for encontrado, mas parece muito inconsistente e pode requerer infinito lookahead se quisermos elidir uma inconsistência.

Sugiro exigir um dígito ou 0x ou 0b após o ponto. Isso evita a colisão e (curiosamente) permite que você troque de radix no meio-literal, se desejar. E é apenas um pouco mais feio do que o que o C99 faz você escrever.

@graydon Ou podemos exigir apenas zeros após o ponto. (por exemplo, 0x1fffffffffffff.0p+972_f64 vez de 0x1.fffffffffffffp+1023_f64 )

Não acredito que isso seja incompatível com as versões anteriores, renomear.

aceito para marco completo de recursos

visitado para triagem de 15/07/2013. Nós realmente definimos uma sintaxe aqui? Parece que pode ser uma tarefa fácil e agradável para um novo contribuidor _se_ pudermos fornecer a ele uma especificação clara da sintaxe; mas se a sintaxe ainda está na fase de design, então essa afirmação é menos verdadeira.

Acho que ainda não acertamos em cheio na sintaxe, mas devo salientar que é necessário evitar a colisão com sufixos (alguns dos quais começam com f, um dígito hexadecimal), então acho que se fizermos isso, só funcionará para especificando a mantissa, e somente quando combinada com um expoente completo (em decimal).

Isso ainda não foi implementado.

Não 1.0

Os flutuadores hexadecimais são bastante populares entre as bibliotecas matemáticas C. E eu adoraria usá-los no Rust também.

Vejo que o float hexadecimal foi implementado na ferrugem como uma extensão, depois movido para uma caixa separada e agora está em rust-deprecated e não consegue compilar com a ferrugem noturna.

Qual é o futuro deste recurso?

Também interessado nisso. Estou procurando implementar um sistema de física repetível para um jogo, que requer resultados consistentes em todos os computadores. Literais hexadecimais flutuantes me permitiriam escrever valores de ponto flutuante com precisão de bits em testes e constantes.

No mínimo, uma declaração de porque esse recurso está sendo preterido seria apreciada, já que este segmento é o primeiro resultado que obtenho para "literal de flutuação hexadecimal ferrugem".

A situação está um pouco nojenta no momento. As macros procedurais estão passando por uma reformulação agora (# 38356) e, portanto, seria pelo menos uma perda de tempo manter hexfloat atualizados enquanto isso está acontecendo. Mas não sei como será a história depois disso.

Se meu entendimento estiver correto, flutuantes hexadecimais em C / C ++ existem porque flutuantes decimais não são garantidos para arredondar corretamente [1]. Em Rust, no entanto, após # 27307 --- eu suspeito que isso não seja necessariamente intencional! --- quase todos os flutuadores decimais (# 31407 descreve casos extremos que são praticamente irrelevantes) devem arredondar para o mais próximo, então você pode apenas fornecer rustc um número apropriado (digamos, 30) de dígitos fracionários e obterá o número arredondado corretamente. Esta seria uma resposta "prática" por enquanto.

Uma coisa para a qual ainda acho que os floats hexadecimais são relevantes é uma conversão de C / C ++. Você não gostaria de converter todos os flutuantes hexadecimais em decimais :) Recentemente escrevi uma macro procedural experimental que faz exatamente isso, convertendo flutuantes hexadecimais em flutuantes decimais (que rustc pode entender), mas estava relutante em lançar um porque o o status quo não foi realmente garantido até agora - é pura sorte, na minha opinião. Se houver uma maneira de construir um float com padrão de bits exato apenas a partir de constexprs, irei adaptá-la.

[1] Por exemplo, ISO C99 requer apenas que flutuações decimais sejam convertidas em um número representável dentro de ± 1,5 ulps ("o resultado é o valor representável mais próximo ou o valor representável maior ou menor imediatamente adjacente ao valor representável mais próximo" )

@lifthrasiir , mais cedo ou mais tarde gostaria de consertar https://github.com/jameysharp/corrode/issues/73 traduzindo corretamente floats hexadecimais C para Rust, então gostaria de entender melhor seu comentário. Ainda não li o suficiente sobre questões de ponto flutuante para entender o que está envolvido aqui.

Você está dizendo que, bugs do compilador do módulo Rust, cada literal hex-float pode ser convertido em um literal float decimal que o compilador Rust converterá para o mesmo padrão de bits? Nesse caso, ficaria feliz se o Corrode fizesse essa conversão. Você pode recomendar uma referência que devo ler para um algoritmo para fazer essa conversão corretamente? (Um indicador para sua macro procedural seria ótimo, mas o ideal é que eu também tenha um artigo ou livro para citar.)

Dito isso, deduzo que a versão decimal exata de um float hexadecimal pode ter muito mais dígitos (certo?), Então talvez a versão hex-float seja mais fácil de ler e entender, pelo menos para pessoas que se preocupam o suficiente com a precisão numérica para usá-los . Se hex floats são a forma preferida pelos humanos para esses números, eu diria que Rust deveria suportá-los. Então, IMO, mais feedback de pessoas que usaram flutuadores hexagonais ajudariam aqui.

Você está dizendo que, bugs do compilador do módulo Rust, cada literal hex-float pode ser convertido em um literal float decimal que o compilador Rust converterá para o mesmo padrão de bits?

Minha crença é sim.

Você pode recomendar uma referência que devo ler para um algoritmo para fazer essa conversão corretamente?

Você não precisa implementar isso, porque o compilador Rust atual e a biblioteca padrão implementam todos os algoritmos necessários (o que é mais difícil :-). Se você realmente precisar de referências, consulte o seguinte:

  • A conversão de binário para decimal ("flt2dec", # 24612) é um híbrido de [Dragon4] e [Grisu3].

    • [Dragon4]: Burger, RG e Dybvig, RK 1996. Impressão de números de ponto flutuante com rapidez e precisão. SIGPLAN Não. 31, 5 (maio de 1996), 108-116.
    • [Grisu3]: Florian Loitsch. 2010. Impressão de números de ponto flutuante com rapidez e precisão com inteiros. SIGPLAN Não. 45, 6 (junho de 2010), 233-243.
  • A conversão de decimal para binário ("dec2flt", # 27307) é um par de algoritmos descritos por [Clinger]. (Eu não os implementei, portanto, meu conhecimento sobre eles é limitado.)

    • [Clinger]: William D. Clinger. 1990. Como ler números de ponto flutuante com precisão. SIGPLAN Não. 25, 6 (junho de 1990), 92-101.

Para registro, minha implementação é lifthrasiir / hexf (publicado agora, ainda não em crates.io). Sinta-se à vontade para atender.

Dito isso, deduzo que a versão decimal exata de um float hexadecimal pode ter muito mais dígitos (certo?), [...] Se os floats hexadecimais forem a forma preferida pelos humanos para esses números, eu diria que o Rust deveria suportá-los . [...]

Não exatamente, por exemplo, 0x1.999999999999bp-4 = 0.10000000000000002 . Não tenho opinião se o Rust deve suportar hex floats ou não.

Agora publiquei formalmente hexf para crates.io . @jameysharp , acho que você provavelmente pode usar hexf-parse para o seu trabalho. (A sintaxe sem sublinhados devem ser idênticos quase o mesmo para C99 hexadecimal-floating-constant sans não-terminal opcional floating-suffix .)

Edit: Aargh, perdi um caso. 0x1p1 deve ser válido, mas hexf não o reconhece; provavelmente é fácil de contabilizar, no entanto.

Caso de uso semelhante para mim também; Gostaria de poder gerar código ferrugem de um compilador, sem perda de precisão para literais float.

Esta página foi útil?
0 / 5 - 0 avaliações