[alg] Hele waarde uit decimaal getal halen.

Pagina: 1
Acties:

  • Limhes
  • Registratie: Oktober 2001
  • Laatst online: 19-08 19:06
Hoe haal ik in het algemeen de hele waarde uit een decimaal getal? Ik wil dit dus zonder ingebouwde functies doen en ook niet naar string converteren en dan splitten op '.' ofzo. Is dit uberhaupt mogelijk? Ik kom er in ieder geval echt niet uit...

En ACM/Wasigh, de post kan ook naar W&L als jullie dat per sé willen...

offtopic:

Verwijderd

Je kan iets proberen als:
code:
1
2
var getal = "6.5"
alert(getal.substring(0,getal.indexOf(".")))

getal moet dan wel een string zijn. En je rond altijd naar beneden af.

Misschien moet je voor je taal wel de syntax aanpassen ;)

Verwijderd

Ben ff bezig geweest..maar hiet is 't dan
code:
1
2
3
4
5
6
7
<script>
var getal = "6.546546546"

getal = (parseInt(getal.substring((getal.indexOf(".") + 1),(getal.indexOf(".") + 2))) >= 5)? (parseInt(getal.substring(0,getal.indexOf(".")))+1):getal.substring(0,getal.indexOf("."))

alert(getal)
</script>

De alert geeft dus netjes 7 terug en vul je 568.235 in dan krijg je netjes 568 terug enz..

Het is nogsteeds in 1 regel code want een variable met een getal had je vast al.

Had wel ff zin in iets speciaals te coden :z

Verwijderd

Op dinsdag 26 maart 2002 20:15 schreef Limhes het volgende:
en ook niet naar string converteren en dan splitten op '.' ofzo.
Eeh vanDee, zonder naar string te converteren en splitten zegt íe.

Limhes, in het algemeen zou je kunnen proberen om het getal in een variabele te stoppen die geen decimalen toestaat, denk hierbij aan het stoppen van een float in een integer. Hierbij zullen de decimalen verloren gaan.
Ook kun je typecasten (java, c++), door (int) getal te doen.

Verwijderd

Op dinsdag 26 maart 2002 20:53 schreef cynical het volgende:

[..]

Eeh vanDee, zonder naar string te converteren en splitten zegt íe.
Je moet toch wat?
Op dinsdag 26 maart 2002 20:53 schreef cynical het volgende:
Limhes, in het algemeen zou je kunnen proberen om het getal in een variabele te stoppen die geen decimalen toestaat, denk hierbij aan het stoppen van een float in een integer. Hierbij zullen de decimalen verloren gaan.
Ook kun je typecasten (java, c++), door (int) getal te doen.
Dat is natuurlijk logisch, maar niet elke taal ondersteund dit, bijvoorbeeld ASP en JavaScript. En dan moet je toch wat anders

Verwijderd

Helemaal waar. Jij hebt de oplossing voor PHP gegeven, ik voor java en c/c++ :-)

Verwijderd

Gelukkig,
zijn we het allebij eens....
maar de vraag is natuurlijk is werkt het ook voor Limhes.....dus wachten maar ff af

  • Goodielover
  • Registratie: November 2001
  • Laatst online: 18-08 11:34

Goodielover

Only The Best is Good Enough.

Onmogelijk zonder ingebouwde functies.
Wat is een taal zonder ingebouwde functies?
zelfs optellen en aftrekken zijn ingebouwde functies.
Is dit een vervroegde 1 april grap?
Op dinsdag 26 maart 2002 20:15 schreef Limhes het volgende:
Hoe haal ik in het algemeen de hele waarde uit een decimaal getal? Ik wil dit dus zonder ingebouwde functies doen en ook niet naar string converteren en dan splitten op '.' ofzo. Is dit uberhaupt mogelijk? Ik kom er in ieder geval echt niet uit...

En ACM/Wasigh, de post kan ook naar W&L als jullie dat per sé willen...

offtopic:

Verwijderd

Onmogelijk zonder ingebouwde functies.
Wat is een taal zonder ingebouwde functies?
zelfs optellen en aftrekken zijn ingebouwde functies.
smartass ;)

  • Limhes
  • Registratie: Oktober 2001
  • Laatst online: 19-08 19:06
owkee peepz...

Wat jullie schrijven is geen oplossing... Ik vroeg mij dus af of het _wiskundig_ mogelijk is om zoiets te doen, dus door bepaalde _wiskundige_ berekeningen erop los te laten.

Maar volgens mij is dat dus onmogelijk.

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
_wiskundig_ is het gewoon [3.141592] = 3 (of was het nou |3.141592| = 3? maargoed, het is gewoon een definitie, heeft niets met algoritmen te maken)

  • tomato
  • Registratie: November 1999
  • Niet online
Zoals marcusk al aangeeft is het gewoon een kwestie van definieren. Wil jij een wiskunde waarin iets dergelijks gedefinieerd is? Maak dan duidelijke regels en geef daar een syntax aan.
Overigens zijn die er inderdaad al ;)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 09-09 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op dinsdag 26 maart 2002 22:34 schreef marcusk het volgende:
_wiskundig_ is het gewoon [3.141592] = 3 (of was het nou |3.141592| = 3? maargoed, het is gewoon een definitie, heeft niets met algoritmen te maken)
die laatste is het iig niet, want dat is de absolute waarde van een getal (en die is gedefinieerd als de wortel uit x02 + x12 + x22 + ... + xn-12, waarbij n het aantal dimensies is van x. Gebaseerd op de stelling van Pythagoras dus :))

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Op dinsdag 26 maart 2002 22:48 schreef OiSyN het volgende:
die laatste is het iig niet, want dat is de absolute waarde van een getal
ow ja, is waar ook :)
en die is gedefinieerd als de wortel uit x02 + x12 + x22 + ... + xn-12, waarbij n het aantal dimensies is van x. Gebaseerd op de stelling van Pythagoras dus :)
oh, dat wist ik niet :) (ik dacht dus dat het gewoon de positieve waarde was, maar dit verklaart ook de notatie voor de lengte van een vector :))

  • Limhes
  • Registratie: Oktober 2001
  • Laatst online: 19-08 19:06
dimensies van x?

maar het is dus niet mogelijk?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 09-09 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

nou ik weet de notatiewijze niet (en of ie er wel is), maar de helft van de wiskunde is gebaseerd op afspraken, dus hier is vast ook wel een afspraak voor te verzinnen.

Maar als je bedoelt of er misschien een formule voor is: nee, die is er niet :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 09-09 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

oh, tip: Eric Weisstein's world of mathemathics (mathworld.wolfram.com)

als je iets wiskundigs of natuurkundigs zoekt, gegarandeerd dat het er tussen staat (is een tijdje offline geweest wegens copyright-problemen, maar is weer live and kicking >:))

.edit: en dan komen we gelijk op deze pagina: http://mathworld.wolfram.com/StaircaseFunction.html

Afbeeldingslocatie: http://mathworld.wolfram.com/s3img652.gif: afronden naar de dichtbijzijnde integer
Afbeeldingslocatie: http://mathworld.wolfram.com/s3img651.gif: afronden naar beneden (bekend als floor () in veel programmeertalen)
Afbeeldingslocatie: http://mathworld.wolfram.com/s3img650.gif: naar boven afronden (bekend als ceil () in veel programmeertalen)

markusk had dus gelijk met z'n [x] :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • RickN
  • Registratie: December 2001
  • Laatst online: 14-06-2025
Euh, misschien was dit onzin

edit:
Mja, het was niet helemaal onzin, maar te mierenneukerig om toegevoegde waarde te hebben voor dit draadje...

He who knows only his own side of the case knows little of that.


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 09-09 20:58

Janoz

Moderator Devschuur®

!litemod

Als je het echt op het processor niveau wilt aanpakken (als enige toegelaten 'standaardfuncties') zul je eerst moeten begrijpen hoe een float opgeslagen wordt. In principe zou je met simpel optellen en aftrekken en schuiven icm het kunnen opvragen van de verschillende bits in het getal kunnen afronden :)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Je kan natuurlijk ook gaan bitshiften...
Kwestie van uitzoeken wat het formaat is van de float die je gebruikt en dan is het een kwestie van parsen op bit niveau. uiteraard het decimale deel weg gooiend.

  • RickN
  • Registratie: December 2001
  • Laatst online: 14-06-2025
Er is nog een mogelijkheid, het shiften van bits. Dan moet je eerst even uitzoeken hoe een float in elkaar zit en dan kun je met shiften, masken en andere bit operaties je float afronden. Eigenlijk ben je dan op bitniveau aan het parsen.

Sorry, moest ff >:) . Echt NOFI verder

He who knows only his own side of the case knows little of that.


  • ArieProductions
  • Registratie: Januari 2002
  • Laatst online: 27-11-2024
hum, in Delphi:
code:
1
2
3
4
5
6
7
8
9
10
11
var
  aValue : Variant;
  aInteger : Integer;
  aFloat : Double;

begin

  aFloat := 6.5;
  aValue := aFloat;
  aInteger := aValue;
end;

Of heb ik het nu niet goed begrepen?

"Quidquid latine dictum sit, altum videtur" (Whatever is said in Latin sounds profound)


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 09-09 20:58

Janoz

Moderator Devschuur®

!litemod

Op woensdag 27 maart 2002 14:56 schreef ArieProductions het volgende:
hum, in Delphi:
code:
1
2
3
4
5
6
7
8
9
10
11
var
  aValue : Variant;
  aInteger : Integer;
  aFloat : Double;

begin

  aFloat := 6.5;
  aValue := aFloat;
  aInteger := aValue;
end;

Of heb ik het nu niet goed begrepen?
Ja joh, laat het gewoon door de compiler oplossen :)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Limhes
  • Registratie: Oktober 2001
  • Laatst online: 19-08 19:06
kee kga het op bit-niveau oplossen...

eindelijk iets waarbij ik het kan toepassen...

edit:

niet toevallig iemand die me 'n link kan geven naar 'n pagina hoe staat hoe een float wordt opgeslagen?

  • Bart Coppens
  • Registratie: April 2000
  • Laatst online: 25-11-2021
In mijn Delphi 3 language bookje stond dat dacht ik, ik kijk het wel ff na :)Edit:
Uit: Object Pascal Language Guide - Internal data formats:
The floating-point types (Real, Single, Double and Extended) store the binary representations of a sign (+or-), an exponent, and a significant. A represented number has the vaue
+/- significand * 2 exponent
where the significand has a single bit to the left of the binary decimal point (that is, 0<=significand<2).
Dan volgt een overzichtje van de verschillende types van floating points.

Edit2:Toch ff een voorbeeldje van The Real Type meegeven:
A 6-byte (48-bit) Real number is devided into three fields:
code:
1
2
3
4
width in bits
1           39         8
[s][          f     ][   e   ]
   msb            lsb  msb   lsb

The value v of the number is determined by the following:
if 0 < e <= 255 then v = (-1s * 2(e-129) * (1.f)
if e = 0 then v = 0
(msb en lsb zijn most significant bit en least significant bit)

Copyright Auteur heeft Tweakers.net BV geen exclusieve licentie op bovenstaande post verleend. Voorafgaande en uitdrukkelijke schriftelijke toestemming van Tweakers.net BV is dus niet noodzakelijk voor het vermenigvuldigen van bovenstaande post


  • Goodielover
  • Registratie: November 2001
  • Laatst online: 18-08 11:34

Goodielover

Only The Best is Good Enough.

Dit heeft toch allemaal geen zin. Nu ga je uitzoeken hoe een bepaalde programmeer-omgeving een float opslaat.
Het lijkt me dan toch echt eenvoudiger gewoon een INT() functie oid te gebruiken. Mijn vorige post was niet als grap bedoeld. Je programmeert in een taal en gebruik de functionaliteit van die taal, daar 'ie voor!
Wat je nu gaat doen is de INT() functie van een taal nabouwen met alle nadelige gevolgen van dien.

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 09-09 20:58

Janoz

Moderator Devschuur®

!litemod

Goodielover, je hebt op zich volkomen gelijk. Het afronden van getallen of het converteren van een float naar een integer moet je overlaten aan de daarvoor beschikbare functies.

Echter, er is helemaal niks mis met het babbelen over hoe dit eigenlijk intern gebeurt. Daarnaast is het, waneer je dingen met floats gaat doen, wel erg handig als je ook weet hoe deze werken. Het practicum 'Inleiding numerieke wiskunde' bij Informatica aan de RuG begint niet voor niks met het uitpluizen van de grenzen van een float. Waneer je de preciese opmaak van een float weet kun je een berekening maken van wat de maximale fout is van je huidige uitkomst. Dat lijkt mischien overbodig, maar zoals iedereen die op de middelbare school natuurkunde heeft gehad weet, kan die fout behoorlijk doorwerken en in het gebied terecht komen waarvan je in 1ste instantie zou denken dat het nog steeds significant was. Een veel duidelijker voorbeeld in de praktijk is echter dat je 2 floats nooit met a==b, maar met abs(a-b) < epsilon moet vergelijken.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Goodielover
  • Registratie: November 2001
  • Laatst online: 18-08 11:34

Goodielover

Only The Best is Good Enough.

Janoz ook jij hebt gelijk. Zoals je in mijn profile kan zien heb ik UT-informatica gedaan en het nut van detailkennis op dit vlak is mij bekend. Je snapt beter wat je programmeert. Het leek echter in dit topic niet die kant op te gaan. Hij leek een probleem te hebben en vroeg hier om hulp.
Op woensdag 27 maart 2002 21:10 schreef Janoz het volgende:
Goodielover, je hebt op zich volkomen gelijk. Het afronden van getallen of het converteren van een float naar een integer moet je overlaten aan de daarvoor beschikbare functies.

Echter, er is helemaal niks mis met het babbelen over hoe dit eigenlijk intern gebeurt. Daarnaast is het, waneer je dingen met floats gaat doen, wel erg handig als je ook weet hoe deze werken. Het practicum 'Inleiding numerieke wiskunde' bij Informatica aan de RuG begint niet voor niks met het uitpluizen van de grenzen van een float. Waneer je de preciese opmaak van een float weet kun je een berekening maken van wat de maximale fout is van je huidige uitkomst. Dat lijkt mischien overbodig, maar zoals iedereen die op de middelbare school natuurkunde heeft gehad weet, kan die fout behoorlijk doorwerken en in het gebied terecht komen waarvan je in 1ste instantie zou denken dat het nog steeds significant was. Een veel duidelijker voorbeeld in de praktijk is echter dat je 2 floats nooit met a==b, maar met abs(a-b) < epsilon moet vergelijken.

  • udenjpg
  • Registratie: November 2000
  • Niet online

udenjpg

C8H10N4O2

Afronden = 0,5 optellen en alles voor de , meenemen.

Coffee isn't a matter of life and death. It's far more important than that.


Verwijderd

waarom doe je niet gewoon zoiets? :
(heb ik zelf nl nogal een tijdje gedaan voordat ik Int() kende.

(asp way trouwens, ken nog niet veel anders:)
--------------------
inta = 5.123128
intb = inta
While inta > 1
inta = inta - 1
Wend
intb = intb - inta
--------------------
geeft intb waarde van 5

Verwijderd

Zoiets, is bijna het zelfde
code:
1
2
3
4
5
6
7
8
intA = 5.123128
intB = intA

while(intA > 1) {
     intA--
     }

intB = intB - intA

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 09-09 20:58

Janoz

Moderator Devschuur®

!litemod

en toen moest je een negatief getal afronden :+ ... overflow :)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 09-09 11:02
En toen moest je opeens 1.3*2^8000 afronden.

  • Goodielover
  • Registratie: November 2001
  • Laatst online: 18-08 11:34

Goodielover

Only The Best is Good Enough.

Dit getal is nit af te ronden. Zoveel preciesie heb je niet.

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op dinsdag 02 april 2002 22:35 schreef Goodielover het volgende:
Dit getal is nit af te ronden. Zoveel preciesie heb je niet.
Jij misschien niet... :+
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
[acm@magnus acm]$ bc
bc 1.05
Copyright 1991, 1992, 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
1.3 * 2^8000
22589606415195229357997717973426631518052172193015242571132527245424\
10888291954110046226337191571106394041526708119098773833931142286782\
33096336391074223252156156370740124350362318708826080528921197750253\
23496635397597858776958763576561745478021059812346477909024852117935\
90294857854192096014552970852620147471002148470444835111399464191344\
95870943040793096896145884922179130629760829261133427855047091410807\
95379994430137732677183524369627734081052102213484445743242521880966\
98970075312496757539926274513283466211724420812209540314575159424431\
86984500311493368890436811954772018908307465174153136164678982799485\
31143270712249203576815639401305753596237740601065895441227832220787\
80602484953939515620990876055127692631592426285184210303895203098142\
74407714079857865032364012616181266629030036996378403244916942860345\
95322584086289918927007369271285195726459107280741883277591455829292\
77219738672171795172053919268522848773764334911374150913395322707207\
08210207136522379282531882202232640254780922175632131441328099334299\
64647053731982847179730588526274201742514076451710633236658674152630\
21703277094774839528785677767189191416839188911424219192107324773028\
39228711704394299463400586038490456181830265877298907618428871813214\
54979803579026412719030018546716261210793682837792234343435693607015\
48476755552202916454939917249822216108614817261492811951627068483277\
07729108555493221572893142689243353135752973935949849127498492735777\
32229552211106654170189941937511832335395927837081213931002932590965\
73943353031548675509405622116114897636890846135313576052240002941632\
73735146251521305563202159684847686597620636781308649693775868557026\
40856107093051518218679342483469946839668842279602612872369018371751\
06315901815258475665437973130395538566868624428463740128515587833922\
12976121903356978549316977743542366226343844698213983771392767670326\
07468694913129235366119832401377436825758757670589472696332073285479\
36156660899710052558142579289020469054868886489529266638017714719832\
76482656224697373887738485264828703949483674696970149969718502883914\
75497893448126132692039639927325605232218828675361125857229829894538\
19188114965208410546377417536686418639720844025647899763820473392922\
51609214140439021688500031376840183001966204423507273930979140468945\
03867300167045709273971342364584730533429242559018707595742368614016\
96352617510883084093034498818044592385676756835963136610126357716799\
90962549398844971980925226188.8

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 09-09 20:58

Janoz

Moderator Devschuur®

!litemod

Op dinsdag 02 april 2002 22:38 schreef ACM het volgende:

[..]

Jij misschien niet... :+
Jij ook niet :) .. Ik zie nog steeds cijfers achter de punt :+

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op dinsdag 02 april 2002 22:44 schreef Janoz het volgende:
Jij ook niet :) .. Ik zie nog steeds cijfers achter de punt :+
En zijn opmerking was dat er niet genoeg preciezie is ;)

  • MisterE
  • Registratie: April 2002
  • Laatst online: 19:21
als je delphi gebruikt kun je Trunc(real value) gebruiken

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 09-09 20:58

Janoz

Moderator Devschuur®

!litemod

Op dinsdag 02 april 2002 22:55 schreef MisterE het volgende:
als je delphi gebruikt kun je Trunc(real value) gebruiken
Lees het topic eens... Het gaat juist om het niet gebruiken van interne functies...

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 09-09 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

in Game Programming Gems II staat een stukje over een efficiente conversie van float naar int dmv bitlevel hacking. Als je wilt kan ik het overtypen (ik heb geen zin om het helemaal over te typen als er niemand in geinteresseerd is, vandaar dat ik het eerst vraag :))

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 09-09 11:02
Op dinsdag 02 april 2002 23:04 schreef OiSyN het volgende:
in Game Programming Gems II staat een stukje over een efficiente conversie van float naar int dmv bitlevel hacking.
Hmm, dit lijkt me redelijk eenvoudig. Je leest de exponent uit, neemt zoveel bits vanaf de linkerkant van de mantissa, voegt vervolgens de hidden bit toe aan de linkerkant en het resultaat geef je weer als ware het een getal in binaire representatie.

Als de exponent negatief is is je resultaat 0. Als de exponent groter is dan het aantal bits in de mantissa kun je 't resultaat aan de rechterkant aanvullen met een aantal willekeurige bits gelijk aan de exponent minus het aantal bits van de mantissa, hoewel je eigenlijk niet kan zeggen welke waarde die bits zouden moeten hebben.

Oh, en het omzetten van floats naar ints kan de FPU sinds de 486 DX toch nog altijd het meest efficiënt.

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op dinsdag 02 april 2002 23:23 schreef Soultaker het volgende:
Oh, en het omzetten van floats naar ints kan de FPU sinds de 486 DX toch nog altijd het meest efficiënt.
Wat geloof ik ook min of meer de reden is dat je het wel met ingebouwde functie moet doen (die dan hopelijk goed gecompiled wordt) ;)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 09-09 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op dinsdag 02 april 2002 23:23 schreef Soultaker het volgende:
Oh, en het omzetten van floats naar ints kan de FPU sinds de 486 DX toch nog altijd het meest efficiënt.
denk het niet, anders zouden ze wel gewoon een fistp doen.
Maar het gaat meer om het feit dat in C er nogal wat criteria zijn waaraan de conversiefunctie moet voldoen; de standaard conversie van float naar int duurt al gauw zo'n 60 (!!!) cycles op een Pentium II (dat is inclusief de rounding modus zetten en weer terug zetten). De criteria die ANSI C stelt is namelijk dat de FPU standaard moet rounden naar de nearest int (ik gebruik even engelse termen, dat is voor mij en ik denk de meeste wat makkelijker). Terwijl bij gewoon casten van float naar int er getruncate moet worden (gedeelte achter de komma gewoon weglaten). Dus een int i = (int)f; resulteert in een functioncall naar een functie die de rounding mode zet naar truncate, vervolgens converteert, en dan de rounding mode weer op nearest int zet.

Dit is een bekend stukje die de boel al aardig optimaliseert: (bron: Flipcode code of the day entry) (MSVC++ only)
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// By JCAB (COTD flipcode.com 5-2-2001)
inline __declspec(naked) void __cdecl _ftol()
{
    const static int zpfp[2] = { 0xBEFFFFFF, 0x3EFFFFFF };

    __asm {
        SUB     ESP,4
        FST     DWORD PTR [ESP]
        MOV     EAX,DWORD PTR [ESP]
        SHR     EAX,29
        AND     EAX,4
        FADD    DWORD PTR [zpfp+EAX]
        FISTP   DWORD PTR [ESP]
        POP     EAX
        RET
    }
}

benchmark:
code:
1
2
Original = 10805 ms
New =  3916 ms

de optimalisatie is hier duidelijk, ipv de modus te zetten wordt gewoon gebruik gemaakt van de nearest int methode, maar om het toch de karakteristieken van truncate te geven wordt er 0.5 bij opgeteld dan wel afgetrokken als ie kleiner dan wel groter dan 0 is.

Yossarian King (Electronic Arts Canada) beschrijft in Game Programming Gems II een methode die gebruik maakt van bitlevel hacking. Daarbij wordt slechts 1 floating point addition gebruikt, en 1 integer subtraction:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
typedef union int_float_u
{
    float f;
    int i;
} int_float_t;

int main ()
{
    float f = 123.456f;  // de float die je wilt converteren

    int_float_t n, bias;

    bias.i = (23 + 127) << 23;
    n.f = f + bias.f;
    n.i -= bias.i;   // i is nu (int)f

    cout << "int (" << f << ") = " << n.i;

    return 0;
}

Dit stukje code brengt de 60 cycles van de originele conversie terug naar 5, maw, 12x zo snel
deze methode werkt echter alleen met positieve floats. Voor negatieve moet je een bias.i van ((23 + 127) << 23) + (1 << 22) gebruiken

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 09-09 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

aangezien ik me toch verveel ga ik ook maar even de uitleg typen :)

een float wordt opgeslagen als 32 bits. 1 bit voor de sign, 8 bits voor de exponent en 23 bits voor de mantissa:
code:
1
2
3
4
5
6
bit:  31  30     23  22             0
     [S ][E7     E0][M22              M0]

S = sign
E = exponent
M = mantissa

de getallen worden gerepresentateerd in de vorm mantissa * 2exp, waarbij de mantissa een getal tussen 1 en 2 is en de exponent een geheel getal.

Omdat de exponent zowel positief als negatief kan zijn is ervoor gekozen om het op te slaan als 127 + exponent. Een E van 127 betekent dus 0 en 126 is -1

De mantissa ligt altijd tussen 1 en 2. Omdat het onzin is om die 1 ook op te slaan, wordt alleen het gedeelte achter de komma maar opgeslagen in M. Een mantissa van 1.5 wordt dus opgeslagen als 0x400000 (de totale grootte van de mantissa is 23 bits, oftewel 0x800000 verschillende waardes. 0.5 ligt dan natuurlijk op de helft van 0x800000, vandaar de 0x400000)

En de sign bit is om aan te geven of het positief of negatief is; als ie geset is dan is het getal negatief.

Wat het trucje doet is zorgen dat de integer waarde gewoon in de mantissa komt te staan. Dit kun je doen door 1 * 223 bij het getal op te tellen, zodat het getal de waarde krijgt:
1.[integer waarde] * 223. (Dit was dus stap 1 van de truc, namelijk n.f += bias.f)

Nu is het gewoon een simpele kwestie van de mantissabits uitlezen. De schrijver van het stukje doet dat door de bits van de bias van de waarde af te trekken. Aangezien de exponenten van beide getallen hetzelfde zijn, levert dit dus precies de mantissa op. Het lijkt mij dat je het ook gewoon kunt and'en met 0x7fffff, dus alle mantissa bits, zodat je alleen de mantissa overhoudt. Waarschijnlijk kiest ie voor aftrekken omdat dat minder bytes aan code oplevert (scheelt maar 2 of 3 bytes ofzo :P)

Het nadeel van dit trucje is dat je apart rekening moet gaan houden met negatieve getallen, maar het grootste nadeel is nog wel dat je maar maximaal 23 bits integers uit de floats kan halen... meer kan er tenslotte niet in de mantissa

Ik hoop dat dit verhaaltje een beetje duidelijk was, ik ben meestal nogal slecht in uitleggen :)
(en dan ga ik nu :z)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 09-09 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

nou lag ik vannacht in bed en toen realiseerde ik me ineens dat ik het stukje over negatieve getallen was vergeten :)

voor negatieve getallen moet je er 1.5 * 222 bij optellen (oftewel: ((23 + 127) << 23) + (1 << 22) in integer vorm). En dan wordt ook gelijk duidelijk waarom er gekozen is voor aftrekken: omdat de msb van de mantissa 1 is en deze van 0 wordt afgetrokken, krijgt de exponent allemaal 1'en door de carry, waardoor het uiteindelijke getal negatief is. Nadeel hiervan is wel dat het getal meer dan -222 moet zijn

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1