2015-10-01 5 views
1

Я работаю над электронной таблицей, которая выполняет вычисления на очень малых числах порядка 1E-14. У меня был проект моего процесса, который использует электронную таблицу и не хранит данные в переменных VBA. Мне не нравится этот подход и я хочу взять весь процесс за кулисами в VBA.Точность вычисления электронных таблиц Excel, отличных от Excel VBA Calculation

Что я замечаю, я не могу подобрать два подхода. Те же операции разные результаты. Я работаю с Excel 2013

An example in a cell 
=B42*COS(2*PI()*E$41*A42) 

or if I plug in values taking all figures reported i get the following 
0.156434465*Cos(2*3.14159265358979*0.012*0.05) 

this results in 
1.56433353400222E-01 

Если бы я сделать то же самое в VBA

gsum = Round(data(i + 1, 1), 10) * Cos(2 * pi * Freq * i * dt) 

or 
0.156434465*Cos(2*3.14159265358979*0.012*1*0.05) 
i get a different answer 
Watch:Round(data(i + 1, 1), 10) * Cos(2 * Pi * Freq * i * dt):  
0.156433353359992 : Variant/Double : Calculation.realFT 

Я не знаю, как бороться с этим. Как-то я теряю каждый раз. Все на стороне VBA объявлено типа double, за исключением I.

Любые идеи о том, как я могу получить VBA, чтобы соответствовать точности электронных таблиц?

Я знаю, что различия небольшие, но я делаю много операций, и они складываются. Также я ограничен Excel для приложения.

UPDATE

Так что я смотрел на это еще немного, и я сузил, что проблема на этап muliplication между выходом косинуса и значением ячейки. В обоих версиях Excel и Excel VBA я могу видеть, что они оба одинаково, но я застрял со следующим

In Excel 
0.999992893893247000000*0.156434465= 1.56433353400222E-01 

In Excel VBA 
0.999992893893247000000*0.156434465= 1.56433353359991861557855E-01 

, кто прав?

+0

Возможно, что косинус Excel лучше, чем у VBA. VBA является старым (без изменений с конца 1990-х годов), но сам Excel постоянно обновляется. Возможно, также проблема с 32-го и 64-разрядным версиями. –

+0

@JohnColeman Хм, кажется, VBA не позволит мне использовать функцию листа ala WorksheetFunction.Cos. Во всяком случае, вокруг этого? – TheCodeNovice

+0

I * думаю * это 'Application.Evaluate (" 0.156434465 * Cos (2 * 3.14159265358979 * 0.012 * 1 * 0.05) ")' будет использовать cos() вместо Excel(). Но - в моем случае (Excel 2010) я не могу обнаружить разницу между оценкой выражения VBA и Excel - они оба возвращают 0,156433353359992. Чарльз Уильямс - гуру, когда дело доходит до высокоточного Excel VBA. Вам может понравиться его блог: https://fastexcel.wordpress.com/. Это также круто: https://newtonexcelbach.wordpress.com/ –

ответ

1

Несколько предложений

Изменение типа переменной с двойной валюты или десятичной (вариант), или строку

Double: 8 байт

-1.79769313486232e+308 to -4.94065645841247E-324 for negative values 
4.94065645841247E-324 to 1.79769313486232e+308 for positive values 

Валюта: 8 байт

-922,337,203,685,477.5808 to 922,337,203,685,477.5807

десятичные: 12 байт (объявлен как Variant, а затем использовать функцию преобразования CDec)

+/- 79,228,162,514,264,337,593,543,950,335 if no decimal is use 
+/- 7.9228162514264337593543950335 (28 decimal places) 

быть осведомлены о том, как извлекать данные из диапазонов для VBA:

Public Sub showData() 
    Const NL As String = vbCrLf & vbCrLf & vbTab 
    Const FR As String = "0.156434465 * Cos(2 * 3.14159265358979 * 0.012 * 0.05)" 

    Dim v1 As Variant, v2 As Variant, v3 As Variant, v4 As Variant, v5 As Variant 

    v1 = CDec((1/3) + (1/3) + (1.00059999999977E-03)) 
    v2 = CDec(CDec(1/3) + CDec(1/3) + CDec(1.00059999999977E-03)) 
    v3 = 0.156434465 * Cos(2 * 3.14159265358979 * 0.012 * 0.05) 
    v4 = CDec(0.156434465 * Cos(2 * 3.14159265358979 * 0.012 * 0.05)) 
    v5 = CDec(CDec(0.156434465) * CDec(Cos(CDec(2 * 3.14159265358979 * 0.012 * 0.05)))) 

    With ActiveSheet.Cells(1, 1) 
     MsgBox "Formula: " & vbTab & .Formula & NL & _ 
       "Text: " & vbTab & .Text & NL & _ 
       "Value: " & vbTab & .Value & NL & _ 
       "Value2: " & vbTab & .Value2 & vbCrLf & NL & _ 
       "VBA 1: " & vbTab & v1 & NL & _ 
       "VBA 2: " & vbTab & v2 & vbCrLf & vbCrLf & vbCrLf & _ 
       "Formula: " & vbTab & FR & NL & _ 
       "VBA 3: " & vbTab & v3 & NL & _ 
       "VBA 4: " & vbTab & v4 & NL & _ 
       "VBA 5: " & vbTab & v5, , "Precision" 
    End With 
End Sub 

Precision


Number precision:15 digits

Largest allowed positive number:1.79769313486231E+308

Largest allowed negative number:-1E-307

Smallest allowed negative number:-2.2251E-308

Smallest allowed positive number:2.229E-308


Более подробную информацию о различиях между .text .Value и .Value2 в this link

Убедитесь, что вы используете .Value2 ("сырые" данные), если вы не не работает с датами или валютой

Ссылка на статью MS «Floating-point arithmetic may give inaccurate results in Excel»

+0

Новый тип данных добавляет больше sigfigs, но все еще выключен. Возможно ли, что таблица неверна или способ, которым Excel выполняет математику, отличается от двух. – TheCodeNovice

+0

. Вы можете найти [Арифметику с плавающей точкой] (https://support.microsoft.com/en-us/kb/78113). –