awk

2013-02-13 14 views
14

Tam sayı bölme kullanarak, yani sonucu kesen iki sayıyı awk numaralı bölüme ayırmak istiyorum. Örneğinawk

için
k = 3/2 
print k 

, the manual göre

Bölümü 1

yazdırmalısınız; awk tüm sayılar sayılar noktalı kayan çünkü, sonuç bir tamsayı

bir tamsayı değeri almak için herhangi bir geçici çözüm var mı yuvarlanır değil mi?

nedeni

I [num-1-0] tamsayıdır dizinler ile bir dizi orta eleman almak isterler.

cevap

27

Bu int(-3/2) -1, int(3/2) 1, sonuç ve örneğin 0 arasında yer alan sonuca en yakın tam sayı üretir 0 doğru kesildi tamsayı kısmı, elde etmek için int işlevini kullanın.

Kaynak: Basit vakalarda The AWK Manual - Numeric Functions

4

, güvenle sıfır doğru keser hangi int() kullanabilirsiniz: Her zaman awk Unutmayın

awk 'BEGIN { print int(3/2) }' # prints 1 
gawk 'BEGIN { print int(-3/2) }' # prints -1; not guaranteed in POSIX awk 

kayan nokta sayıları çift kesinlikli kullanır 2 Yine de ve kayan noktalı aritmetik . Tamsayılar ve tamsayı aritmetiğini alabilmenin tek yolu, harici araçları kullanmaktır, örn. Standart expr yarar:

awk 'BEGIN { "expr 3/2" | getline result; print result; }' # prints 1 

Bu gerçekten yavaş ... ama güvenli ve taşınabilir uzun awk koğuş, vardır. POSIX awk olarak


sıfıra kesme sadece olumlu bağımsız değişkenler için garanti edilir: int (x) - bir tamsayı olarak kesildi bağımsız değişken dönün. Kesim x> 0 olduğunda 0'a doğru olmalıdır. GNU awk (gawk), negatif sayılar için bile sıfıra doğru kesmeyi kullanır: int (x) - En yakın tam sayıyı x ile sıfır arasında bulunan ve sıfıra doğru kesilmiş olan x olarak döndür. Örneğin int (3) 3, int (3.9) 3, int (-3.9) -3 ve int (-3) -3 de.
Sayısal ifadeler, POSIX'te Expressions in awk numaralı belgede çift kesinlikli yüzer olarak belirtilir.
Tüm aritmetik ISO C standardında belirtildiği gibi kayan nokta aritmetik semantiğini (Concepts Derived from the ISO C Standard bakınız) takip edecektir. - Eğer yüzen kullanmayı seçerseniz POSIX awk: Arithmetic functions


, onların tuhaflıklar hakkında bilmek ve onları tespit ve ilgili hataları önlemek hazır olmalıdır. Çeşitli korkutucu örnekler:

  • temsil edilemeyen numaraları:

    awk 'BEGIN { x = 0.875; y = 0.425; printf("%0.17g, %0.17g\n", x, y) }' 
    # prints 0.875, 0.42499999999999999 
    
  • Round-off errors birikimi:

    awk 'BEGIN{s=0; for(i=1;i<=100000;i++)s+=0.3; printf("%.10f, %d\n",s,int(s))}' 
    # prints 29999.9999999506, 29999 
    
  • Yuvarlama hataları bozmak karşılaştırmalar:

    awk 'BEGIN { print (0.1 + 12.2 == 12.3) }' # prints 0 
    
  • Hassas sonsuz döngüler neden büyüklüğü ile azalır:

    1. yığın taşması etiketler wiki

    2. Wikipedia makalesi Floating point

    3. : Daha fazla iş yüzen nasıl Oku

      awk 'BEGIN { for (i=10^16; i<10^16+5; i++) printf("%d\n", i) }' 
      # prints 10000000000000000 infinitely many times 
      

  • GNU awk arbitrary precision arithmetic - özgü uygulanması ve genel kültür hem bilgi içeren

  • +0

    Ben nispeten için (yüzer hatalarını gidermek için bir yol sanırım küçük sayılar) int (3/2 + 0.25) 'yapmaktır. – user000001

    +0

    @ user000001 Sabit eklemek sorunu çözmez, aslında yeni bir tane ekler. 'awk' BEGIN {print int (7/8), int (7/8 + 0,25)} ''' 0 '' üretir. – Palec

    +0

    Evet, 1/(d/2) 'den daha az olmalı, burada 'd' paydadır. Bu değer kayan hatadan daha büyük olduğu sürece çalışmalıdır. – user000001

    5

    Güvenli ve hızlı awk tamsayı bölme ile yapılabilir:

    q=(n-n%d)/d+(n<0) 
    
    +0

    +1. Zeki numara, sana bunu vereceğim. @Palec'in açıkladığı gibi hassas hatalar için güvenli olup olmadığını merak ediyorum ... – user000001

    +0

    +1 Bu, bir 'ceil' tipi yuvarlama (+ inf'ye doğru) uygular. Diğer matematiksel olarak doğru mod kavramları ve sonuç olarak yuvarlama yöntemleri vardır. Başka bir yöntem tercih edilebilir. – sorontar

    +0

    @sorontar En azından sistemimde, bu bir 'ceil' işlevine eşdeğer değil –