• 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

VPS Starter Arubacloud
+1 głos
610 wizyt
pytanie zadane 13 stycznia 2022 w JavaScript przez dev\null Nowicjusz (230 p.)
edycja 13 stycznia 2022 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ź 13 stycznia 2022 przez Kamil Naja Nałogowiec (27,330 p.)

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

komentarz 13 stycznia 2022 przez tkz Nałogowiec (42,000 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 14 stycznia 2022 przez dev\null Nowicjusz (230 p.)
edycja 14 stycznia 2022 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 14 stycznia 2022 przez tkz Nałogowiec (42,000 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 14 stycznia 2022 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 14 stycznia 2022 przez tkz Nałogowiec (42,000 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 14 stycznia 2022 przez Comandeer Guru (599,730 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 14 stycznia 2022 przez tkz Nałogowiec (42,000 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 14 stycznia 2022 przez Comandeer Guru (599,730 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ź 14 stycznia 2022 przez qax Dyskutant (8,060 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 14 stycznia 2022 przez VBService Ekspert (251,210 p.)
edycja 14 stycznia 2022 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 14 stycznia 2022 przez qax Dyskutant (8,060 p.)
edycja 14 stycznia 2022 przez qax

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

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

komentarz 14 stycznia 2022 przez VBService Ekspert (251,210 p.)
edycja 9 lutego 2022 przez VBService

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

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 14 stycznia 2022 przez qax Dyskutant (8,060 p.)

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

Podobne pytania

0 głosów
1 odpowiedź 430 wizyt
pytanie zadane 14 kwietnia 2020 w PHP przez terianmt2 Nowicjusz (230 p.)
0 głosów
1 odpowiedź 4,749 wizyt
+2 głosów
0 odpowiedzi 1,389 wizyt

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...