• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Zaokrąglanie kwoty do pełnych groszy

+1 głos
99 wizyt
pytanie zadane 4 dni temu w JavaScript przez dev\null Nowicjusz (230 p.)
edycja 4 dni temu przez dev\null

Zastanawia mnie jak najlepiej poradzić sobie z poprawną obsługą cen netto/brutto w JS.
Chciałbym poprawnie zaokrąglić wartość, która przyjdzie do mnie w złotówkach z groszami

Przykładowo mogę zrobić tak:

+(Math.round(price * 100)/100).toFixed(2);

W przypadku gdy `price` to wartość np. `99.956666`, dostaniemy poprawne zaokrąglenie na `99.96`, ale jeżeli wartość `price` będzie wynosić: 99.99999, to wówczas otrzymam `100`, co jest niepoprawną wartością w kontekście księgowo - finansowym.

2 odpowiedzi

+2 głosów
odpowiedź 4 dni temu przez Kamil Naja Nałogowiec (26,810 p.)

Wszelkie zaokrąglanie będzie powodowało błędy, użyj biblioteki (za https://dev.to/damxipo/handle-money-with-js-4a13)

komentarz 4 dni temu przez tkz Nałogowiec (41,420 p.)
parseInt(99.99999*100)/100)

Bardzo bawi mnie podejście ludzi, którzy piszą w JS. Macie miliardy paczek, które właściwie nic nie robią. Do trywialnego zaokrąglenia potrzebujesz czegoś z zewnątrz? 

komentarz 4 dni temu przez dev\null Nowicjusz (230 p.)
edycja 4 dni temu przez dev\null

@tkz, czy to aby na pewno takie trywialne, skoro:

parseInt(10230.21*100)/100

zwróci Ci 10230.2 (czyli już grosz ucieka)

komentarz 4 dni temu przez tkz Nałogowiec (41,420 p.)

Nadal uważam, że rozwiązanie jest trywialne, problem tkwi w JS. Nadal nie widzę sensu w dodawaniu miliona zależności. 

Math.round((10230.21 + Number.EPSILON) * 100) / 100

https://stackoverflow.com/questions/11832914/how-to-round-to-at-most-2-decimal-places-if-necessary pierwszy lepszy link

komentarz 4 dni temu przez dev\null Nowicjusz (230 p.)

Zgadzam się z Tobą, że pakowanie libki do wszystkiego co popadnie to droga donikąd.

Znam również ten przykład bo przewertowałem całe SO w tym temacie.
Zwróć uwagę, że teraz jak zrobisz sobie:

Math.round((99.999999 + Number.EPSILON) * 100) / 100

To też Ci grosz ucieknie, ale w górę bo zwróci 100. I tak można w kółko.
Póki co nie znalazłem rozwiązania uniwersalnego/idealnego ‍

komentarz 4 dni temu przez tkz Nałogowiec (41,420 p.)
Nie piszę w JS, ale przychodzi mi jeszcze na myśl zamiana na napis, sprawdzenie 3 pozycji po kropce, ewentualne zaokrąglenie i rzutowanie na liczbę. Możliwe, że rozwodzimy się również nad problemem, który nie ma znaczenia, w sensie +/- 1 grosz.
1
komentarz 4 dni temu przez Comandeer Guru (562,300 p.)

@tkz, tylko wiesz, te "nic nierobiące miliardy paczek" z jakiegoś powodu powstały i są dość popularne. Po co rozwiązywać samemu problem, który ktoś kiedyś rozwiązał i – biorąc pod uwagę, że 58k ściągnięć Dinero.js oznacza o wiele więcej userów, niż rozwiązanie in-house – natknął się na problemy, na które Ty też się natkniesz? Zwłaszcza przy rzeczach takich jak obliczenia walutowe, które mogą być dość kosztowne.

No i +/- 1 grosz dla pojedynczych obliczeń może i nie ma znaczenia, ale na większą skalę już będzie miał.

komentarz 4 dni temu przez tkz Nałogowiec (41,420 p.)
Popularność nie świadczy o jakości. Powód jest chyba tylko znany autorowi paczki. Znowu, kwestia potrzeby i problemu biznesowego. Chyba żaden inny język nie ma tak przerośniętego i zapchanego bzdurnymi rzeczami menadżera pakietów jak JS.

Z drugiej strony oczywiście nie neguje tych "przydatnych" paczek, ale jak widzę "isPrime" na npm... Albo coś co sprawdza, czy liczba jest parzysta. Albo cokolwiek innego, co jest trywialne, szczególnie dla osoby, która piszę w tym na co dzień. Problem wyżej, pięć wymian myśli i doszliśmy jak to rozwiązać, chyba, tutaj akurat potrzebowałbym potwierdzenia, czy sposób z napisem jest okey.  

To moje zdanie, osoby, która nie piszę w JS z własnej woli, a tylko wtedy gdy musi.
komentarz 4 dni temu przez Comandeer Guru (562,300 p.)

Problem wyżej, pięć wymian myśli i doszliśmy jak to rozwiązać, chyba, tutaj akurat potrzebowałbym potwierdzenia, czy sposób z napisem jest okey.  

 Po co rozwiązywać samemu problem, który ktoś kiedyś rozwiązał i – biorąc pod uwagę, że 58k ściągnięć Dinero.js oznacza o wiele więcej userów, niż rozwiązanie in-house – natknął się na problemy, na które Ty też się natkniesz?

+2 głosów
odpowiedź 4 dni temu przez qax Mądrala (7,140 p.)

Zobacz czy to by ci odpowiadało:

const price = 99.99999;
function numberApproximation(number) {
	let fractionalPart = 0;
	if (number.toString().indexOf('.') !== -1) {
  	fractionalPart = number.toString().split('.')[1].substring(0, 3);
  }
  const approximation = (fractionalPart < 995) ? (Math.round(number * 100) / 100).toFixed(2) : (Math.floor(number * 100) / 100).toFixed(2);
  return approximation;
}
console.log(numberApproximation(price));

 

komentarz 3 dni temu przez VBService VIP (143,170 p.)
edycja 3 dni temu przez VBService

@qax, wygląd, że Twoja propozycja "daje radę".  laugh

function numberApproximation(number) {
  const fractionalPart = (!number.toString().indexOf('.')) ? number : number.toString().substr(number.toString().indexOf('.')+1,3);
  const  approximation = (fractionalPart<995) ? (Math.round(number*100)/100) : (Math.floor(number*100)/100);
  
  return approximation.toFixed(2);
}

console.log(numberApproximation(99.99999));
console.log(numberApproximation(99.956666));
console.log(numberApproximation(99.946666));
console.log(numberApproximation(100));
console.log(numberApproximation(100.));
console.log(numberApproximation(.99));

 

komentarz 3 dni temu przez qax Mądrala (7,140 p.)
edycja 3 dni temu przez qax

VBService, tzn. że coś jest źle? crying

EDIT: Z czego widzę wszystko jest w porządku... laugh

komentarz 3 dni temu przez VBService VIP (143,170 p.)
edycja 3 dni temu przez VBService

Sam zobacz, Twoje rozwiązanie, w sumie "takie proste", ale działa całkiem nieźle.

function numberApproximation(number) {
  const fractionalPart = (!number.toString().includes('.')) ? number : number.toString().substr(number.toString().indexOf('.')+1,3);
  const  approximation = (fractionalPart<995) ? (Math.round(number*100)/100) : (Math.floor(number*100)/100);
  
  return approximation.toFixed(2);
}

const test = [ 9.9999, 99.994999, 99.995555, 99.956666, 99.946666, 100, '100.', '.99', '.9965', '.9954', 1000.96, 1000.9755, 1000.9766, 1000.005, '.00', '0.' ];

for (let sample of test)
  console.log('For '+sample+' approximation is '+numberApproximation(sample));

 

1
komentarz 3 dni temu przez qax Mądrala (7,140 p.)

Dzięki - a już się wystraszyłem, że kogoś w błąd wprowdziłem... wink

Podobne pytania

0 głosów
1 odpowiedź 131 wizyt
pytanie zadane 14 kwietnia 2020 w PHP przez terianmt2 Nowicjusz (230 p.)
0 głosów
1 odpowiedź 3,235 wizyt
+2 głosów
0 odpowiedzi 1,039 wizyt

86,400 zapytań

135,161 odpowiedzi

300,250 komentarzy

57,163 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...