/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
[C++] Matematik bliver til int
Fra : Rick


Dato : 30-03-05 10:09

Hej i gruppen,

Hvis jeg laver følgende beregning:

double tal = (35-26) / (89-45);

bliver resultatet 0, selvom resultatet skulle have været 0.20454545454545456
Det er fordi at alle tal er int.

Indtil nu har jeg altid rettet fejlen ved at gøre noget lignende følgende:

double tal = (35-26) / (89-45*1.0);

Dette giver dog en multiplicering ekstra i processoren, som sikkert nok
sluger tid (jeg skal lave noget, hvor jeg skal foretage milioner af den
slags beregninger mange gange). Uanset om det tager tid eller ej, så må der
da næsten findes en anden metode! Nogle ideer?

- rick -



 
 
Kim Schulz (30-03-2005)
Kommentar
Fra : Kim Schulz


Dato : 30-03-05 10:33

On Wed, 30 Mar 2005 11:09:09 +0200
"Rick" <rickcool22@hotmail.com> wrote:

> Hej i gruppen,
>
> Hvis jeg laver følgende beregning:
>
> double tal = (35-26) / (89-45);
>
> bliver resultatet 0, selvom resultatet skulle have været
> 0.20454545454545456 Det er fordi at alle tal er int.
>
> Indtil nu har jeg altid rettet fejlen ved at gøre noget lignende
> følgende:
>
> double tal = (35-26) / (89-45*1.0);
>
> Dette giver dog en multiplicering ekstra i processoren, som sikkert
> nok sluger tid (jeg skal lave noget, hvor jeg skal foretage milioner
> af den slags beregninger mange gange). Uanset om det tager tid eller
> ej, så må der da næsten findes en anden metode! Nogle ideer?

så vidt jeg husker kan du sætte d bag på dine tal for at få dem
fortolket som double i stedet for int. du kan vel også bare skrive dine
tal ind som doubles med .0 bagpå ?




--
Kim Schulz | Fundanemt Content Management system:
Geek by nature | http://www.fundanemt.com
schulz.dk | http://www.fundausers.org

Rick (30-03-2005)
Kommentar
Fra : Rick


Dato : 30-03-05 11:56

"Kim Schulz" <kim@schulz.dk> wrote in message
news:20050330113305.1ef51cee@lifesuckz.nork.aau.dk...
On Wed, 30 Mar 2005 11:09:09 +0200

>så vidt jeg husker kan du sætte d bag på dine tal for at få dem
>fortolket som double i stedet for int. du kan vel også bare skrive dine
>tal ind som doubles med .0 bagpå ?

Ja, det har du selvfølgelig ret i - det var vist et lidt dumt eksempel.
Det jeg tænker på er, hvis der nu også er tale om variabler:

double tal = (a - b) / (c - d);

hvor a, b, c og d er af typen int og bliver ændret meget ofte.
Jeg tror dog, at jeg gør følgende:

double tal = ((double)a - b) / (c - d);

Det ser umiddelbart ud til at virke i hvert fald.

- rick -



Thorsten Ottosen (30-03-2005)
Kommentar
Fra : Thorsten Ottosen


Dato : 30-03-05 12:33

"Rick" <rickcool22@hotmail.com> wrote in message
news:424a85ac$0$158$edfadb0f@dread11.news.tele.dk...
| "Kim Schulz" <kim@schulz.dk> wrote in message
| news:20050330113305.1ef51cee@lifesuckz.nork.aau.dk...
| On Wed, 30 Mar 2005 11:09:09 +0200
|
| >så vidt jeg husker kan du sætte d bag på dine tal for at få dem
| >fortolket som double i stedet for int. du kan vel også bare skrive dine
| >tal ind som doubles med .0 bagpå ?
|
| Ja, det har du selvfølgelig ret i - det var vist et lidt dumt eksempel.
| Det jeg tænker på er, hvis der nu også er tale om variabler:
|
| double tal = (a - b) / (c - d);
|
| hvor a, b, c og d er af typen int og bliver ændret meget ofte.
| Jeg tror dog, at jeg gør følgende:
|
| double tal = ((double)a - b) / (c - d);
|
| Det ser umiddelbart ud til at virke i hvert fald.

C-style cast er ikke altid heldige. Hvad nu hvis en double ikke kan indeholde
en int?

double tal = ( boost::numeric_cast<double>(a) - b) / (c - d);

vil kaste en exception ved konverteringsfejl.

-Thorsten



Kent Friis (30-03-2005)
Kommentar
Fra : Kent Friis


Dato : 30-03-05 12:53

Den Wed, 30 Mar 2005 13:33:11 +0200 skrev Thorsten Ottosen:
> "Rick" <rickcool22@hotmail.com> wrote in message
> news:424a85ac$0$158$edfadb0f@dread11.news.tele.dk...
> | "Kim Schulz" <kim@schulz.dk> wrote in message
> | news:20050330113305.1ef51cee@lifesuckz.nork.aau.dk...
> | On Wed, 30 Mar 2005 11:09:09 +0200
> |
> | >så vidt jeg husker kan du sætte d bag på dine tal for at få dem
> | >fortolket som double i stedet for int. du kan vel også bare skrive dine
> | >tal ind som doubles med .0 bagpå ?
> |
> | Ja, det har du selvfølgelig ret i - det var vist et lidt dumt eksempel.
> | Det jeg tænker på er, hvis der nu også er tale om variabler:
> |
> | double tal = (a - b) / (c - d);
> |
> | hvor a, b, c og d er af typen int og bliver ændret meget ofte.
> | Jeg tror dog, at jeg gør følgende:
> |
> | double tal = ((double)a - b) / (c - d);
> |
> | Det ser umiddelbart ud til at virke i hvert fald.
>
> C-style cast er ikke altid heldige. Hvad nu hvis en double ikke kan indeholde
> en int?
>
> double tal = ( boost::numeric_cast<double>(a) - b) / (c - d);
>
> vil kaste en exception ved konverteringsfejl.

Bør du ikke have den på b,c og d også? Ellers er det kun a der bliver
checket.

Men bortset fra det, hvornår kan en double ikke indeholde en int? Man
kan miste en smule præcision, men det er forhåbentlig så lidt er det
er irrelevant efter divisionen. Ellers ville man nok ikke bruge
floating point division.

Mvh
Kent
--
Hard work may pay off in the long run, but lazyness pays off right now.

Thorsten Ottosen (30-03-2005)
Kommentar
Fra : Thorsten Ottosen


Dato : 30-03-05 13:05

"Kent Friis" <nospam@nospam.invalid> wrote in message
news:424a932f$0$43981$14726298@news.sunsite.dk...
| Den Wed, 30 Mar 2005 13:33:11 +0200 skrev Thorsten Ottosen:

| > | double tal = ((double)a - b) / (c - d);
| > |
| > | Det ser umiddelbart ud til at virke i hvert fald.
| >
| > C-style cast er ikke altid heldige. Hvad nu hvis en double ikke kan
indeholde
| > en int?
| >
| > double tal = ( boost::numeric_cast<double>(a) - b) / (c - d);
| >
| > vil kaste en exception ved konverteringsfejl.
|
| Bør du ikke have den på b,c og d også? Ellers er det kun a der bliver
| checket.

yes, og det ville nok være lidt smartere caste uden om summerne a - b og c -
d.

| Men bortset fra det, hvornår kan en double ikke indeholde en int?

hvis sizeof(double) == sizeof(int), så vil der jo være mange ints some ikke
kan være i en double pga. bits brugt til exponenten.

| Man
| kan miste en smule præcision,

tja, jeg mener ikke du kan stole på at du får "et tal tæt på"...det kunne være
helt ude i skoven.

| men det er forhåbentlig så lidt er det
| er irrelevant efter divisionen. Ellers ville man nok ikke bruge
| floating point division.

hvis precision ikke er vigtig, hvorfor bruger du så ikke float? Anyway,
det afhænger jo helt af situationen om man kan tollere en fejl. Men...
indtil man har en god grund til det, så kommer korrekthed altid først.

-Thorsten



Kent Friis (30-03-2005)
Kommentar
Fra : Kent Friis


Dato : 30-03-05 13:47

Den Wed, 30 Mar 2005 14:05:05 +0200 skrev Thorsten Ottosen:
> "Kent Friis" <nospam@nospam.invalid> wrote in message
> news:424a932f$0$43981$14726298@news.sunsite.dk...
> | Den Wed, 30 Mar 2005 13:33:11 +0200 skrev Thorsten Ottosen:
>
> | > | double tal = ((double)a - b) / (c - d);
> | > |
> | > | Det ser umiddelbart ud til at virke i hvert fald.
> | >
> | > C-style cast er ikke altid heldige. Hvad nu hvis en double ikke kan
> indeholde
> | > en int?
> | >
> | > double tal = ( boost::numeric_cast<double>(a) - b) / (c - d);
> | >
> | > vil kaste en exception ved konverteringsfejl.
> |
> | Bør du ikke have den på b,c og d også? Ellers er det kun a der bliver
> | checket.
>
> yes, og det ville nok være lidt smartere caste uden om summerne a - b og c -
> d.
>
> | Men bortset fra det, hvornår kan en double ikke indeholde en int?
>
> hvis sizeof(double) == sizeof(int), så vil der jo være mange ints some ikke
> kan være i en double pga. bits brugt til exponenten.

De kan stadig være der, de vil blot miste præcision. Exponenten gør netop
at maxdouble > maxint når sizeof(double) == sizeof(int).

> | Man
> | kan miste en smule præcision,
>
> tja, jeg mener ikke du kan stole på at du får "et tal tæt på"...det kunne være
> helt ude i skoven.

Det bør under alle omstændigheder være det nærmeste tal typen kan
repræsentere. Om det så er med 8 eller 10 cifres nøjagtighed gør normalt
ikke den store forskel. Og hvis det gør, har man valgt en forkert type.

> | men det er forhåbentlig så lidt er det
> | er irrelevant efter divisionen. Ellers ville man nok ikke bruge
> | floating point division.
>
> hvis precision ikke er vigtig, hvorfor bruger du så ikke float? Anyway,
> det afhænger jo helt af situationen om man kan tollere en fejl. Men...
> indtil man har en god grund til det, så kommer korrekthed altid først.

Absolut korrekthed opnås under ingen omstændigheder med floating point.
Det vil altid være et spørgsmål om hvor meget præcision er påkrævet.

Mvh
Kent
--
Hard work may pay off in the long run, but lazyness pays off right now.

Thorsten Ottosen (30-03-2005)
Kommentar
Fra : Thorsten Ottosen


Dato : 30-03-05 10:44

"Rick" <rickcool22@hotmail.com> wrote in message
news:424a6cae$0$172$edfadb0f@dread11.news.tele.dk...
| Hej i gruppen,
|
| Hvis jeg laver følgende beregning:
|
| double tal = (35-26) / (89-45);
|
| bliver resultatet 0, selvom resultatet skulle have været 0.20454545454545456
| Det er fordi at alle tal er int.
|
| Indtil nu har jeg altid rettet fejlen ved at gøre noget lignende følgende:
|
| double tal = (35-26) / (89-45*1.0);
|
| Dette giver dog en multiplicering ekstra i processoren, som sikkert nok
| sluger tid

kan du vise det med en test? (jeg tror ikke du vil kunne se forskel på
assembleren)

| (jeg skal lave noget, hvor jeg skal foretage milioner af den
| slags beregninger mange gange). Uanset om det tager tid eller ej, så må der
| da næsten findes en anden metode! Nogle ideer?

double tal = (35-26) / (89-45. );
^^^^^

-Thorsten



Rick (30-03-2005)
Kommentar
Fra : Rick


Dato : 30-03-05 12:32

"Thorsten Ottosen" <nesotto@cs.auc.dk> wrote in message
news:424a74ef$0$43993$14726298@news.sunsite.dk...
>
> kan du vise det med en test? (jeg tror ikke du vil kunne se forskel på
> assembleren)
>
Den samlede kode er ikke færdig. Men der er ikke så meget i det andet end
det.
Beregningen skal foregå i en løkke, hvor tallene er udskiftet med
int-variabler.

- rick -



Kim Schulz (30-03-2005)
Kommentar
Fra : Kim Schulz


Dato : 30-03-05 12:43

[snip]
> C-style cast er ikke altid heldige. Hvad nu hvis en double ikke kan
> indeholde en int?
>
> double tal = ( boost::numeric_cast<double>(a) - b) / (c - d);
>
> vil kaste en exception ved konverteringsfejl.

kræver så at man har boost inde.

--
Kim Schulz | Fundanemt Content Management system:
Geek by nature | http://www.fundanemt.com
schulz.dk | http://www.fundausers.org

Ukendt (30-03-2005)
Kommentar
Fra : Ukendt


Dato : 30-03-05 12:51

Rick wrote:
> double tal = (35-26) / (89-45);
> bliver resultatet 0, selvom resultatet skulle have været 0.20454545454545456
> Det er fordi at alle tal er int.

Prøv med

double tal = (35-26) / (89-45.0f);

aggregator.remove@th~ (30-03-2005)
Kommentar
Fra : aggregator.remove@th~


Dato : 30-03-05 14:55

Rick wrote:
> double tal = (35-26) / (89-45*1.0);
[...]
> Dette giver dog en multiplicering ekstra i processoren, som sikkert nok
> sluger tid

Medmindre man bruger en totalt hjernedød oversætter, så vil det sidste
multiplicering med 1.0 blive optimeret væk.
Så du kan roligt fortsætte med at 'fixe' problemet den gamle måde.


--
If you pull the pin, mr. Grenade would no longer be your friend.

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

Månedens bedste
Årets bedste
Sidste års bedste