VBA: a weird case of inequality

Nelson78

Well-known Member
Joined
Sep 11, 2017
Messages
526
Office Version
  1. 2007
Hello everybody.

I've developped a code with a check at the end.

Seemingly, everything is ok with aaaa = bbbb.

But, as you can see by the highlighted part of the code in debug operation, vba is saying that aaaa is not = to bbbb

https://imgur.com/7nsEQIQ

Why?
 

Excel Facts

Add Bullets to Range
Select range. Press Ctrl+1. On Number tab, choose Custom. Type Alt+7 then space then @ sign (using 7 on numeric keypad)
Floating point error/arithmetic?

What do you see when you print both aaaa and bbbb to the Immediate window?
 
Upvote 0
This is due to anomalies of 64-bit binary floating-point arithmetic.

Excel and VBA format only the first 15 significant decimal digits, but the binary representation has more precision.

In VBA, you can easily see the infinitesimal difference with a statement like:

Debug.Print aaaa - bbbb

Unforatunately, it is not always so easy in Excel. Excel likes to play games that sometimes hides the infinitesimal differences. But Excel is inconsistent.

For example, A1=B1 might return TRUE, and =A1-B1 might return exactly zero (0.00E+00).

But A1-B1=0 returns FALSE, MATCH(A1,B1,0) returns #N/A (not a match), and A1-B1-0 returns the infinitesimal difference. Of course, the redundant -0 should not make a difference; but it does, demonstrating the inconsistency.

These infinitesimal differences arise even when we expect arithmetic to be accurate to a small number of decimal places (e.g. 2). The reason is: most decimal fractions cannot be represented exactly in 64-bit binary floating-point, and the binary representation of a particular decimal fraction varies depending on the magnitude of the number.

In those cases, the work-around is: whenever you expect a calculation to be accurate to some number of decimal places, explicitly round to that number of decimal places. For example, ROUND(A1-B1,2) instead of simply A1-B1.

In your example, you might round to 15 decimal places. For example, Round(aaaa,15). But beware of anomalies of VBA "banker's rounding" (round half to even).

Ordinarily, I would prefer WorksheetFunction.Round(aaaa,15). Unfortunately, Excel ROUND has some defects that come to light when we round to 15 decimal places. But they are relatively rare.
 
Last edited:
Upvote 0
PS....

Excel and VBA format only the first 15 significant decimal digits, but the binary representation has more precision.

Excel numbers and VBA type Double are represented as the sum of 53 consecutive powers of 2. The highest power of 2 is determined by the magnitude of the number.

Always (*) use type Double instead of type Single in VBA, especially when transferring between Excel and VBA.

For VBA-only arithmetic, you might consider using type Currency or type Decimal. Read the help pages to understand their limitations. Type Decimal is not straight-forward to use.

However, most functions and some arithmetic operations convert to type Double. And values are converted to type Double when they are stored in Excel cells.


-----
(*) I use type Single only for arithmetic with values returned by Timer. Nevertheless, I convert to type Double in order to format those values. VBA formats type Single only up to 7 significant decimal digits.
 
Upvote 0
PS....



Excel numbers and VBA type Double are represented as the sum of 53 consecutive powers of 2. The highest power of 2 is determined by the magnitude of the number.

Always (*) use type Double instead of type Single in VBA, especially when transferring between Excel and VBA.

For VBA-only arithmetic, you might consider using type Currency or type Decimal. Read the help pages to understand their limitations. Type Decimal is not straight-forward to use.

However, most functions and some arithmetic operations convert to type Double. And values are converted to type Double when they are stored in Excel cells.


-----
(*) I use type Single only for arithmetic with values returned by Timer. Nevertheless, I convert to type Double in order to format those values. VBA formats type Single only up to 7 significant decimal digits.

Great contribute.
I'm going to study it in an accurate way.

Meanwhile, rounding to the 10th decimal is the key to confirm the equality.

Thank's a lot.
 
Upvote 0

Forum statistics

Threads
1,223,228
Messages
6,170,871
Members
452,363
Latest member
merico17

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top