﻿ 64-bit programs and floating-point calculations

64-bit programs and floating-point calculations

Andrey Karpov
Articles: 316

A developer who is porting his Windows-application to the 64-bit platform sent a letter to our support service with a question about using floating-point calculations. By his permission we publish the answer to this question in the blog since this topic might be interesting for other developers as well.

The text of the letter

I want to ask you one particular question concerning 32 -> 64 bits migration. I studied articles and materials on your site and was very astonished at the discrepancy between 32-bit and 64-bit code I had encountered.


float fConst = 1.4318620f; 

MSVC 32, SSE and SSE2 are disabled

/fp:precise: fValue1 = 40.016743, fValue2 = 40.016747

MSVC 64, SSE and SSE2 are disabled

/fp:precise: fValue1 = 40.016743, fValue2 = 40.016743


Does your product detect anything related to this issue? Could you please tip me in what way 32/64 can impact the results of real arithmetic?

Our answer

The Viva64 product does not detect such variations in a program's behavior after it's recompilation for the 64-bit system. Such changes cannot be called errors. Let's study this situation in detail.

Simple explanation



When compiling in 64-bit mode, the compiler generates the same correct code whose result is the same "a bit larger than 40.01674" value. In this case, it is always 40.016743. But it does not matter. Within the limits of float type's accuracy we get the same result as in the 32-bit program.


Stricter explanation



In our case, we handle not 1 but values 40.016743 and 40.016747. Let's take the largest of these two and multiple it by FLT_EPSILON. The result number will be the accuracy value for our calculations:

Epsilon = 40.016743*FLT_EPSILON = 40.016743*0.0000001192092896 = 0,0000047703675051357728

Let's see how much different numbers 40.016747 and 40.016743 are:

Delta = 40.016747 - 40.016743 = 0.000004


Delta < Epsilon

0.000004 < 0,00000477


What to do?


In this case the result will be the following:

MSVC x86:

/fp:strict: fValue1 = 40.016747, fValue2 = 40.016747

MSVC x86-64:

/fp:strict: fValue1 = 40.016743, fValue2 = 40.016743





It seems that the reason lies in using different sets of instructions. In 64-bit mode, these are SSE2 instructions which are always used nowadays and which are implemented in all the processors of the AMD64 (Intel 64) family. By the way, because of this, the phrase in your question "MSVC 64, SSE and SSE2 are disabled" is incorrect. SSE2 are used by the 64-bit compiler anyway.


Use PVS-Studio to search for bugs in C, C++ and C# code


goto PVS-Studio;

Andrey Karpov
Articles: 316

Do you make errors in the code?

Check your code
with PVS-Studio

Static code analysis
for C, C++ and C#

goto PVS-Studio;