Tải bản đầy đủ - 0 (trang)
Chapter 9. Floating-Point Math in C++

Chapter 9. Floating-Point Math in C++

Tải bản đầy đủ - 0trang

Previouschaptersmentionedthatfloating-pointnumbersare

numbersthatcontainafractionalpart.However,thatisonlythe

mostbasicdefinitionoffloating-pointnumbers.Youmustknow

howC++implementsfloating-pointnumberstousethemwell

andtoavoidtheproblemsyoucanhavewiththem.

Thischapterprovidesafairlydetailedoverviewoffloating-point

numbersinC++.Itdemonstratestheirusebyshowingyouhow

todorealistic(butsurprisinglysimple)physicswithfloatingpointnumbers.



GettingintotheGutsofFloating-PointNumbers

Bydefinition,floating-pointnumbershavefractionalparts.

Whenaprogramstoresafloating-pointnumberinavariable,it

actuallystorestwopiecesofinformation;thesignificantdigits

andtheexponent.

Thesignificantdigitsinafloating-pointnumberarethedigitsof

thenumberthatmostsignificantlyaffectitsvalue.Forexample,

thenumberinFigure9.1containsalotofdigits.However,not

allofthemaresignificant.



Figure9.1.Thesignificantdigitsofafloatingpointnumber.



AsFigure9.1indicates,theleftmostsevendigitsofthefloatingpointnumberarethemostsignificant.Anythingtotherightof

thosedigitsdoesn'taffectthevalueofthenumbermuch.This

canleadtobothimportantadvantagesandimportantproblems.

I'lltalkaboutwhyinjustafewmoments.



Note

Sevensignificantdigitsistypicalonmostpersonal

computers.



AsIalreadymentioned,floating-pointnumbersstorethemost

significantdigitsandanexponent.Figure9.2illustrateshow

programswouldstorethenumberinFigure9.1.



Figure9.2.Themostsignificantdigitsandan

exponent.



Whenyoumultiplyanumberbyapowerof10,youmovethe

decimalpoint.Multiplyinganynumberby104movesthe

decimalpointrightfourplaces.Asaresult,thenumber

1.234567x104isthesameas12345.67.

IfwetaketheleftmostsevendigitsofthenumberinFigure9.1

asthemostsignificant,then12345.67isapproximatelythe

sameas12345.678901234567890123456789.Thedifferenceis

small.Tomakethingseasyforthecomputer,thedecimalpoint

isalwaysassumedtobeaftertheleftmostdigit,asshownin

Figure9.2.Toputintothecorrectplace,youmultiplyitbya

powerof10.InthecaseofFigure9.2,thenumbermustbe

multipliedby104togetthedecimalpointintothecorrectspot.

Sowhenacomputerstoresafloating-pointnumber,itstores

thesignificantdigits,inthiscase1.234567,andtheexponent,

whichis104inthisexample.



Okay,Ilied.



Note

Multiplyingbyanegativepowerof10movesthe

decimalpointtotheleft.



Thereisoneoptimizationthatthecomputermakeswhenit

storesfloating-pointnumbers.Ifbothweandthecomputer

knowthatwe'realwaysstoringthesignificantdigitsanda

powerof10,thenwereallydon'tneedtostorethe10.Instead,

thecomputercanjuststoretheexponentorpowerthatthe10

israisedto.InthecaseofFigure9.2,thecomputerwouldn't

store104;itwouldjuststorethe4.Inreality,it'sthe4that's

theexponent,andthe10isjustassumed.That'swhywesay

thatthecomputerstoresthemostsignificantdigitsandan

exponent.Figure9.3showswhatreallygetsstoredina

floating-pointvariable.



Figure9.3.Thetruthaboutfloating-point

numbers.



WhenthecomputerusesthenumberinFigure9.3,it

understandswhatthesignificantdigitsareforanditknowsthat



theexponentisapowerof10.Italsounderstandsthatinorder

tousethefloating-pointnumber,itmustraise10bythe

exponentandthenmultiplytheresultbythesignificantdigits.

Itdoesallofthisautomaticallyforyouwheneveryouuse

floating-pointnumbers.

YoumaybewonderingwhyyouhavetounderstandhowC++

implementsfloating-pointnumbers.Theansweristhatthis

knowledgeisnecessarytoavoidpotentialproblemsthatcan

cropupwhenusingfloating-pointnumbers.Tofindoutwhat

theyare,keepreading.



Note

OfcourseI'musingthewordsunderstandsand

knowsintheprecedingparagraphfiguratively.

Computers,inspiteofwhatweseeinthemovies,

areincapableofunderstandingorknowinganything.



Floating-PointNumbersandPrecisionErrors

Ifcomputersdon'tstorefloating-pointnumbersexactly,there's

apotentialproblem.Let'sgobacktothenumber

12345.678901234567890123456789.Ifyoudeclareavariable

oftypefloatinyourprogram,theprogramstores

12345.678901234567890123456789as1.234567and4.It

throwsawayallbutthesevenmostsignificantdigits.Whatif

youneedthosedigitsforyourcalculationtobecorrect?

Thistypeofproblemiscalledaprecisionerror.It'spossiblefor

floating-pointvariablestolacktheprecisionneededtoperform

thecalculationcorrectly.Inotherwords,it'spossiblethatthe



digitsarenotsignificanttothecomputerbutarevery

significanttoyou.

Precisionerrorscanalsooccurifthesignificantdigitsaretoofar

apart.Takethenumber900000.00000012.Ifyourgamestores

thatnumberinavariableoftypefloat,itwillcontain9.0and5.

That's9.0x105.The.00000012gotthrownaway.

Howcanyoufixprecisionerrors?

Theansweristhatyoucanuseabiggerdatatype.For

example,onmostpersonalcomputers,thefloatdatatype

currentlycontainsaboutsevensignificantdigits.Ifyouneed

moresignificantdigits,thenyoucanuseadoubleinstead.The

C++specificationstatesthatadoubleisnoshorterthanafloat.

Usually,itisimplementedastwicethenumberofbitsasafloat.

Ifso,avariableoftypedoublecontainsabout15significant

digits.Idoubtyou'lleverneedanythingmoreprecisethanthat

foryourgames.



Warning

Usingalargerdatatypemeansthatyourprogram

performscalculationsmoreslowlyandusesmore

memory.However,inmostinstances,youwill

probablynotbeabletonoticethedifference.



Floating-PointNumbersandRoundingErrors

Ifyoudivide2.0/3.0,whichisafloating-pointcalculation,what

doyouget?



YouandIknowtheansweris0.66666666666666,withthe6's

repeatinginfinitely.However,computersdon'thaveawayof

storinganinfinitenumberof6's.Whenthecomputerhasto

representaninfinitenumberoffloating-pointdigitsinafixed

amountofmemory,itrounds.Asaresult,0.66666666666666

becomes0.6666667.

Dependingonthecalculationsyourgameisdoing,roundingcan

causeerrors.Thisisparticularlytruewhenyourgameis

simulatingadvancedphysics,asmany3Dgamesdothesedays.

Thefixforroundingerrorsisthesameasthefixforprecision

errors.Youusealargerdatatype.Theprogramstillrounds

whenithasto.However,usingalargerdatatype,suchas

double,meansagreaternumberofdigitsinthenumbers.

Therefore,yourresultsaremoreaccurateeveniftheyarestill

rounded.







CaseStudy:Floating-PointNumbersand

Gamespaces

It'stimetoseefloating-pointnumbersinaction.Toseehow

theywork,you'lldoacasestudythatsimulatesthefiringofa

cannon.Thissimulationismorelikerealgamesthanthe

exampleprogramsshownsofarbecauseitusesfloating-point

numbersforallofitscalculations.Theobjectsinthesimulation

willalsobepositionedusingfloating-pointnumbers.

Asyou'vealreadyseen,computerscreensuseintegersrather

thanfloating-pointnumbers.Soifallofthesimulation's

calculationsandobjectpositionsareinfloating-pointnumbers,

howdoyouconnectthattointegerlocationsonthescreen?

Theansweristhatyouuseagamespace.



WhatisaGamespace?

Agamespaceisavirtualworldthatallofagame'sobjectsexist

in.Thegamespacecanbeanysize.Itcanuseanyunitof

measure.So,forinstance,programmerswholiketheEnglish

systemcanuseinches,feet,yards,andmiles.Programmers

whopreferthemetricsystemcandefinetheirgamespaces

usingcentimeters,meters,andkilometers.

Inrealgames,gamespacesarealmostalwaysdefinedusing

floating-pointnumbers.Thisenablesthemtodomuchmore

accurateandrealisticphysicscalculations.Inthecasestudyof

thecannon,theprogrammustperformcalculationsthat

simulatethemovementofacannonball.Ifitweretouseonly

integers,itwouldprobablynotlookveryrealisticbecauseof

inaccuraciesinthephysicscalculations.Instead,thecannon

simulationcreatesagamespacethatusesvectorscontaining



floating-pointnumbers.Thisenablesmoreaccuratecalculations

thanintegervectors.

Whenyourgameusesagamespace,itmustconvertthe

locationsofobjectsfromfloating-pointgamecoordinatesinto

integerscreencoordinates.ThisisillustratedinFigure9.4.



Figure9.4.Thegamespaceontheleftcontains

thegame'sobjects.Theimagesoftheobjectsare

drawninthescreenspaceattheright.



Figure9.4showsthatthegamespaceforthecannonsimulation

is10,560feet(2miles)wide.Thescreenresolutionissetso

thatthescreenis800pixelswide.Thepositionofthe

cannonballthat'sinflightisdefinedinthegamespacewith

floating-pointnumbers.Thesameistrueofthecannon's

position.Duringeachframe,thepositionofthecannonand

cannonballmustbeconvertedtointegerscreencoordinatesso

thatthecannonandtheballcanberenderedatthecorrect



locationsonthescreen.



Factoid

Anothercommonnameforgamecoordinatesis

worldcoordinatesbecausethegamespacecanbe

calledaworld.



Toconvertfromgamespacecoordinatestoscreenspace

coordinates,youusetheformulasshowninFigure9.5.



Figure9.5.Convertingcoordinatesfromthe

gamespacetothescreenspace.



IntheequationsinFigure9.5,thetermxSSstandsforthex

valueinthescreenspace.ThetermxGSisthexvalueinthe

gamespace.Likewise,ySSandyGSrepresenttheyvaluesin

thescreenspaceandthegamespace,respectively.

AsthefirstequationinFigure9.5shows,youconvertxvalues

inthegamespacetoscreenspacebydividingthewidthofthe

screeninpixelsbythewidthofthegamespace.Inourcannon

example,theheightofthegamespaceisinfeet(10,560.0feet

tobeexact).Next,youmultiplytheresultbythexcoordinate



inthegamespace.

Similarly,youconvertyvaluesinthegamespacetoscreen

spacebydividingtheheightofthescreeninpixelsbythewidth

ofthegamespace.Inthecannonexample,thewidthofthe

gamespaceis7920.0feet.Youmultiplytheresultofthedivision

bytheyvalueinthegamespace.



Tip

I'vedefinedthegamespaceforthecannonsimulator

inEnglishunits(feet).However,ifyou'reserious

aboutgameprogramming,Istronglyencourageyou

tobecomefamiliarwiththemetricsystemifyou're

notalready.You'llfindthatalmostallphysics

calculationsareeasierusingthemetricsystem.



Convertingfromscreenspacecoordinatestogamespace

coordinatesusestheformulainFigure9.6.



Figure9.6.Convertingcoordinatesfromthe

screenspacetothegamespace.



AswiththeequationinFigure9.5,thetermySSinFigure9.6



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 9. Floating-Point Math in C++

Tải bản đầy đủ ngay(0 tr)

×