Share via

VBA CDec Function Conversion Question

Anonymous
2019-10-21T16:41:35+00:00

A question to the group:

Working on a macro that utilizes a double-word to store difference configurations via binary settings.  After some time I realized that using the Double data type produced rounding issues even though no decimal places are used.  I then attempted to use the Variant-type with a Decimal subtype but the CDec function is returning crazy values that I cannot figure out.  Can someone provide some insight to the first step of my function that simply takes a constant value of 255, converts it to decimal, and then shifts the 8-bits into the high-byte:

Const conRELMacAppEnu As Byte = 255

Dim varRELAudMsgSvc As Variant

varRELAudMsgSvc = CDec(conRELMacAppEnu) * 2 ^ 56

This will return a value of 18374686479671614500 which I believe is not 255 x 2^56.  I understand that decimal subtypes are 12-byte numbers but I have no use of the high-word.

Any help is greatly appreciated!

-----James

Microsoft 365 and Office | Excel | For home | Windows

Locked Question. This question was migrated from the Microsoft Support Community. You can vote on whether it's helpful, but you can't add comments or replies or follow the question.

0 comments No comments

Answer accepted by question author

Anonymous
2019-10-21T17:54:06+00:00

James:

Can someone provide some insight to the first step of my function

First, the exponential operator (^) always returns type Double.  To confirm, note that the following displays Double:

MsgBox TypeName(CDec(2) ^ CDec(56))

Type Double can represent 2^56 accurately with no loss of precision (72057594037927936).

(Type Double can represent any power of 2 up to 2^1023 accurately with no loss of precision.)

And CDec(255) * CDec("72057594037927936") is exactly 18374686479671623680, the accurate result with no loss of precision.

However, CDec(255) * CDec(2^56) is 18374686479671614500 (!).

I believe the reason is:  CDec(double) first formats the type Double expression, which is limited to 15 significant digits.

Note that Format(2^56,"0") is 72057594037927900.  And CDec(255) * CDec("72057594037927900") is indeed 18374686479671614500.

The largest power of 2 that can be formatted accurately with 15 significant digits (or less) is 2^49 (562949953421312).

So you could write CDec(255) * 2^49 * 2^7, but not CDec(255) * 2^50 * 2^6.

Or you could simply write:

Sub doit()

Const conRELMacAppEnu As Byte = 255

Dim varRELAudMsgSvc As Variant, varShift56 As Variant

varShift56 = CDec("72057594037927936")

varRELAudMsgSvc = conRELMacAppEnu * varShift56

MsgBox varRELAudMsgSvc

End Sub

Was this answer helpful?

1 person found this answer helpful.
0 comments No comments

Answer accepted by question author

Anonymous
2019-10-21T17:10:45+00:00

Hi.  In general, the power function "^" is not decimal compliant.  2^56 is too high.

If you want to use "^", the last example is something I would do. (but not recommended)

Sub Demo()

Dim K As Variant

Dim d1 As Variant

Const conRELMacAppEnu As Byte = 255

Dim varRELAudMsgSvc As Variant

K = 2 ^ 28

d1 = CDec(1)

varRELAudMsgSvc = CDec(conRELMacAppEnu)

Debug.Print "Wrong"

Debug.Print varRELAudMsgSvc * 2 ^ 56

Debug.Print "Correct"

Debug.Print varRELAudMsgSvc * K * K

Debug.Print "Also correct, but not recommended"

Debug.Print (2 ^ 8 - d1) * 2 ^ 28 * 2 ^ 28

End Sub

Returns:

Wrong

 18374686479671614500 

Correct

 18374686479671623680 

Also correct

 18374686479671623680

Was this answer helpful?

1 person found this answer helpful.
0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Anonymous
    2019-10-21T18:04:52+00:00

    Joeu: Thanks so much for the technical clarification...that is also what I am in need of was an intricate understanding of what is going on in the background...you explanation clears alot of questions up for me!  I sincerely appreciate all the help!!!   -----James

    Was this answer helpful?

    0 comments No comments
  2. Anonymous
    2019-10-21T18:02:28+00:00

    Dana, thank you for your fast response and the clarification as to what is going on...I had read somewhere where mathematical calculations on large-precision numbers can get a bit crazy when using various functions...I appreciate the help!!!!   -----James

    Was this answer helpful?

    0 comments No comments