Printf yuvarlak yarıları ilk ondalık basamağa nasıl çevirir?


11

printfSistemimde iki farklı uygulamayı test ediyorum : printf (GNU coreutils) 8.26ve birlikte verilen sürüm zsh 5.3.1. Yarım sayıların nasıl yuvarlandığını test ediyorum, yani 1.5, 2.5, 3.5,… 9.5 için.

$ 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

Burada, her ikisi de açıkça yarıya eşittir . Ancak, ilk ondalık basamağa yuvarlamayı test ettiğimde işler kafa karıştırıyor. Yani, 1.15, 1.25, 1.35,… 1.95 için test yapıyorum.

$ 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

Her iki uygulama da farklı şekilde yapıyor ve ben de net bir örüntü göremiyorum. Bu iki printfyarı yarıya ilk ondalık basamağa nasıl dönüşür?

Yanıtlar:


19

GNU printf kullanılırkenlong double zsh normal doubles kullanır . Gördüğünüz yuvarlama davranışı, (diyelim) 1.45'in, 2'nin güçlerinin toplamı olarak temsil edilememesidir, bu nedenle IEEE 754 kayan nokta gösterimi nasıl çalışır ve en yakın yaklaşım hassasiyete göre değişir. Biraz daha fazla (80 bit ile) veya daha az (64 bit ile), böylece gördüğünüz gibi yukarı veya aşağı yuvarlanıyor.

Her zamanki gibi, doğru insan seviyesinde temsil ve yuvarlamayı önemsiyorsanız, kayan nokta kullanmayın.


1
Sadece x.25 ve x.75'in (uygun olarak küçük x için) diğerlerinden farklı olarak tam ikili gösterimlere sahip olduğuna dikkat edin.
Toby Speight
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.