[c++] static_cast<int> vraagje

Pagina: 1
Acties:

  • Postie
  • Registratie: April 2001
  • Laatst online: 18-08 12:04

Postie

No beer, no glory

Topicstarter
als ik de volgende code heb :
code:
1
2
float f = 9.98;
int i = static_cast<int>(f*100);

dan geeft i de waarde 997. i wordt dus 1 kleiner.

Dit gebeurt bij verschillende waarden van f.
Heeft het iets met afronding te maken wellicht? Wat is
het probleem en hoe los ik het op?

Live every day, as if it's your last one


Verwijderd

maak van de float een double. In Visual C++ geeft ie bij mij een warning als ik die float gebruik:

Warning C4305: 'initializing' : truncation from 'const double' to 'float'

  • Postie
  • Registratie: April 2001
  • Laatst online: 18-08 12:04

Postie

No beer, no glory

Topicstarter
Thnx, dat loste het op. egcs-2.91.66 gaf geen warning.

Live every day, as if it's your last one


  • Postie
  • Registratie: April 2001
  • Laatst online: 18-08 12:04

Postie

No beer, no glory

Topicstarter
Double van gemaakt, leek het op te lossen, maar nu geeft ie bij f=2.30 de waarde 229. Ik snap er niks meer van. Iemand een idee?

Live every day, as if it's your last one


Verwijderd

tja rottig... eigenlijk is dit niet een gebied waar ik veel kennis van heb. Een vriend van me gebruikt wel een afrond functie:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int d2i(double value) 
{ 
     int num; 

     __asm 
     { 
        fld     value //load float value to the stack 
        fistp num  // round it off to a int 
        mov eax, num // make it return the rounded value 
     } 
} 

// ergens anders in de code
double f = 2.30;
int i = d2i(f*100);

dit lijkt beter te werken bij mij.... geen idee of het netjes of het gewenste resultaat heeft bij jou.

Verwijderd

Vond dit ergens:
The cout function that prints a double rounds.

static_cast<int>(some_double) truncates.

Floating point arithetic is *not* exact; in particular, some constants (such as 2.03) cannot be exactly represented in the 64 bit IEEE double precision floating point standard, which gcc uses to represent doubles.

This is due to the fact that 2.03 is a base 10 floating point value, while doubles are represented as base 2 floating point values.

So you start with an imprecise value for 2.03, and this imprecision gets larger each time you multiply by 10.

Eventually, you end up with a value that is just a tiny bit smaller (say, by 2^-50 or so) than 2030.

static_cast<int> truncates this to 2029, since that is the next int lower than 2030 minus a small epsilon.

The operator<<() that cout uses, however, rounds - and rounds it up because the fraction is >=0.5 .

  • Postie
  • Registratie: April 2001
  • Laatst online: 18-08 12:04

Postie

No beer, no glory

Topicstarter
tja rottig... eigenlijk is dit niet een gebied waar ik veel kennis van heb. Een vriend van me gebruikt wel een afrond functie:
Tis op een linux systeem, dat gaat dan vast niet werken (toch?)

Live every day, as if it's your last one


Verwijderd

Op vrijdag 11 januari 2002 00:13 schreef Postie het volgende:

[..]

Tis op een linux systeem, dat gaat dan vast niet werken (toch?)
__asm is Microsoft specific

misschien kun je een alternatief vinden voor linux...

  • Sjonny
  • Registratie: Maart 2001
  • Laatst online: 13:42

Sjonny

Fratser

waarom niet normaal met rint() ?
code:
1
2
double d = 2.30;
int i = rint(d*100);

en je hebt je 230.
check met `man rint` en `man floor` enzo voor varianties.
vergeet math.h niet te includen en -lm erbij te linken.

The problem is in the part of your brain that handles intelligence.


  • Orphix
  • Registratie: Februari 2000
  • Niet online
rint() is geen standaard C++. VC++ herkent het iig niet.
Bij mij voldoet het volgende
code:
1
2
3
#include <cmath>
double f = 2.30;
int i = static_cast<int>(ceil(f*100));

  • Postie
  • Registratie: April 2001
  • Laatst online: 18-08 12:04

Postie

No beer, no glory

Topicstarter
rint() is geen standaard C++. VC++ herkent het iig niet.
Bij mij voldoet het volgende
code:
1
2
3
#include <cmath>
double f = 2.30;
int i = static_cast<int>(ceil(f*100));
Bedankt. Dat lijkt het op te lossen. rint() is idd geen C++ standaard en dat moet het wel zijn. Ik zal nog wat proberen enkele doubles te testen, maar voorlopig ziet het er goed uit.

Live every day, as if it's your last one


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 23:11
Op donderdag 10 januari 2002 22:38 schreef Postie het volgende:
als ik de volgende code heb :
code:
1
2
float f = 9.98;
int i = static_cast<int>(f*100);

dan geeft i de waarde 997. i wordt dus 1 kleiner.

Dit gebeurt bij verschillende waarden van f.
Heeft het iets met afronding te maken wellicht? Wat is
het probleem en hoe los ik het op?
Het probleem is dat float(9.98) < 9.98000...
Als je inderdaad 998/1000 bedoelt, dan heb je geen
float nodig, maar een rational. Omdat die nog niet in standaard C++ zit, moet je even de boost math library downloaden van www.boost.org

boost::rational(998,100)*100 is namelijk wel 998, en heeft geen last van afrondingen e.d.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • PrinsEdje80
  • Registratie: Oktober 2001
  • Laatst online: 01-01 15:26

PrinsEdje80

Holographic, not grated...

Ah, nou snap ik waar dat ontzettend leuke mailtje van de c/c++ maillinglist vandaan kwam ;)

Used to be Down Under... Foto gallery


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 23:11
Op vrijdag 11 januari 2002 10:58 schreef PrinsEdje80 het volgende:
Ah, nou snap ik waar dat ontzettend leuke mailtje van de c/c++ maillinglist vandaan kwam ;)
:?

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Postie
  • Registratie: April 2001
  • Laatst online: 18-08 12:04

Postie

No beer, no glory

Topicstarter
Ah, nou snap ik waar dat ontzettend leuke mailtje van de c/c++ maillinglist vandaan kwam ;)
LOL *D

Live every day, as if it's your last one

Pagina: 1