Svish Skrevet 8. september 2008 Del Skrevet 8. september 2008 Hvis en har et tall, for eksempel: double x = 123,4567; Så kan en finne det før komma, ved å double/int y = (int) x; For å finne det etter komma, kan man double z = x - (int) x; Er disse operasjonene trygge med tanke på flyttall osv? Tenker da spesielt på den siste. Kan det bli rot, eller er disse to operasjonene helt trygge? Er det dessuten noen viktig forskjell på de to uttrykkene nedenunder? nøyaktighet, hastighet, etc. int y = (int) x; int y = Math.Floor(x); Lenke til kommentar
GeirGrusom Skrevet 8. september 2008 Del Skrevet 8. september 2008 De er trygge med tanke på flyttall ja, og fungerer kun på flyttall. int bible_pi = (int)Math.PI; double precision_not_biblical = Math.PI - bible_pi; Om det er noen forskjell på Math.Floor og cast til int vet jeg ikke, jeg holder en knapp på 'neppe' Lenke til kommentar
Svish Skrevet 9. september 2008 Forfatter Del Skrevet 9. september 2008 ok. gikk for neppe selv, men da er jo det greit på ikke-flyttall så er det vel ikke så mye å hente bak komma uansett, hehe. (Bible Pi ) Lenke til kommentar
GeirGrusom Skrevet 9. september 2008 Del Skrevet 9. september 2008 Som regel bruker jeg Math.Floor når jeg jobber med double, fordi en da slipper å caste. Lenke til kommentar
Svish Skrevet 9. september 2008 Forfatter Del Skrevet 9. september 2008 hva er fordelen med å ikke caste? billigere ressursmessig? Penere kode? Lenke til kommentar
GeirGrusom Skrevet 9. september 2008 Del Skrevet 9. september 2008 Ok, nå sjekket jeg med disassembly double en_verdi = Math.PI; double dbl_val = Math.Floor(en_verdi); double int_val = (int)en_verdi; Ble til dette double en_verdi = Math.PI; 00000034 fld qword ptr ds:[00CB11B0h] 0000003a fstp qword ptr [ebp-44h] double dbl_val = Math.Floor(en_verdi); 0000003d fld qword ptr [ebp-44h] 00000040 sub esp,8 00000043 fstp qword ptr [esp] 00000046 call 792D3B29 0000004b fstp qword ptr [ebp-5Ch] 0000004e fld qword ptr [ebp-5Ch] 00000051 fstp qword ptr [ebp-4Ch] double int_val = (int)en_verdi; 00000054 movsd xmm0,mmword ptr [ebp-44h] 00000059 cvttsd2si eax,xmm0 0000005d mov dword ptr [ebp-60h],eax 00000060 fild dword ptr [ebp-60h] 00000063 fstp qword ptr [ebp-54h] Wow! jeg er imponert! .NET bruker MMX! Utifra dette ser det ut til at det er mer effektivt å caste. Lenke til kommentar
Manfred Skrevet 9. september 2008 Del Skrevet 9. september 2008 Det ser overraskende mer effektivt ut, ja. Jeg kan ikke skjønne hvorfor de har gjort .Floor() så mye mer omfattende? Lenke til kommentar
GeirGrusom Skrevet 9. september 2008 Del Skrevet 9. september 2008 Og det du ser der er bare overhead fra funksjonskall til Math.Floor. Lenke til kommentar
Manfred Skrevet 9. september 2008 Del Skrevet 9. september 2008 ja, nettopp... :\ Lenke til kommentar
teflonpanne Skrevet 10. september 2008 Del Skrevet 10. september 2008 (endret) Om det er noen forskjell på Math.Floor og cast til int vet jeg ikke, jeg holder en knapp på 'neppe' floor(-2.6) = -3 (int)-2.6 = -2 Det ser overraskende mer effektivt ut, ja. Jeg kan ikke skjønne hvorfor de har gjort .Floor() så mye mer omfattende? Vel, det eneste du ser fra den asm-koden er jo funksjonkalloverheadet, du kan jo ikke se om floor faktisk er mye mer omfattende. Floor er avrunding nedover, casting er trunkering. Men floor er en matematisk definert funksjon som må implementeres deretter ved å ta hensyn til positive og negative verdier, men det kan dog godt hende at det fins en asm-instruksjon for det også, men det kan du ikke se fra koden. En cast mellom to typer er derimot ikke det, og (ihvertfall i C) er det heller ikke definert hvordan en cast fra double/float til int det skal implementeres, den kan f.eks implementeres som floor eller ceiling eller noe helt annet. Men det er vanligst med optimaliserte assemblyinstruksjoner for en slik cast (cvttsd2si eax,xmm0 i GeirGrusom sitt eksempel, som betyr "Convert scalar double-precision floating-point value (with truncation) to signed doubleword of quadword integer (SSE2)"). Og en annnen ting man også må huske på, som gjelder både floor og cast, er at flyttall har avrundingsfeil, så det kan hende du vil slenge på litt epsiloner her og der omtrent som man gjør når man sammenligner to flyttall. Endret 10. september 2008 av teflonpanne Lenke til kommentar
Svish Skrevet 10. september 2008 Forfatter Del Skrevet 10. september 2008 ..., så det kan hende du vil slenge på litt epsiloner her og der omtrent som man gjør når man sammenligner to flyttall. Say whaat? uansett, dette var jo egentlig litt imponerende hva folk kan finne ut av.... hehe. Lenke til kommentar
teflonpanne Skrevet 10. september 2008 Del Skrevet 10. september 2008 ..., så det kan hende du vil slenge på litt epsiloner her og der omtrent som man gjør når man sammenligner to flyttall. Say whaat? uansett, dette var jo egentlig litt imponerende hva folk kan finne ut av.... hehe. Vet du hvordan du tester om to flyttall er like? Hvis du har et flyttall som du kjører gjennom en løkke og inkrementerer med 0.1 for hver gang f.eks og vil teste om det blir 3.14 f.eks, så er det nemlig ikke bare å gjøre if (f == 3.14) som det er med integerer siden flyttall ikke er nøyaktig representert i minnet (se her hvordan ieee-flyttall er implementert med mantissa og eksponent). Du får avrundingsfeil så det er ikke sikkert at f noen gang vil bli akkurat 3.14 men 3.139 eller 3.141 osv, og da vil testen aldri bli true. Så den vanligste metoden er å definere en float epsilon = 0.0001 f.eks og så gjøre if (fabs(3.14 - f) < epsilon) som betyr hvis f ligger 0.0001 innenfor verdien av 3.14 så sier vi at den er lik. Noe av det samme må du da gjøre med floor. Tenk f.eks på floor(0.6/0.2), i C blir dette 2, men 0.6/0.2 er jo 3, men pga flyttall ikke blir representert nøyaktig så blir 0.6/0.2 2.99999etellerannet, så floor(2.999999) = 2. Da kan du f.eks gjøre floor((0.6/0.2) + epsilon) og så blir svaret 3 Lenke til kommentar
Svish Skrevet 10. september 2008 Forfatter Del Skrevet 10. september 2008 ahaa, men da er jeg med bare ikke hørt uttrykket epsilon før. Det vil si, har sikkert hørt det i matten eller fysikken, men må vel ha fallt ut igjen sammen med diverse andre småting, hehe. Lenke til kommentar
Anbefalte innlegg
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 kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå