Como o printf arredonda as metades até a primeira casa decimal?

11

Estou testando duas implementações diferentes de printf no meu sistema: printf (GNU coreutils) 8.26 e a versão empacotada com zsh 5.3.1 . Eu estou testando como metade dos números são arredondados, ou seja, para 1,5, 2,5, 3,5, ... 9,5.

$ for i in {1..9}; do /usr/bin/printf '%.0f\n' "${i}.5"; done
2
2
4
4
6
6
8
8
10
$ for i in {1..9}; do printf '%.0f\n' "${i}.5"; done
2
2
4
4
6
6
8
8
10

Aqui, ambos claramente arredondam a metade para o . No entanto, quando eu testar o arredondamento para a primeira casa decimal, as coisas ficam confusas. Ou seja, estou testando para 1.15, 1.25, 1.35,… 1.95.

$ for i in {1..9}; do /usr/bin/printf '%.1f\n' "1.${i}5"; done
1.1
1.2
1.4
1.5
1.5
1.6
1.8
1.9
2.0
$ for i in {1..9}; do printf '%.1f\n' "1.${i}5"; done
1.1
1.2
1.4
1.4
1.6
1.6
1.8
1.9
1.9

Ambas as implementações fazem isso de maneira diferente, e não consigo ver nenhum padrão claro em nenhuma delas. Como essas duas metades printf s arredondam para a primeira casa decimal?

    
por Sparhawk 21.02.2017 / 05:21

1 resposta

19

GNU printf usa long double enquanto zsh usa% normal co_de % s . O comportamento de arredondamento que você vê é porque (digamos) 1.45 não pode ser representado como uma soma de potências de 2, que é como IEEE 754 flutuante A representação de ponto funciona e a aproximação mais próxima varia de acordo com a precisão. É um pouco mais (com 80 bits) ou menos (com 64 bits), arredondando para cima ou para baixo como você vê.

Como sempre, se você se preocupa com representações e arredondamentos precisos em nível humano, não use ponto flutuante.

    
por 21.02.2017 / 06:22

Tags