PRB: RFX Unnecessarily Updates Floating Point Fields (163244)
The information in this article applies to:
- The Microsoft Foundation Classes (MFC), when used with:
- Microsoft Visual C++ 1.51
- Microsoft Visual C++ 1.52
- Microsoft Visual C++ 1.52b
- Microsoft Visual C++ 1.52c
- Microsoft Visual C++, 32-bit Enterprise Edition 4.2
- Microsoft Visual C++, 32-bit Enterprise Edition 5.0
- Microsoft Visual C++, 32-bit Enterprise Edition 6.0
- Microsoft Visual C++, 32-bit Professional Edition 2.0
- Microsoft Visual C++, 32-bit Professional Edition 2.1
- Microsoft Visual C++, 32-bit Professional Edition 2.2
- Microsoft Visual C++, 32-bit Professional Edition 4.0
- Microsoft Visual C++, 32-bit Professional Edition 4.1
- Microsoft Visual C++, 32-bit Professional Edition 4.2
- Microsoft Visual C++, 32-bit Professional Edition 5.0
- Microsoft Visual C++, 32-bit Professional Edition 6.0
- Microsoft Visual C++, 32-bit Learning Edition 4.0
- Microsoft Visual C++, 32-bit Learning Edition 4.2
- Microsoft Visual C++, 32-bit Learning Edition 6.0
This article was previously published under Q163244 SYMPTOMS
When you use the Microsoft Foundation Classes (MFC) ODBC database classes
to access tables containing floating point numeric data, you may observe
that some numeric fields are updated unnecessarily. Fields that contain
values that were not modified may be marked as dirty and, as a result, are
unnecessarily updated.
CAUSE
RFX_Double and RFX_Single are the RFX functions that the wizards select to
handle the SQL data types SQL_DOUBLE and SQL_REAL, respectively. Both of
these functions detect when recordset member variable values have changed
and require an update to change the corresponding fields in the actual
database table. The detection of dirty fields is based on caching the
original value of the recordset member variable and comparing it to the
current value of the variable. The comparison that Microsoft Foundation
Classes uses to detect dirty floating point values has always been some
form of exact comparison.
It is generally not recommended that you perform exact comparisons of
floating point values because when store a decimal fraction in binary it is
inherently imprecise. Rounding and truncation can occur when these values
are processed (particularly when the Floating Point Unit (FPU) is invoked)
and can lead two values that were initially exactly equal to eventually be
only nearly equal. It is preferable to either treat a floating point field
as character data that is immune to rounding errors or incorporate a small
offset value into comparisons (known as an epsilon value) to allow nearly
equal values to be considered sufficiently equal.
RFX_Double and RFX_Single do not employ an epsilon value in their dirty
field detection comparisons so they will occasionally mark fields whose
values have undergone some form of rounding or truncation as being dirty.
The process of transferring recordset member variables via DDX to and from
the edit controls of a record view or a dialog box can introduce sufficient
rounding errors to result in a field that is marked dirty. In addition, in
Visual C++ 4.2 Microsoft Foundation Classes has been modified to use the
"==" equality operator when comparing the cached and current values. The
"==" invokes the Floating Point Unit and that, in itself, causes rounding
that may result in the field being flagged dirty when it could actually be
unchanged.
RESOLUTION
There are several ways to address this problem:
Modification Type: | Major | Last Reviewed: | 12/8/2003 |
---|
Keywords: | kbprb KB163244 |
---|
|