Vra

Ek het 'n funksie wat byna so sal lyk:

float function(){
    float x = SomeValue;
    return x / SomeOtherValue;
}

Op 'n sekere punt, hierdie funksie oorloop en terug 'n baie groot negatiewe waarde. Om te probeer en hou op presies waar dit gebeur het, het ek bygevoeg 'n cout verklaring sodat die funksie gelyk soos volg:

float function(){
    float x = SomeValue;
    cout << x;
    return x / SomeOtherValue;
}

en dit het gewerk! Natuurlik, ek het die probleem opgelos heeltemal deur die gebruik van 'n dubbel. Maar ek is nuuskierig oor hoekom die funksie behoorlik gewerk toe ek couted dit. Is dit tipies, of kan daar 'n fout wees iewers anders wat ek mis?

(As dit enige hulp, die waarde gestoor in die float is net 'n heelgetal waarde, en nie 'n besonder groot een. Ek het dit net in 'n float na beslissende vermy.)

Was dit nuttig?

Oplossing

Welkom by die wonderlike wêreld van drywende punt. Die antwoord wat jy kry sal waarskynlik afhang van die drywende punt model wat jy die kode saamgestel met.

Dit gebeur as gevolg van die verskil tussen die IEEE spec en die hardeware die kode is wat uitgevoer word op. Jou CPU het waarskynlik 80 bit floating point registers wat ontslae te gebruik om die 32-bis float waarde hou. Dit beteken dat daar veel meer akkuraatheid terwyl die waarde in 'n register bly as wanneer dit word gedwing om 'n geheue adres (ook bekend as 'homing' die register).

As jy die waarde geslaag om die samesteller cout moes die drywende punt om geheue te skryf, en dit lei tot 'n verlore van presisie en interessante gedrag WRT oorloop gevalle.

Sien die MSDN dokumentasie op VC ++ drywende punt skakelaars . Jy kan probeer opstel van met / FP:. Streng en sien wat gebeur

Ander wenke

'n waarde Druk om cout moet nie die waarde van die Parameter verander op enige manier nie.

Maar ek het soortgelyke gedrag gesien, en voeg by die opsporing van state veroorsaak 'n verandering in die waarde. In sulke gevalle, en waarskynlik hierdie een sowel my raaiskoot was dat die bykomende state veroorsaak optimizer die samesteller se anders optree, so te genereer verskillende kode vir jou funksie.

Die toevoeging van die cout verklaring beteken dat die vaue van x direk gebruik word. Sonder dat dit die optimizer die veranderlike kan verwyder, sodat die verandering van die orde van die berekening en dus die verandering van die antwoord.

As 'n eenkant, dit is altyd 'n goeie idee om onveranderlike veranderlikes verklaar met behulp van const:

float function(){
    const float x = SomeValue;
    cout << x;
    return x / SomeOtherValue;
}

Onder andere hierdie sal jy verhoed per ongeluk verby jou veranderlikes te funksioneer dat hulle via nie-const verwysings kan verander.

cout veroorsaak dat 'n verwysing na die veranderlike, wat dikwels veroorsaak dat die opsteller om dit te dwing om dit te mors om die stapel.

Omdat dit 'n float, hierdie waarskynlik veroorsaak die waarde daarvan te kapt van die dubbel of lang dubbel verteenwoordiging dit normaalweg sou hê.

'n funksie (nie-inlined) wat 'n wyser of verwysing na x neem moet uiteindelik veroorsaak dat die dieselfde gedrag, maar as die samesteller later kry slimmer en leer om dit inline, sal jy ewe geskroef Oproep:)

Ek dont dink die cout het geen invloed op die veranderlike, sou die probleem moet iewers anders wees.

scroll top