Liczby

Perl FAQ | RecentChanges | Preferences

1. Jak zamienić liczbę dziesiętną na binarną lub szesnastkową?
2. A na inną podstawę?
3. A binarną na dziesiętną?
4. Jak zamienić string na liczbę (i odwrotnie)?
5. Czy ciąg jest liczbą?
6. Jak zaokrąglić liczbę?
7. Jak poprawić format liczby?
8. Jak policzyć cyfry w liczbie?
9. Czy jest true/false?

1. Jak zamienić liczbę dziesiętną na binarną lub szesnastkową?

 print unpack("B*",pack("N",$liczba));        # na bin
 print unpack ("H2", pack ("C", $dec));	      # na hex
 printf "%x", $liczba;			      # na hex

2. A na inną podstawę?

 do {
   $wynik = chr(($reszta=$liczba % $podstawa) + 
     ($reszta>9 ? 87:48)) . $wynik;
 } while ($liczba = int ($liczba / $podstawa));
 print "$wynik\n";

Zamień 87 na 55 by litery były duże.

3. A binarną na dziesiętną?

 oct('0b'.$_);
 $a=reverse;$i=1;$_=0;$a=~s/./$_+=$i*$&,$i*=2/ge;
 $s=0;for(split//){$s*=2;$s+=$_}$_=$s;
 $s=0;($s*=2)+=$_ for/./g;$_=$s;
 s/./$s=$s*2+$&/ge;$_=$s;

4. Jak zamienić string na liczbę (i odwrotnie)?

Nie trzeba, perl robi to automatycznie, odwrotnie również.

Jeśli ktoś potrzebuje zapisać słownie liczbę, poleca się

 http://radek.karnet.pl/Number-SpellPolish-0.5.tar.gz

5. Czy ciąg jest liczbą?

Sprawdzenie czy string jest liczbą (same cyfry) w ogólności nie jest potrzebne, ale ...

 $zmienna =~ /^\d+$/

Bardziej zaawansowane sprawdzenie:

 $ciag =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/

lub

 $ciag =~ /^[+-]?\d+(\.\d*)?([eE][+-]?\d+)?$/;

6. Jak zaokrąglić liczbę?

 $liczba=int($liczba+0.5);       #Zaokraglanie do czesci calkowitej
 $liczba=sprintf "%.2f",$liczba; #Zaokraglanie do 2 miejsc
 $liczba=int($liczba);  #wyrzucenie po przecinku

Przy zaokrąglaniu funkcją typu printf, sprawdź czy o takie zakrąglanie ci chodzi wpisując poniższe dwie linie (chodzi o zaokrąglanie przy równej odległości):

 printf "%.0f", 0.5;
 printf "%.0f", 1.5;

Oprócz funkcji int, są jeszcze ceil i floor z modułu POSIX, działające według tabeli:

 liczba    int    floor   ceil
  3.3      3.0     3.0     4.0
  3.5      3.0     3.0     4.0
  3.7      3.0     3.0     4.0
 -3.3     -3.0    -4.0    -3.0

Funkcja ceil inaczej to:

 int($x)==$x ? $x : int($x)+1

7. Jak poprawić format liczby?

 #Format po 3 cyfry
 $string=scalar reverse join " ",grep length,split /(\d{3})/,reverse
  $liczba;

 #Zamiast powyższych 3 linii - dwa razy wolniej
 1 while s/(.*\d)(\d{3})/$1 $2/;

Można też zastosować moduł Number::Format.

8. Jak policzyć cyfry w liczbie?

W ogólnym przypadku dobrze jest skorzytać z funkcji logarytm dziesiętny, na podstawie wbudowanej funkcji log (logarytm naturalny):

 log10(x) = log (x) / log (10)

W większości zastosowań zamiast int(log($x)/log(10)+1) można stosować prostszą i szybszą konstrukcję (poza przedziałem (0,1) oraz zapisem typu 1e13):

 length(int($x))

trochę wolniejsza, lecz poprawna dla dużych liczb jest

 length(sprintf "%.0f", $x)

9. Czy jest true/false?

Nie ma, należy sobie zdefiniować, przy czym zmienna, która jest pusta, niezdefiniowana, lub równa wartości 0 uznawana jest zawsze jako fałsz, pozostałe wartości zmiennej to prawda.

 use constant true  => 1;
 use constant false => 0;

Perl FAQ | RecentChanges | Preferences
This page is read-only | View other revisions (diff)
Search:
Strona znajduje się na serwerze KT AGH.