Skróć (nie zaokrąglij) liczby dziesiętne w javascript


93

Próbuję skrócić liczby dziesiętne do miejsc dziesiętnych. Coś takiego:

5.467   -> 5.46  
985.943 -> 985.94

toFixed(2)robi właściwie, ale zaokrągla wartość. Nie potrzebuję zaokrąglenia wartości. Mam nadzieję, że jest to możliwe w javascript.


6
jQuery to tylko framework, a twój problem nie jest związany z jQuery. Chodzi bardziej o wykonanie podstawowych obliczeń w JavaScript. Mam nadzieję, że rozwiązanie inne niż jQuery również Ci odpowiada.
Felix Kling

Okazało się, że wymagało to zbyt wiele pracy, aby moje obliczenia zwracały tylko 2 miejsca po przecinku za pomocą JavaScript. Zamiast tego mogłem to łatwo zrobić w moim widoku bazy danych. Zdaję sobie sprawę, że ta metoda nie będzie pasować do każdej sytuacji, ale chcę ją tutaj przedstawić, ponieważ może to komuś zaoszczędzić dużo czasu.
MsTapp

Odpowiedzi:


51

upd :

Okazało się, że zaokrąglanie błędów zawsze będzie cię prześladować, bez względu na to, jak bardzo będziesz próbował je zrekompensować. Dlatego problem należy rozwiązać, przedstawiając liczby dokładnie w notacji dziesiętnej.

Number.prototype.toFixedDown = function(digits) {
    var re = new RegExp("(\\d+\\.\\d{" + digits + "})(\\d)"),
        m = this.toString().match(re);
    return m ? parseFloat(m[1]) : this.valueOf();
};

[   5.467.toFixedDown(2),
    985.943.toFixedDown(2),
    17.56.toFixedDown(2),
    (0).toFixedDown(1),
    1.11.toFixedDown(1) + 22];

// [5.46, 985.94, 17.56, 0, 23.1]

Stare, podatne na błędy rozwiązanie oparte na kompilacji innych:

Number.prototype.toFixedDown = function(digits) {
  var n = this - Math.pow(10, -digits)/2;
  n += n / Math.pow(2, 53); // added 1360765523: 17.56.toFixedDown(2) === "17.56"
  return n.toFixed(digits);
}

4
Tak, prototypy nie działają niezawodnie w różnych przeglądarkach. Zamiast definiować tę funkcję (o ograniczonym przeznaczeniu) za pomocą systemu typów, w sposób, który nie działa niezawodnie, dlaczego nie umieścić jej po prostu w bibliotece.
Thomas W.

3
To nie działa jak wyjątek. Wypróbuj liczbę 17,56, a cyfry = 2. Powinno wynosić 17,56, ale ta funkcja zwraca 17,55.
shendz,

2
Dwie niespójności z tą funkcją: Ta funkcja zwraca ciąg, więc 1.11.toFixedDown(1) + 22kończy się jako 1.122zamiast 23.1. 0.toFixedDown(1)Powinien także produkować, 0ale zamiast tego produkuje -0.1.
Nick Knowlson,

5
Zauważ, że ta funkcja usuwa znak ujemny. Np (-10.2131).toFixedDown(2) // ==> 10.21. : .
rgajrawala

4
Również (1e-7).toFixedDown(0) // ==> 1e-7. Robi to za 1e-(>=7)(ex: 1e-8, 1e-9, ...).
rgajrawala

60

Odpowiedź Dogberta jest dobra, ale jeśli twój kod może mieć do czynienia z liczbami ujemnymi, Math.floorsam w sobie może dać nieoczekiwane wyniki.

Np. Math.floor(4.3) = 4AleMath.floor(-4.3) = -5

Zamiast tego użyj funkcji pomocniczej, takiej jak ta, aby uzyskać spójne wyniki:

truncateDecimals = function (number) {
    return Math[number < 0 ? 'ceil' : 'floor'](number);
};

// Applied to Dogbert's answer:
var a = 5.467;
var truncated = truncateDecimals(a * 100) / 100; // = 5.46

Oto wygodniejsza wersja tej funkcji:

truncateDecimals = function (number, digits) {
    var multiplier = Math.pow(10, digits),
        adjustedNum = number * multiplier,
        truncatedNum = Math[adjustedNum < 0 ? 'ceil' : 'floor'](adjustedNum);

    return truncatedNum / multiplier;
};

// Usage:
var a = 5.467;
var truncated = truncateDecimals(a, 2); // = 5.46

// Negative digits:
var b = 4235.24;
var truncated = truncateDecimals(b, -2); // = 4200

Jeśli to nie jest pożądane zachowanie, wstaw wywołanie do Math.absw pierwszej linii:

var multiplier = Math.pow(10, Math.abs(digits)),

EDYCJA: shendz poprawnie wskazuje, że użycie tego rozwiązania w a = 17.56przypadku nieprawidłowego wyprodukowania 17.55. Aby dowiedzieć się więcej o tym, dlaczego tak się dzieje, przeczytaj artykuł Co każdy informatyk powinien wiedzieć o arytmetyce zmiennoprzecinkowej . Niestety, napisanie rozwiązania, które eliminuje wszystkie źródła błędów zmiennoprzecinkowych, jest dość trudne w przypadku javascript. W innym języku użyłbyś liczb całkowitych lub może typu dziesiętnego, ale z javascript ...

To rozwiązanie powinno być w 100% dokładne, ale będzie też wolniejsze:

function truncateDecimals (num, digits) {
    var numS = num.toString(),
        decPos = numS.indexOf('.'),
        substrLength = decPos == -1 ? numS.length : 1 + decPos + digits,
        trimmedResult = numS.substr(0, substrLength),
        finalResult = isNaN(trimmedResult) ? 0 : trimmedResult;

    return parseFloat(finalResult);
}

Dla tych, którzy potrzebują szybkości, ale chcą również uniknąć błędów zmiennoprzecinkowych, spróbuj czegoś takiego jak BigDecimal.js . Inne biblioteki javascript BigDecimal można znaleźć w tym pytaniu SO: „Czy istnieje dobra biblioteka BigDecimal Javascript?” a oto dobry wpis na blogu o bibliotekach matematycznych dla JavaScript


Dlaczego nieoczekiwany? Zmiana kierunku zaokrąglania, gdy spadasz poniżej 0, powoduje różnego rodzaju artefakty arytmetyczne i kiepską matematykę. Na przykład dwa razy więcej liczb zostanie zaokrąglonych do 0, niż każda inna liczba całkowita. W przypadku grafiki, księgowości i wielu innych zastosowań uzyskasz kiepskie wyniki. Mówiąc prawdę, byłoby trudniej powiedzieć, co się propozycja jest dobra tak powiedzieć, co to jest nie .
Thomas W.

Jest to dobre dla dokładnie tego, co jest napisane - gdy chcesz skrócić ułamki dziesiętne zamiast zaokrąglać.
Nick Knowlson,

1
Nie będzie działać z 17,56, ponieważ przeglądarka podaje 17,56 * 100 = 1755.9999999999998, a nie 1756
shendz

Słuszna uwaga shendz. Zaktualizowałem moją odpowiedź rozwiązaniem, które eliminuje wszystkie błędy zmiennoprzecinkowe dla tych, którzy tego potrzebują.
Nick Knowlson

1
To nie zadziała dla liczb, które są mniejsze niż 1, jeśli nie chcesz używać liczb dziesiętnych - truncateDecimals (.12345, 0) daje wynik NaN, chyba że dodasz czek: if(isNAN(result) result = 0; Zależy od żądanego zachowania.
Jeremy Witmer

35
var a = 5.467;
var truncated = Math.floor(a * 100) / 100; // = 5.46

5
Działa to dobrze, ale da wyniki, które są prawdopodobnie niepożądane, jeśli on (lub ktoś inny, patrząc na tę odpowiedź później) będzie musiał radzić sobie z liczbami ujemnymi. Zobacz stackoverflow.com/a/9232092/224354
Nick Knowlson,

3
Dlaczego niepożądane? Zmiana kierunku zaokrąglania, gdy spadniesz poniżej 0, powoduje różnego rodzaju artefakty arytmetyczne.
Thomas W.

8
Istnieje różnica między zaokrąglaniem a obcięciem. Obcinanie jest wyraźnie zachowaniem, którego dotyczy to pytanie. Jeśli zadzwonię truncate(-3.14)i otrzymam -4odpowiedź, zdecydowanie nazwałbym to niepożądanym.
Nick Knowlson

Zgadzam się z Thomasem. Różnica w perspektywie może wynikać z tego, czy zwykle obcinasz w celu wyświetlenia, czy do obliczeń. Z punktu widzenia obliczeń pozwala to uniknąć „artefaktów arytmetycznych”

3
var a = 65.1 var truncated = Math.floor(a * 100) / 100; // = 65.09 Dlatego nie jest to właściwe rozwiązanie
Sanyam Jain

22

Możesz naprawić zaokrąglenie, odejmując 0,5 dla toFixed, np

(f - 0.005).toFixed(2)

1
Uwaga: ponieważ to nie działa w przypadku bardzo małych liczb, liczb z więcej niż 3 miejscami po przecinku lub liczb ujemnych. Spróbuj .0045, 5.4678 i -5.467
Nick Knowlson

Będzie to działać, o ile dopasujesz wartość, którą odejmujesz, do długości, którą chcesz mieć. cokolwiek przekazujesz do toFixed (), musi być liczbą 0 po przecinku.
dmarra

18

Rozważyć wykorzystanie podwójnego tyldy:~~ .

Weź pod uwagę liczbę. Pomnóż przez cyfry znaczące po przecinku, aby skrócić do zera miejsc za pomocą ~~. Podzielić ten mnożnik z powrotem. Zysk.

function truncator(numToTruncate, intDecimalPlaces) {    
    var numPower = Math.pow(10, intDecimalPlaces); // "numPowerConverter" might be better
    return ~~(numToTruncate * numPower)/numPower;
}

Próbuję oprzeć się zawinięciu ~~rozmowy w pareny; Uważam, że kolejność operacji powinna sprawić, że będzie to działać poprawnie.

alert(truncator(5.1231231, 1)); // is 5.1

alert(truncator(-5.73, 1)); // is -5.7

alert(truncator(-5.73, 0)); // is -5

Link do JSFiddle .

EDYCJA: Patrząc wstecz, nieumyślnie zająłem się również sprawami, aby zaokrąglić lewą część dziesiętną.

alert(truncator(4343.123, -2)); // gives 4300.

Logika jest trochę zwariowana, szukając tego zastosowania i może skorzystać na szybkim refaktorze. Ale nadal działa. Lepsze szczęście niż dobre.


To najlepsza odpowiedź. Jeśli rozszerzysz Mathprototyp o to i sprawdzisz NaN-y przed wykonaniem, byłoby to po prostu idealne.
Bartłomiej Zalewski

truncator((10 * 2.9) / 100, 2)return 0.28 zamiast 0.29 ... jsfiddle.net/25tgrzq1
Alex

14

Ładne rozwiązanie jednowierszowe:

function truncate (num, places) {
  return Math.trunc(num * Math.pow(10, places)) / Math.pow(10, places);
}

Następnie zadzwoń za pomocą:

truncate(3.5636232, 2); // returns 3.56
truncate(5.4332312, 3); // returns 5.433
truncate(25.463214, 4); // returns 25.4632

2
Podoba mi się to rozwiązanie, ale pamiętaj, że nie jest w pełni obsługiwane przez wszystkie przeglądarki. ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… )
Gene Parcellano,

11

Pomyślałem, że dorzucę odpowiedź za pomocą, |ponieważ jest prosta i działa dobrze.

truncate = function(number, places) {
  var shift = Math.pow(10, places);

  return ((number * shift) | 0) / shift;
};

1
Dobra decyzja. Użycie operatora bitowego wymusza wartość na int, a orz 0 oznacza „po prostu zachowaj to, co już mam”. Robi to, co moja ~~odpowiedź, ale za pomocą jednej operacji bitowej. Chociaż ma to samo ograniczenie, co napisano: nie możemy przekroczyć 2 ^ 31 .
ruffin

1
niepoprawne, gdy truncate((10 * 2.9) / 100);ten kod zwraca 0,28 zamiast 0,29 jsfiddle.net/9pf0732d
Alex

@Alex Jak domyślam się zdajesz sobie sprawę ... witamy w JavaScript! . Są poprawki. Może chciałbyś się nim podzielić? : D
ruffin

@ruffin Wiem o tym problemie =) Myślałem, że ta odpowiedź jest rozwiązaniem tego problemu. Niestety nie znalazłem jeszcze dokładnego rozwiązania, wszędzie jest taki problem.
Alex


7

Odpowiedź @ Dogberta można poprawić za pomocą Math.trunc, która obcina zamiast zaokrąglać.

Istnieje różnica między zaokrąglaniem a obcięciem. Obcinanie jest wyraźnie zachowaniem, którego dotyczy to pytanie. Jeśli zadzwonię do truncate (-3,14) i otrzymam -4 z powrotem, zdecydowanie nazwałbym to niepożądanym. - @NickKnowlson

var a = 5.467;
var truncated = Math.trunc(a * 100) / 100; // = 5.46
var a = -5.467;
var truncated = Math.trunc(a * 100) / 100; // = -5.46

1
To nie działa we wszystkich przypadkach, np. Console.log (Math.trunc (9.28 * 100) / 100); // 9.27
Mike Makuch

@MikeMakuch to nie problem Math.trunc, ale raczej niż 9.28 * 100jest 927.9999raczej niż 928. Możesz przeczytać The Perils of Floating Point
zurfyx,

5

Napisałem odpowiedź krótszą metodą. Oto co wymyśliłem

function truncate(value, precision) {
    var step = Math.pow(10, precision || 0);
    var temp = Math.trunc(step * value);

    return temp / step;
}

Metoda może być używana w ten sposób

truncate(132456.25456789, 5)); // Output: 132456.25456
truncate(132456.25456789, 3)); // Output: 132456.254
truncate(132456.25456789, 1)); // Output: 132456.2   
truncate(132456.25456789));    // Output: 132456

Lub, jeśli chcesz mieć krótszą składnię, proszę bardzo

function truncate(v, p) {
    var s = Math.pow(10, p || 0);
    return Math.trunc(s * v) / s;
}

jest to metoda, której bym się spodziewał
taksówkarz

4
Number.prototype.trim = function(decimals) {
    var s = this.toString();
    var d = s.split(".");
    d[1] = d[1].substring(0, decimals);
    return parseFloat(d.join("."));
}

console.log((5.676).trim(2)); //logs 5.67

Podoba mi się, że działa to ze stringami, eliminując w ten sposób niuanse liczb zmiennoprzecinkowych. Dzięki!
iCode

4

Myślę, że ta funkcja mogłaby być prostym rozwiązaniem:

function trunc(decimal,n=2){
  let x = decimal + ''; // string 
  return x.lastIndexOf('.')>=0?parseFloat(x.substr(0,x.lastIndexOf('.')+(n+1))):decimal; // You can use indexOf() instead of lastIndexOf()
}

console.log(trunc(-241.31234,2));
console.log(trunc(241.312,5));
console.log(trunc(-241.233));
console.log(trunc(241.2,0));  
console.log(trunc(241));


Dwa lata po tym, jak to zostało opublikowane, natknąłem się na to, gdy próbowałem znaleźć najlepszy sposób za pomocą Math.trunc, regex itp. Naprawdę podoba mi się to rozwiązanie. Martwe proste, ale działa doskonale (w każdym razie w moim przypadku).
giles123

Nie zapomnij jednak uwzględnić n = 0.
giles123

3

Znalazłem problem: rozważając następną sytuację: 2.1 lub 1.2 lub -6.4

Co jeśli chcesz zawsze mieć 3 miejsca po przecinku lub dwa lub gdziekolwiek, więc musisz uzupełnić początkowe zera po prawej stronie

// 3 decimals numbers
0.5 => 0.500

// 6 decimals
0.1 => 0.10000

// 4 decimales
-2.1 => -2.1000

// truncate to 3 decimals
3.11568 => 3.115

To stała funkcja Nicka Knowlsona

function truncateDecimals (num, digits) 
{
    var numS = num.toString();
    var decPos = numS.indexOf('.');
    var substrLength = decPos == -1 ? numS.length : 1 + decPos + digits;
    var trimmedResult = numS.substr(0, substrLength);
    var finalResult = isNaN(trimmedResult) ? 0 : trimmedResult;

    // adds leading zeros to the right
    if (decPos != -1){
        var s = trimmedResult+"";
        decPos = s.indexOf('.');
        var decLength = s.length - decPos;

            while (decLength <= digits){
                s = s + "0";
                decPos = s.indexOf('.');
                decLength = s.length - decPos;
                substrLength = decPos == -1 ? s.length : 1 + decPos + digits;
            };
        finalResult = s;
    }
    return finalResult;
};

https://jsfiddle.net/huttn155/7/


x = 0.0000test truncateDecimals (x, 2)kończy się niepowodzeniem. zwraca 0. nie tak jak oczekiwano0.00
Ling Loeng

3
function toFixed(number, digits) {
    var reg_ex = new RegExp("(\\d+\\.\\d{" + digits + "})(\\d)")
    var array = number.toString().match(reg_ex);
    return array ? parseFloat(array[1]) : number.valueOf()
}

var test = 10.123456789
var __fixed = toFixed(test, 6)
console.log(__fixed)
// => 10.123456

3

Odpowiedź @kirilloid wydaje się być poprawną odpowiedzią, jednak główny kod wymaga aktualizacji. Jego rozwiązanie nie uwzględnia liczb ujemnych (o których ktoś wspomniał w sekcji komentarzy, ale nie zostało zaktualizowane w głównym kodzie).

Aktualizacja do kompletnego, ostatecznie przetestowanego rozwiązania:

Number.prototype.toFixedDown = function(digits) {
    var re = new RegExp("([-]*\\d+\\.\\d{" + digits + "})(\\d)"),
    m = this.toString().match(re);
    return m ? parseFloat(m[1]) : this.valueOf();
};

Przykładowe użycie:

var x = 3.1415629;
Logger.log(x.toFixedDown(2)); //or use whatever you use to log

Fiddle: JS Number Zaokrąglij w dół

PS: Za mało repozytorium, aby skomentować to rozwiązanie.


2

Oto prosta, ale działająca funkcja obcinania liczby do 2 miejsc po przecinku.

           function truncateNumber(num) {
                var num1 = "";
                var num2 = "";
                var num1 = num.split('.')[0];
                num2 = num.split('.')[1];
                var decimalNum = num2.substring(0, 2);
                var strNum = num1 +"."+ decimalNum;
                var finalNum = parseFloat(strNum);
                return finalNum;
            }

2

Wynikowy typ pozostaje liczbą ...

/* Return the truncation of n wrt base */
var trunc = function(n, base) {
    n = (n / base) | 0;
    return base * n;
};
var t = trunc(5.467, 0.01);

2

Lodash posiada kilka metod narzędziowych matematyczne, które mogą okrągły , podłoga i ceil numer do danego dokładnością po przecinku. To pozostawia końcowe zera.

Przyjmują interesujące podejście, używając wykładnika liczby. Najwyraźniej pozwala to uniknąć zaokrąglania problemów.

(Uwaga: funcjest Math.roundlub ceillub floorw poniższym kodzie)

// Shift with exponential notation to avoid floating-point issues.
var pair = (toString(number) + 'e').split('e'),
    value = func(pair[0] + 'e' + (+pair[1] + precision));

pair = (toString(value) + 'e').split('e');
return +(pair[0] + 'e' + (+pair[1] - precision));

Link do kodu źródłowego


1

Oto moje podejście do tematu:

convert.truncate = function(value, decimals) {
  decimals = (decimals === undefined ? 0 : decimals);
  return parseFloat((value-(0.5/Math.pow(10, decimals))).toFixed(decimals),10);
};

To tylko nieco bardziej rozbudowana wersja

(f - 0.005).toFixed(2)

1

Ten, który jest oznaczony jako rozwiązanie, jest lepszym rozwiązaniem, które znalazłem do dzisiaj, ale ma poważny problem z 0 (na przykład 0. toFixedDown (2) daje -0,01). Więc proponuję użyć tego:

Number.prototype.toFixedDown = function(digits) {
  if(this == 0) {
    return 0;
  }
  var n = this - Math.pow(10, -digits)/2;
  n += n / Math.pow(2, 53); // added 1360765523: 17.56.toFixedDown(2) === "17.56"
  return n.toFixed(digits);
}

1

Oto czego używam:

var t = 1;
for (var i = 0; i < decimalPrecision; i++)
    t = t * 10;

var f = parseFloat(value);
return (Math.floor(f * t)) / t;

1
const TO_FIXED_MAX = 100;

function truncate(number, decimalsPrecison) {
  // make it a string with precision 1e-100
  number = number.toFixed(TO_FIXED_MAX);

  // chop off uneccessary digits
  const dotIndex = number.indexOf('.');
  number = number.substring(0, dotIndex + decimalsPrecison + 1);

  // back to a number data type (app specific)
  return Number.parseFloat(number);
}

// example
truncate(0.00000001999, 8);
0.00000001

pracuje z:

  • liczby ujemne
  • bardzo małe liczby (dokładność Number.EPSILON)

0

tylko po to, aby wskazać proste rozwiązanie, które zadziałało dla mnie

przekonwertuj go na łańcuch, a następnie wykonaj regex ...

var number = 123.45678;
var number_s = '' + number;
var number_truncated_s = number_s.match(/\d*\.\d{4}/)[0]
var number_truncated = parseFloat(number_truncated_s)

Można go skrócić do

var number_truncated = parseFloat(('' + 123.4568908).match(/\d*\.\d{4}/)[0])

0

Oto kod ES6, który robi to, co chcesz

const truncateTo = (unRouned, nrOfDecimals = 2) => {
      const parts = String(unRouned).split(".");

      if (parts.length !== 2) {
          // without any decimal part
        return unRouned;
      }

      const newDecimals = parts[1].slice(0, nrOfDecimals),
        newString = `${parts[0]}.${newDecimals}`;

      return Number(newString);
    };

// your examples 

 console.log(truncateTo(5.467)); // ---> 5.46

 console.log(truncateTo(985.943)); // ---> 985.94

// other examples 

 console.log(truncateTo(5)); // ---> 5

 console.log(truncateTo(-5)); // ---> -5

 console.log(truncateTo(-985.943)); // ---> -985.94


0
Number.prototype.truncate = function(places) {
  var shift = Math.pow(10, places);

  return Math.trunc(this * shift) / shift;
};

0

Możesz pracować ze sznurkami. Sprawdza, czy „.” istnieje, a następnie usuwa część ciągu.

obcięcie (7,88, 1) -> 7,8

obcięte (7,889, 2) -> 7,89

obcięcie (-7,88, 1) -> -7,88

function  truncate(number, decimals) {
    const tmp = number + '';
    if (tmp.indexOf('.') > -1) {
        return +tmp.substr(0 , tmp.indexOf('.') + decimals+1 );
    } else {
        return +number
    }
 }

0

Jestem trochę zdezorientowany, dlaczego jest tak wiele różnych odpowiedzi na tak fundamentalnie proste pytanie; widziałem tylko dwa podejścia, które wydawały się warte uwagi. Zrobiłem szybki test porównawczy, aby zobaczyć różnicę prędkości za pomocą https://jsbench.me/ .

Oto rozwiązanie, które jest obecnie (26.09.2020) oflagowane jako odpowiedź:

function truncate(n, digits) {
    var re = new RegExp("(\\d+\\.\\d{" + digits + "})(\\d)"),
        m = n.toString().match(re);
    return m ? parseFloat(m[1]) : n.valueOf();
};

[   truncate(5.467,2),
    truncate(985.943,2),
    truncate(17.56,2),
    truncate(0, 1),
    truncate(1.11, 1) + 22];

Jednak jest to wykonywanie operacji na łańcuchach i wyrażeniach regularnych, co zwykle nie jest zbyt wydajne, a istnieje funkcja Math.trunc, która robi dokładnie to , czego chce OP, tylko bez miejsc po przecinku. Dlatego możesz łatwo użyć tego plus trochę dodatkowej arytmetyki, aby uzyskać to samo.

Oto kolejne rozwiązanie, które znalazłem w tym wątku, a którego użyłbym:

function truncate(n, digits) {
    var step = Math.pow(10, digits || 0);
    var temp = Math.trunc(step * n);

    return temp / step;
}

[   truncate(5.467,2),
    truncate(985.943,2),
    truncate(17.56,2),
    truncate(0, 1),
    truncate(1.11, 1) + 22];
    

Pierwsza metoda jest „o 99,92% wolniejsza” niż druga, więc druga jest zdecydowanie tą, którą polecam.

OK, wracając do szukania innych sposobów uniknięcia pracy ...

zrzut ekranu testu porównawczego

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.