/ Forside / Teknologi / Udvikling / VB/Basic / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
VB/Basic
#NavnPoint
berpox 2425
pete 1435
CADmageren 1251
gibson 1230
Phylock 887
gandalf 836
AntonV 790
strarup 750
Benjamin... 700
10  tom.kise 610
Altid runde op
Fra : Tomas Christiansen


Dato : 18-12-02 14:36

Kære visualbasicprogrammørinternetnyhedsgruppelæsere

Hvordan vil I forslå at jeg gør, når jeg står med et tal (af typen Double), som jeg ønsker skal rundes op (altid op!), såfremt
tallet ikke er et heltal.

Bemærk at der er sket udregninger på tallet forinden, så man kan ikke være helt sikker på at hele tal er _helt_ hele (om man så må
sige)...

-------
Tomas


 
 
///JJ (18-12-2002)
Kommentar
Fra : ///JJ


Dato : 18-12-02 15:12

"Tomas Christiansen" <toc-nospam-01@blikroer.dk> wrote in message
news:atptkl$1u2i$1@news.cybercity.dk...
> Hvordan vil I forslå at jeg gør, når jeg står med et tal (af typen
Double), som jeg ønsker skal rundes op (altid op!), såfremt
> tallet ikke er et heltal.

http://support.microsoft.com/default.aspx?scid=kb;EN-US;196652

Alt afhængig af om du har negative værdier og hvordan du ønsker dem
behandlet:

AsymUp Asymmetrically rounds numbers fractions up.
Same as SymDown for negative numbers.
Similar to Ceiling.

SymUp Symmetrically rounds fractions up - that is, away from 0.
Same as AsymUp for positive numbers.
Same as AsymDown for negative numbers.



Function AsymUp(ByVal X As Double, _
Optional ByVal Factor As Double = 1) As Double
Dim Temp As Double
Temp = Int(X * Factor)
AsymUp = (Temp + IIf(X = Temp, 0, 1)) / Factor
End Function

Function SymUp(ByVal X As Double, _
Optional ByVal Factor As Double = 1) As Double
Dim Temp As Double
Temp = Fix(X * Factor)
SymUp = (Temp + IIf(X = Temp, 0, Sgn(X))) / Factor
End Function



mvh
///JJ



Tomas Christiansen (18-12-2002)
Kommentar
Fra : Tomas Christiansen


Dato : 18-12-02 23:10

///JJ skrev:
> Function AsymUp(ByVal X As Double, _
> Optional ByVal Factor As Double = 1) As Double
> Dim Temp As Double
> Temp = Int(X * Factor)
> AsymUp = (Temp + IIf(X = Temp, 0, 1)) / Factor
> End Function
>
> Function SymUp(ByVal X As Double, _
> Optional ByVal Factor As Double = 1) As Double
> Dim Temp As Double
> Temp = Fix(X * Factor)
> SymUp = (Temp + IIf(X = Temp, 0, Sgn(X))) / Factor
> End Function

Det var fint. Jeg var ikke klar over at MS har en artikel liggende
omkring dette emne, MEN...

De gør jo netop det, som jeg antyder kan være et problem: Forventer at
hvis tallet er (læs: er meningen at det skal være) et helt tal, f.eks.
1, kan det godt være at den binære repræsentation - efter at der er
foretaget adskillige beregninger på variablen - rent faktisk er noget
i retning af 0,9999999999999... (op til den maksimalt repræsenterbare
antal betydende decimaler).

Med andre ord vil en Fix(X) _ikke_ give 1 som forventet men 0, og en
sammenligning X=1 vil være falsk.

Et klassisk eksempel er X=1/3*3, som altså bare ikke duer mere, fordi
beregningsrutinerne faktisk er så smarte, at de foretager små
justeringer undervejs som klarer mange af den slags småproblemer, men
så lad os da producere et lidt mere komplekst eksempel til formålet:

y = 49
x = 2 / y
x = 3 - x * y

Værdien i x burde nu være 1, men det er den ikke. Den er lige nøjagtig
en lille bitte minimal mikroskopisk smule større end 1.

Udfør derefter SymUp og AsymUp på x, og 1-tallet vil nu blive rundet
op til 2. Det er ikke særlig rart, når man forventer et 1-tal.

Problemet er ganske kort berørt i slutningen af den MS artikel, som du
henviser til:
"Since not all fractional values can be expressed exactly, you might
get unexpected results because the display value does not match the
stored value."

Grundet til at jeg skrev indlægget i gruppen var netop for at høre
nogle forslag fra nogle, som aktivt har taget stilling til denne
problemstilling og fundet på nogle brugbare løsning. Jeg mener at MS
stikker hovedet lidt i busken, ved kun at berøre emnet så kort som de
gør i den eller udmærkede artikel, som du henviste til.

Er der nogen med et bud...
....eller stikker alle andre også hovedet i busken, krydser fingrene og
tænker "det går nok". Hvis der opstår en fejl, skyder vi bare skylden
på brugeren...

-------
Tomas


Finn Tolderlund (19-12-2002)
Kommentar
Fra : Finn Tolderlund


Dato : 19-12-02 09:44

Du kan sige at MS stikker hovedet i busken.
Men der er ikke noget MS kan gøre ved det.
Dette problem kan ikke undgås i floating point beregninger.
Der er de samme problemer og konskvenser i alle programmeringssprog der
benytter floating point variabler. Det gælder ikke kun i programmeringssprog
fra MS.
Det er en naturlig konskvens af den måde som man nu en gang har valgt at
opbevare decimaltal i computeren hvor et decimaltal deles deles op i tre
dele: sign, exponent og mantissa.
Det er stammer sikkert fra den måde cpu'en laver beregninger på decimaltal
hvor cpu kun kan foretage decimaltalsberegninger på tal der er opdelt på
denne måde.
Og som artiklen fra MS ganske rigtigt siger så er det altså ikke muligt at
udtrykke alle decimal tal i floating point. Et tal som 2 / 49 fra dit
eksempel kan ikke udtrykkes præcist i floating point.
Der er ikke noget at gøre ved det, andet end at leve med det.
--
Finn Tolderlund


"Tomas Christiansen" <toc-nospam-01@blikroer.dk> wrote in message
news:atqroc$4pd$1@news.cybercity.dk...
> Problemet er ganske kort berørt i slutningen af den MS artikel, som du
> henviser til:
> "Since not all fractional values can be expressed exactly, you might
> get unexpected results because the display value does not match the
> stored value."
>
> Grundet til at jeg skrev indlægget i gruppen var netop for at høre
> nogle forslag fra nogle, som aktivt har taget stilling til denne
> problemstilling og fundet på nogle brugbare løsning. Jeg mener at MS
> stikker hovedet lidt i busken, ved kun at berøre emnet så kort som de
> gør i den eller udmærkede artikel, som du henviste til.



Tomas Christiansen (19-12-2002)
Kommentar
Fra : Tomas Christiansen


Dato : 19-12-02 20:53

Finn Tolderlund skrev en masse fornuftigt, som er i og for sig er enig
i bortset fra:
> Du kan sige at MS stikker hovedet i busken.
> Men der er ikke noget MS kan gøre ved det.

Jo. På samme måde som at man selv kan implementere en løsning på så
mange andre problemer (f.eks. alle dem, som de giver en løsning på i
den omtalte artikel). En lille funktion som hjælper til at
fjerne/mindske problemet

Èn løsning kan være at kigge på hvor tæt tallet er på et heltal, og
hvis værdien er tættere på et heltal end værdien Q, skal den rundes
op/ned til dette heltal.

Der er allerede sket en positiv udvikling på dette område, hvilket man
hurtigt overbeviser sig om, hvis man prøver at dividere et X med Y og
derefter gange med Y. Der er ikke så voldsomt mange X,Y'er, som man
måske kunne forvente, hvor det går galt,

-------
Tomas


Finn Tolderlund (20-12-2002)
Kommentar
Fra : Finn Tolderlund


Dato : 20-12-02 11:21


"Tomas Christiansen" <toc-nospam-01@blikroer.dk> wrote in message
news:att83k$kns$1@news.cybercity.dk...
> Finn Tolderlund skrev en masse fornuftigt, som er i og for sig er enig
> i bortset fra:
> > Du kan sige at MS stikker hovedet i busken.
> > Men der er ikke noget MS kan gøre ved det.
>
> Jo. På samme måde som at man selv kan implementere en løsning på så
> mange andre problemer (f.eks. alle dem, som de giver en løsning på i
> den omtalte artikel). En lille funktion som hjælper til at
> fjerne/mindske problemet
>
> Èn løsning kan være at kigge på hvor tæt tallet er på et heltal, og
> hvis værdien er tættere på et heltal end værdien Q, skal den rundes
> op/ned til dette heltal.

Den holder bare ikke.
For det første, hvis det var så nemt så var det jo nok allerede blevet
indbygget i diverse programmeringssprog eller i cpu'en.
For det andet, og det er for mig det væsentligste, jeg vil aldeles og
bestemt have mig frabedt at mine beregninger bliver ændret nogen måder.
Hvis jeg et sted i min kode vil have et tal justeret så skal jeg nok selv
gøre det, der hvor jeg ønsker det og ikke andre steder.
--
Finn Tolderlund



Tomas Christiansen (20-12-2002)
Kommentar
Fra : Tomas Christiansen


Dato : 20-12-02 14:04

Finn Tolderlund skrev:
> For det første, hvis det var så nemt så var det jo nok allerede blevet
> indbygget i diverse programmeringssprog eller i cpu'en.
> For det andet, og det er for mig det væsentligste, jeg vil aldeles og
> bestemt have mig frabedt at mine beregninger bliver ændret nogen måder.

Jamen det er det jo allerede!!!!! Det virker blot "kun" i 98% af tilfældene.

> Hvis jeg et sted i min kode vil have et tal justeret så skal jeg nok selv
> gøre det, der hvor jeg ønsker det og ikke andre steder.

Det er jo netop det, som jeg efterlyser: En metode til at justere tal med, så alle ikke skal sidde og opfinde den dybe tallerken på
ny.

-------
Tomas


///JJ (19-12-2002)
Kommentar
Fra : ///JJ


Dato : 19-12-02 14:06

"Tomas Christiansen" <toc-nospam-01@blikroer.dk> wrote in message
news:atqroc$4pd$1@news.cybercity.dk...
> Udfør derefter SymUp og AsymUp på x, og 1-tallet vil nu blive rundet
> op til 2. Det er ikke særlig rart, når man forventer et 1-tal.
>
> Problemet er ganske kort berørt i slutningen af den MS artikel, som du
> henviser til:
> "Since not all fractional values can be expressed exactly, you might
> get unexpected results because the display value does not match the
> stored value."

Ahh - det missede jeg.
Kan det ikke løses ved at regne med færre dicimaler eller andre vartyper?
Det må da kunne løses :)

mvh
///JJ



Tomas Christiansen (19-12-2002)
Kommentar
Fra : Tomas Christiansen


Dato : 19-12-02 20:56

///JJ skrev:
> Kan det ikke løses ved at regne med færre dicimaler eller andre
vartyper?

Du mener vel _flere_ decimaler?

Prøv at skrive værdien 1/3 (1 divideret med 3) op i decimal-systemet,
og se hvor mange decimaler der skal til for at repræsentere værdien
eksakt (hint: et liggende 8-tal)

-------
Tomas


Søg
Reklame
Statistik
Spørgsmål : 177557
Tips : 31968
Nyheder : 719565
Indlæg : 6408879
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste