Rotunjire numere negative

Are cineva idee cum se face rotunjirea numerelor negative în contabilitate? Adica, round(-0.5) ar trebui sa devină -1 sau 0?

round(3) are definiţia de mai jos, momentan îl folosesc pe acesta, dar nu sunt sigur că e corect.

These functions round x to the nearest integer, but round halfway cases away from zero (regardless of the current rounding direction, see fenv(3)), instead of to the nearest even integer like rint(3).

For example, round(0.5) is 1.0, and round(-0.5) is -1.0.

Ma rog, fac rotunjire la doua zecimale, aşa: round(value * 100.) / 100.

1 Like

Ultimul program de contabilitate pe care l-am facut e scris in JS si JS are Number.toFixed(2), ceea ce imi rotunjeste in sus, ah crap.

Nu stiu daca e bine sau nu, dar inca nu mi s-a plans nimeni.

La negative Number.toFixed(2) va face din -1.36769 -1.37… Chiar s-ar putea sa fie o problema.

Da, tocmai mi-ai amintit ca .toFixed(2) in JS nu face round de la 0.5 ci doar de la 0.6, daca ma bag in discutie cu JS o sa fie un subiect foarte complicat. Totusi cred ca in contabilitate chiar e foarte ok ce face JS.

Serios? Adica ai folosit ceil()?

Un soi de act normativ exista, dar nu pomeneşte nimic de sumele negative…

Art. 3. - Începând cu data de 1 iulie 2005, taxa pe valoarea adăugată şi accizele se înscriu în lei noi în facturile fiscale şi în orice alte documente justificative întocmite pentru livrări de bunuri şi prestări de servicii, utilizându-se două zecimale. Rotunjirea zecimalelor sumelor astfel determinate se face după următoarea regulă: prin rotunjirea la 1 ban a fracţiunilor de peste 0,5 bani inclusiv şi prin neglijarea fracţiunilor de până la 0,5 bani.

http://www.bnr.ro/apage.aspx?pid=404&actId=116

1 Like

Nu sunt foarte convins că e o idee bună să foloseşti floor() şi/sau ceil() în contabilitate.

De fapt nici macar float/double nu e o idee prea bună. Am prins câteva corner-case-uri când un anumit numâr nu putea fi reprezentat ca double binar si dadea erori in calcule. Normal ar trebui folosite numere zecimale cu virgulă fixă. În viitor intentionez sa tin sumele ca integeri pe 64 de biti (numarul zecimal inmultit cu 100 sau 10000).

1 Like

.toFixed() pare sa facă rotunjire la intregul cel mai apropiat, cred ca îţi ies corect calculele, de aia nu s-a plans nimeni :slight_smile:

toFixed() returns a string representation of numObj that does not use exponential notation and has exactly digits digits after the decimal place. The number is rounded if necessary, and the fractional part is padded with zeros if necessary so that it has the specified length. If numObj is greater than 1e+21, this method simply calls Number.prototype.toString() and returns a string in exponential notation.

Sper sa te ajute https://www.avocatnet.ro/forum/discutie_165319/Rotunjirea-sumelor-datorate.html

Stiu, nu prea este de dev

Citisem pe forum tot de o chestie de matematica, iar cineva a postat asta:
http://mathjs.org/

Nu ca sunt expert in contabilitate, dar zic sa mergi fara aproximare. Aproximarea lui 0.5 la 1 mi se pare cam mare si poate duce la erori in calcule.
:slight_smile:

1 Like

Cu Number.toFixed(2) am vazut mai multa lume ca lucreaza, deci e ok.
Din ce am mai citit, astia zic ca nu prea conteaza cum rotunjesti atata timp cat folosesti aceeasi metoda de rotunjire in toata aplicatia.

Rotunjirea se face la doua zecimale. Nu poti să faci fără aproximare, că n-ai cum să afişezi in facturi un număr nelimitat de zecimale.

1 Like

Nu ai folosit formula scrisa de tine ? :slight_smile:

Ba da. Intrebarea e dacă e corect să rotunjeşti aşa. La numere pozitive e simplu, tot ce e >= 0.5 merge in sus, restul e trunchiat. La numere negative devine mai… fuzzy. Din cate înţeleg, pentru numere negative round() merge in jos, nu in sus si nu stiu daca asta e o chestie ok in contabilitate. Deşi… dacă stau bine să mă gândesc, ar avea sens şi in conta, ca ar fi în “oglindă”, ceea ce e de dorit de exemplu la stornarea facturilor.

1 Like

Poate e un context implicit pe care nu-l știu, dar nu ar trebui folosite float sau double pentru numere, ci un tip decimal, sau chiar unul special pentru bani. De exemplu, vad că pe npm e js-money care arata interesant. Altfel ai erori de calcule și numere pe care efectiv nu le poți reprezenta, chiar cu doua zecimale . Ditto pe tot stack-ul - de la baza de date, la componente server și frontend. Rotunjirea aia ar trebui sa fie folosita doar pentru afișare.

2 Likes

Si un coleg a avut acesta problema. A facut calculele fara aproximari in spate, iar in fata a facut afisarea

Eu am un soft de facturare scris in C++ si mi-a venit cel mai simplu sa folosesc double, crezănd că n-o să prind niciodată un număr nereprezentabil binar. Well… n-a fost chiar aşa. La un moment dat am innebunit încercând să-mi dau seama de ce o egalitate dadea false deşi numerele păreau identice :slight_smile:

Nope, asta nu e bine. Chiar ieri am avut de rezolvat un astfel de bug. Clientul se plângea ca în calculele mele totalul de plată este un bănuţ în minus. Era ceva de genul asta:

1301.50 - scont 5% (65.07) = 1236.42

De ce? Simplu, eu in spate faceam calculele la precizie maximă şi afişam rotunjit la două zecimale şi evident că îmi dadea “1236.42”. Totusi, pe hartie pare greşit, pentru că 1301.50 - 65.07 = 1236.43.

Am inteles !

2 posts were split to a new topic: Calcul TVA cu patru zecimale

De exemplu in cazuri din acestea nu e ok sa faci si o impartire/inmultire si o scadere/adunare. Cel mai bine faci direct o inmultire cu 0.95. Eu sunt putin obisnuit din CUDA pe arhitecturi mai vechi sa merge-uiesc doua operatii care desi pe hartie par la fel, pentru procesor sunt total diferite si iti dau niste solutii care difera la ultima zecimala. Daca cumva acea eroare de o zecimala (si aici ma refer la o eroare de 10^-6) se propaga in program si faci operatii cu acea valoare eronata … well, sa zicem ca nu o sa ai o zi buna.

Ca sa dau un exemplu de operatie care desi pe hartie pare la fel, pentru procesor e diferit:
a*(b+c) != (b+c)*a

De ce? La prima operatie se face o singura operatie FMA (fused multiply add), in schimb la a doua se fac doua operatii (suma si inmultirea). Prima o sa “dea” cel mai bine si va fi cea mai rapida. Daca poti scapa de o operatie la nivel de procesor, just do it.

2 Likes