Gå til innhold

ProgrammeringsBaren! Småprat, om det du elsker!


Anbefalte innlegg

Spørsmålet er om dette er noe stort problem asicman.

Jeg har ikke hørt om så mange sliter med dette.

Det fleste som programmerer kjenner til dette og dokumentasjon har med dette.

Floating Point Arithmetic: Issues and Limitations

Dette gjelder i de fleste språk,nå det mulig som du sier at commen lisp har en annen løsning.

 

For finansielle kalkulasjoner bruker man ikke float,men decimal modulen.

For rasjonale tall bruker man fraction modulen eller sympy

som har full støtte for rasjonale tall.

Og som nevnt tidligere __future__ import division.

 

Man innser at man kan få problemer med kompabilitetet og innfører from __future__

(D) 3.0 release

From __future__ har vært her lenge før python 3 kom.

Gjør at man teste/bruke nye funksjoner som kommer,selv om man bruker en eldere versjon.

Så brukte man python 2.3 kunne man teste/bruke nye funksjoner som kom i python 2.5.

Pep-236 fra 2001.

Endret av SNIPPSAT
Lenke til kommentar
Videoannonse
Annonse

Spørsmålet er om dette er noe stort problem asicman.

 

Kanskje ikke, men det at man plutselig får en annen semantikk i senere versjoner av språket kan få programmer til å oppføre seg forskjellig og kan potensielt få katstrofale følger.

 

Det fleste som programmerer kjenner til dette og dokumentasjon har med dette.

Floating Point Arithmetic: Issues and Limitations

Dette gjelder i de fleste språk,nå det mulig som du sier at commen lisp har en annen løsning.

 

Jeg snakker ikke om floating point, men om rasjonale tall. Common Lisp har støtte for rasjonale tall som jeg viste innledningsvis i denne diskusjonen. Det jeg sa om floating er at det ikke er noen løsning for rasjonale tall.

 

For finansielle kalkulasjoner bruker man ikke float,men decimal modulen.

 

I gamle dager når maskiner hadde BCD aritmetikk og man programmerte i COBOL var det vanlig. I dag bruker man som oftest integer (med støtte for store tall) til finansielle kalkulasjoner og gjør beregningene i den minste enheten som f.eks. øre her i Norge og skriver vanligvis ut som kroner.

 

 

For rasjonale tall bruker man fraction modulen eller sympy

som har full støtte for rasjonale tall.

 

Fraction modulen er akkurat det jeg sa tidligere, men du kom først med desimal modulen som respons på min melding om rasjonale tall. Fraction er greit, selv om det ikker er så enkel syntax som i CL: Fraction(1,3) i stedet for 1/3.

 

From __future__ har vært her lenge før python 3 kom.

 

Jeg tror ikke du forstod helt hva jeg mente med den tidslinjen. Poenget er at ingen vet om disse egenskapene før de blir påtenkt og man lager en from __future__ for å støtte denne, f.eks. som før tidspunket C i mitt eksempel.

Lenke til kommentar

I gamle dager når maskiner hadde BCD aritmetikk og man programmerte i COBOL var det vanlig. I dag bruker man som oftest integer (med støtte for store tall) til finansielle kalkulasjoner og gjør beregningene i den minste enheten som f.eks. øre her i Norge og skriver vanligvis ut som kroner.

 

Nja, integer som valuta er mer en billig hack man bruker i språk/plattformer som ikke har noe bedre lett tilgjengelige desimale datatyper og aritmetikk.

 

Er man opptatt av ihvertfall et minimum av presisjon gjennom mer enn pluss og minus bruker man en datatype som regner og avrunder korrekt desimalt, som f.eks java.math.BigDecimal (java), System.Decimal (.NET), eller hva som nå måtte finnes på plattformen man bruker.

 

Driver man å gjør finansielle kalkulasjoner på en plattform som ikke har gode desimale typer er det på høy tid å revurdere teknologivalgene sine.

Endret av MailMan13
Lenke til kommentar

 

Nja, integer som valuta er mer en billig hack man bruker i språk/plattformer som ikke har noe bedre lett tilgjengelige desimale datatyper og aritmetikk.

 

 

Det er ikke noe billig hack. Det er ofte mer effektivt å implementere også. De applikasjonene jeg har sett i den senere tid regner i øre. Hva som er korrekt avrunding og når denne gjøres kan være applikasjonsavhenging.

Lenke til kommentar

Vet ikke hva slags applikasjoner du har sett, men en slik strategi i produksjonskode til en kunde som bryr seg et minimum av presisjon høres ikke spesielt trygt ut.

 

Skal ikke mer til enn å legge til moms på et beløp, så prøve å trekke det ut igjen før ørene begynner vippe opp og ned. Mangler det desimaler annuiteter inn i beregninger på nåverdi eller fremtidig verdi kommer feilene i kroner nokså fort med såpass lite presisjon som ett øre.

 

"I dag bruker man som oftest integer", nei, jeg tror ikke det er riktig, og hvis man gjør det på en plattform som har gode alternativer mener jeg man har dummet seg litt ut.

Lenke til kommentar

Vet ikke hva slags applikasjoner du har sett, men en slik strategi i produksjonskode til en kunde som bryr seg et minimum av presisjon høres ikke spesielt trygt ut.

 

"minimum av presisjon"? Hva er det du snakker om? Med heltall med støtte for store tall har man full presisjon og full kontroll på all avrunding til kroner når man måtte ønske det.

Lenke til kommentar

Kanhende noen bruker integer, ettersom flyttall er av natur upresise. Blant annet finnes det en rekke tall som ikke lar seg representere, og da vil det nærmeste mulige bli valgt. Dette er grunnen til at man noen ganger får 0.0000001 istedet for 0 i visse beregninger. En kommer ikke vekk ifra at tall slik de er representert i en datamaskin er upresise.

Mange systemer bruker derimot 128-bit flyttall (Decimal i .NET og Java)

Lenke til kommentar

Kanhende noen bruker integer

 

 

Jeg snakker ikke om 32-bit interger o.l. selv om for noen beregninger kan det brukes 32-bit og 64-bit internt. Jeg snakker om integer med støtte for store tall. Divisjon med 3 osv. er rasjonale tall og vil holde full presisjon.

Lenke til kommentar

Men for de som jobber med eksponesialfunksjoner så er jeg enig at det kan være mindre ressurskrevende å bruke et fixed point bibliotek enn et med støtte for rasjonale tall. I Ptyhon så blir feks. 1/3^10000:

 

>>> pow(Fraction(1,3),10000)

Fraction(1, 16313501853426258743032567291811547168121324535825379939348203261918257308143190787480155630847848309673252045223235795433405582999177203852381479145368112501453192355166224391025423628843556686559659645012014177448275529990373274425446425751235537341867387607813619937225616872862016504805593174059909520461668500663118926911571773452255850626968526251879139867085080472539640933730243410152186914328917354576854457274195562218013337745628502470673059426999114202540773175988199842487276183685299388927825296786440252999444785694183675323521704432195785806270123388382931770198990841300861506996108944782065015163410344894945809337689156807686673462563038164792190665340124344133980763205594364754963451564072340502606377790585114123814919001637177034457385019939060232925194471114235892978565322415628344142184842892083466227875760501276009801530703037525839157893875741192497705300469691062454369926795975456340236777734354667139072601574969834312769653557184396147587071260443947944862235744459711204473062937764153770030210332183635531818173456618022745975055313212598514429587545547296534609597194836036546870491771927625214352957503454948403635822345728774885175809500158451837389413798095329711993092101417428406774326126450005467888736546254948658602484494535938888656542746977424368385335496083164921318601934977025095780370104307980276356857350349205866078371806065542393536101673402017980951598946980664330391505845803674248348878071010412918667335823849899623486215050304052577789848512410263834811719236949311423411823585316405085306164936671137456985394285677324771775046050970865520893596151687017153855755197348199659070192954771308347627111052471134476325986362838585959552209645382089055182871854866744633737533217524880118401787595094060855717010144087136495532418544241489437080074716158404895914136451802032446707961058757633345691696743293869623745410870051851590672859347061212573446572045088465460616826082579731686004585218284333452396157730036306379421822435818001505905203918209206969662326706952623512427380240468784114535101496733983401240219840048956733689309620321613793757156727562461651933397540266795963865921590913322060572673349849253303397874242381960775337182730037783698708748781738419747698880321601186310506332869704931303076839444790968339306301273371014087248060946851793697973114432706759288546077622831002526800554849696867710280945946603669593797354642136622231192695027321229511912952940320879763123151760555959496961163141455688278842949587288399100273691880018774147568892650186152065335219113072582417699616901995530249937735219099786758954892534365835235843156112799728164123461219817343904782402517111603206575330527850752564642995318064985900815557979945885931124351303252811255254295797082281946658798705979077492469849644183166585950844953164726896146168297808178398470451561320526180542310840744843107469368959707726836608471817060598771730170755446473440774031371227437651048421606224757527085958515947273151027400662948161111284777828103531499488913672800783167888051177155427285103861736658069404797695900758820465238673970882660162285107599221418743657006872537842677883708807515850397691812433880561772652364847297019508025848964833883225165668986935081274596293983121864046277268590401580209059988500511262470167150495261908136688693861324081559046336288963037090312033522400722360882494928182809075406914319957044927504420797278117837677431446979085756432990753582588102440240611039084516401089948868433353748444104639734074519165067632941419347985624435567342072815910754484123812917487312938280670403228188813003978384081332242484646571417574404852962675165616101527367425654869508712001788393846171780457455963045764943565964887518396481296159902471996735508854292964536796779404377230965723361625182030798297734785854606060323419091646711138678490928840107449923456834763763114226000770316931243666699425694828181155048843161380832067845480569758457751090640996007242018255400627276908188082601795520167054701327802366989747082835481105543878446889896230696091881643547476154998574015907396059478684978574180486798918438643164618541351689258379042326487669479733384712996754251703808037828636599654447727795924596382283226723503386540591321268603222892807562509801015765174359627788357881606366119032951829868274617539946921221330284257027058653162292482686679275266764009881985590648534544939224296689791195355783205968492422636277656735338488299104238060289209390654467316291591219712866052661347026855261289381236881063068219249064767086495184176816629077103667131505064964190910450196502178972477361881300608688593782509793781457170396897496908861893034634895715117114601514654381347139092345833472226493656930996045016355808162984965203661519182202145414866559662218796964329217241498105206552200001)

Lenke til kommentar

Det er intet problem å representere tall som e π sin(x) osv i en datamaskin med total presisjon. Skal man derimot ha en numerisk tilnærming av tall hvor irrasjonale tall og transendale tall er en del vil man miste informasjon. Derfor er det en god idé å beholde slike faktorer i utregningen og så eventuellt tilnærme til slutt. Hvis man er heldig kan det også hende at disse blir faktorisert ut ved en senere operasjon, og man sitter igjen med kanskje et rasjonelt eller helt tall.

 

For mange operasjoner er flyttall rett og slett ikke nøyaktige nok.

Lenke til kommentar

"minimum av presisjon"? Hva er det du snakker om? Med heltall med støtte for store tall har man full presisjon og full kontroll på all avrunding til kroner når man måtte ønske det.

Du har ikke full presisjon, du har den presisjonen du definerer som base, og den blir dårligere og dårligere hver gang du gjør en divisjon eller en multiplikasjon på tallet ditt.

 

Regner du i øre har du presisjon på ett øre, selger du 100 av en vare med en slik pris har totalprisen en presisjon på 1 krone. Eks: Du har en vare som koster 2.50 kr eks moms. Du regner ut prisen ink.moms. korrekt til 3,13.

 

Prisen for 100 er da avhengig om du ganger inn momsen før eller etter du ganger ut med antallet, gjør du det først koster 100 stk 313,-, gjør du det etterpå koster det 312,50. Det mener jeg er helt uakseptabelt.

 

Gjør du det samme med inputen til finansielle funksjoner, som f.eks. nåverdi beregninger, over litt tid blir avviket enda større.

Lenke til kommentar

"minimum av presisjon"? Hva er det du snakker om? Med heltall med støtte for store tall har man full presisjon og full kontroll på all avrunding til kroner når man måtte ønske det.

Du har ikke full presisjon, du har den presisjonen du definerer som base, og den blir dårligere og dårligere hver gang du gjør en divisjon eller en multiplikasjon på tallet ditt.

 

Det er helt rett når det gjelder divisjon. Ikke multiplikasjon (selv om multiplikasjon kan skalere en tidligere avrundingsfeil). Når det gjelder divisjon så er det korrekt. Man må ha støtte for rasjonale tall for å få full presisjon. Har man ikke det så er det bedre å bruke et fixed point bibliotek for bedre presisjon, selv om man ikke får eksakt svar om man deler på f.eks. 3 dersom tallet ikke er et multiple av 3.

Lenke til kommentar

Multiplikasjoner alene påvirker også absolutt presisjon negativt (som er det vi vil ha når vi driver med penger). (int)(1.25 * 250) * 100 gir dårligere presisjone enn (int) (1,25 * (250 * 100)), ingen divisjoner involvert.

 

Akkurat derfor "I dag bruker man som oftest integer" er galt. Det er kanskje enkelte som gjør man fordi man ikke vet bedre, eller fordi man koder javascript, eller noe som kanskje ikke har alternativer. Er det det default løsningen man som oftest velger, så er man langt ute på glattisen.

 

I Common Lisp ville det være 31250 øre for 100 stk. (antatt 25% moms)

 

CL-USER> (* 100 (* 250 (1+ 25/100)))
31250

Nå kan ikke jeg Lisp, men resultatet av (250 (1+ 25/100)) kan umulig være integer, så her har du jo ett eksempel på at resultatet ditt vil bli forskjellig avhengig av om du legger moms på stykkpris først, eller regner det i ett utrykk med stykkpris som "whatever" default numerisk type du får der.

Endret av MailMan13
Lenke til kommentar

Multiplikasjoner alene påvirker også absolutt presisjon negativt (som er det vi vil ha når vi driver med penger). (int)(1.25 * 250) * 100 gir dårligere presisjone enn (int) (1,25 * (250 * 100)), ingen divisjoner involvert.

 

Men der har du i høyeste grad division siden 1,25 er 5/4. Som sagt så kan multiplikasjon skalere opp en tidligere avrundingsfeil som følge av divisjon, men det blir ikke redusert presisjon med heltall og multiplikasjon.

 

 

Akkurat derfor "I dag bruker man som oftest integer" er galt. Det er kanskje enkelte som gjør man fordi man ikke vet bedre, eller fordi man koder javascript, eller noe som kanskje ikke har alternativer. Er det det default løsningen man som oftest velger, så er man langt ute på glattisen.

 

Det er derfor jeg har stresset litt dette med rasjonale tall og heltall i denne tråden, fordi man har full presisjon. Det har man ikke med et fixed point bibliotek. f.eks. 1/3 lar seg ikke representere nøyaktig.

 

 

Nå kan ikke jeg Lisp, men resultatet av (250 (1+ 25/100)) kan umulig være integer, så her har du jo ett eksempel på at resultatet ditt vil bli forskjellig avhengig av om du legger moms på stykkpris først, eller regner det i ett utrykk med stykkpris som "whatever" default numerisk type du får der.

 

Mellomregningen er et rasjonalt tall (det ser ut som om du har mistet en multiplikasjon i editeringen din, (250 vil forsøke å kalle en funksjon som heter 250). Det samme i Ptyhon ville være:

 

100 * 250 * (1 + Fraction(25,100))

 

Selv om Python vil ulikt Common Lisp returnere et rasjonalt (eller Fraction som de kaller det) tall. Common Lisp koden jeg viste tidligere returnerer et heltall.

Lenke til kommentar

Så det du egentlig mener er ikke "øre som integer", men "øre i den typen det dynamiske typesystemet til Lisp mener du er best tjent med"?

 

Jeg ville representere all input og output av øre som integer (Common Lisp har støtte store tall, f.eks. 10^100000 er ingen problem. Mellomregning kan være rasjonale tall. Resultater kan også være det, hvis det er snakk om halve øre eller 1/3 øre. Så ville jeg styre avrundingen som gitt av en eller annen spesifikasjon. I Python ville jeg gjort det samme, men jeg ville være forsiktig å spesifisere moms som 25/100 siden det vil ha forskjellig semantikk før og etter Python 3.0 (inklusive framtidig import).

Lenke til kommentar

Så bruker du strengt tatt ikke "øre som integer" hvis det detter ut et rasjonelt tall så snart det er behov for det ;)

 

Jeg hadde nok hatt problemer om jeg kun hadde hatt hele øre i I/O (database) også, Jeg synes ikke det bør forsvinne presisjon i noen ledd (Om gui eller andre komponenter krever gitt avrunding får det være en jobb i de integrasjonspunktene det gjelder).

Endret av MailMan13
Lenke til kommentar

Så bruker du strengt tatt ikke "øre som integer" hvis det detter ut et rasjonelt tall så snart det er behov for det ;)

 

Input og output er som oftest heltall som representerer øre, men i mellomregninger kan det ofte være rasjonale tall. Når det gjelder databaser så er det ofte bare "persistent storage" (selv om det er en vanlig SQL database i bunnen) som representerer Common Lisp objektene.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...