• News

• Industries

• Learning & Support

• Community

• Marketplace

# Floating point precision

Hello,

I have a CPP project and a ue4 CPP project

I’m doing a bunch of calculations and when i call

``````
sin(4141414414141414.0f)

``````

I get a different value from each

UE4 - SIN: 0.899859
CPP - SIN: 0.899861

Probably a daft question I’m just wondering why?
They are both using math.h from what I can see they are both running on the same machine.

I’m not very good with CPP so I’m just wondering if someone can tell me why this might be happening and if its possible to make the two match?

FMath::Sin uses sinf, not sin. In UE4 Are you calling FMath::Sin or just sin?

Hi, thanks for the response,

I’m using just sin,

When I click on the method sin in both projects it opens up cmath which then uses sinf()
However when I click on that methods the UE4 project opens up math.h and the CPP project opens up correct_math.h

Not sure if any of that helps.

Further investigation I have found a “magic number”

929887887991829

If anything large than that number is added to the sin function it starts to give out different numbers the native CPP project

this sin(929887887991829) in both projects produce

UE4 - SIN: 0.958895
CPP - SIN: 0.958895

However

sin(929887887991830)

produces the following

UE4 - SIN: 0.322073
CPP - SIN: 0.322072

I assume there is some limit or rounding or something on UE4?

Shouldn’t you be using doubles for numbers that obviously can’t be accurately represented by a single precision float?

Sorry, I don’t understand what you mean.

seedCalc is a double

``````

float X = 2450;
float Y = 2440;
float Z = -30;

double a = (pow(10, 9) + pow(10, 5) + 10);
double seedCalc = 5 * a + X * pow(10, 6) + Y * pow(10, 2) + Z;

``````

seedCalc give out

7450744010.000000 UE4

7450744020.000000 CPP

Ok, in your first post you had an ‘f’ suffix for the number so I assumed you’re using floats.
Also I don’t see ‘sin’ anywhere so it’s obviously not related to that.
Could be that you are compiling with different floating point precision options than UE4 is.

From UE4 Build tool source:

``````
if (Target.WindowsPlatform.Compiler == WindowsCompiler.Intel || Target.WindowsPlatform.Compiler == WindowsCompiler.Clang)
{
// FMath::Sqrt calls get inlined and when reciprical is taken, turned into an rsqrtss instruction,
// which is *too* imprecise for, e.g., TestVectorNormalize_Sqrt in UnrealMathTest.cpp
// TODO: Observed in clang 7.0, presumably the same in Intel C++ Compiler?
}
else
{
// Relaxes floating point precision semantics to allow more optimization.
}

``````

Sorry, this is one of many different function im using and many of these math functions sin cos pow thery all produce different results in UE4 than CPP.

Which /fp flag are you building your c++ program with?

Morning,

``````
Precise(/fp:precise)

``````

It is definitely something to do with large numbers being passed into sin everything is the same until I pass Val into the sin function, then all hell breaks loose

UE4
X: 2450.000000, Y: 2440.000000, Z: -40.000000, pow(10, 6) = 1000000.000000, pow(10, 2) = 100.000000
Density: 0.157030
Star amount: 12 GG: 7450744010.000000 A: 1000100010.000000
Val: 100000007450744016.000000
ValSin: 0.393407
ValFloor: 3934.000000
StellaCharacteristicsSeed: 0.074625

CPP
X: 2450.000000, Y: 2440.000000, Z: -40.000000, pow(10, 6) = 1000000.000000, pow(10, 2) = 100.000000
Density: 0.157030
Star amount: 12 GG: 7450744010.000000 A: 1000100010.000000
Val: 100000007450744016.000000
ValSin: 0.393289
ValFloor: 3932.000000
StellaCharacteristicsSeed: 0.890989

``````
double a = (pow(10, 9) + pow(10, 5) + 10);
double gg = 5 * a + X * pow(10, 6) + Y * pow(10, 2) + Z;

Seed *seed = new Seed(gg, false);

int StarAmount = (int)round(78 * Density * (1 + 2.2 * (pow(seed->GetValue() - 0.5, 3))));

double Val = gg + pow(10, 17);

for (auto i = 1; i < StarAmount; i++) {
FStar* Star = new FStar();
Seed *StellaCharacteristicsSeed = new Seed(t * i, true);
double s = StellaCharacteristicsSeed->GetValue();

UE_LOG(LogTemp, Warning, TEXT("StellaCharacteristicsSeed: %f
"), s);
}

``````
``````

Seed::Seed(double value, bool debug)
{
this->value = value;
this->debug = debug;
}

float Seed::GetValue() {
if (debug) {
UE_LOG(LogTemp, Warning, TEXT("Val: %f"), this->value);
UE_LOG(LogTemp, Warning, TEXT("ValSin: %f"), sin(this->value));
UE_LOG(LogTemp, Warning, TEXT("ValFloor: %f"), floor(sin(this->value) * 10000));
}
this->value = sin(this->value) * 10000;
return this->value - floor(this->value);
}

``````

Try /fp:fast

Same issue when I switched.

I have moved on further now, I have lowered the values so they fall within the allowed scope this has resulted in the correct behaviour between both applications

With the exception of the log function

``````
double rad = min(0.08 - 0.43912 * log(1 - StellaCharacteristicsSeed), 12.0);
}

``````

Star ID 2b2c144ecb05ee720af871bb2af50822.
Star lum: 0.121248
StellaCharacteristicsSeed: 0.785080
log(1 - StellaCharacteristicsSeed)=: -1.537487

``````