2015-08-28 1 views
-3

Я пытался разобраться в следующей подпрограмме, но не можешь показаться, чтобы получить это право:Сложность в понимании FORtran arthimetic

subroutine press(ptes,Re,densm,void,svel,vis,dhyd,ht,p) 
a=1.30 
p=a*Re**(-1.63)*svel**2*ht/dhyd/void/densm/1000. 
p=p*ptes 
return 
end 

Я следовал за информацию об арифметическом старшинстве упомянутого here, но не могут похоже, получают эквивалентную функцию C# (показано ниже), чтобы выплюнуть аналогичный вывод.

public static void calculatePressureDrop(
    float pressure_drop_coeff, 
    float re, 
    float density_massecuite, 
    float voidage, 
    float superficial_mass_velocity, 
    float viscosity, 
    float hydraulic_diameter, 
    float height_of_section, 
    ref float pressure_drop) 
{ 
    float sel_exp_val = (float)(2 * height_of_section/hydraulic_diameter/voidage/density_massecuite/1000.0); 
    float sel_exp = (float)Math.Pow(superficial_mass_velocity, sel_exp_val); 
    float sel_exp_prod = -1.63F * sel_exp; 
    float re_exp = (float)Math.Pow(re, sel_exp_prod); 
    pressure_drop = (float)1.30 * re_exp; 
    pressure_drop = pressure_drop * pressure_drop_coeff; 
} 

UPDATE: это код в моем тестовом примере, который держит неудачу

[TestMethod] 
    public void TestPressureDropMethodV2() // Uses call by ref 
    { 
     float pressure_drop_coeff = 1.20000005F; 
     float re = 0.000365345448F; 
     float density_massecuite = 1460; 
     float voidage = 0.757799625F; 
     float superficial_mass_velocity = 1.53357923F; 
     float hydraulic_diameter = 0.151121646F; 
     float viscosity = 634.350342F; 
     float height_of_section = 0.0850000009F; 
     float pressure_drop = 0; 
     Finless5Lib.calculatePressureDrop(pressure_drop_coeff, re, density_massecuite, voidage, superficial_mass_velocity, viscosity, hydraulic_diameter, height_of_section,ref pressure_drop); 
     float expectedResult = 0.74733448F; 
     //// Verify the result: 
     Assert.AreEqual(expectedResult, pressure_drop); 
    } 

Когда я напечатал значения от от Fortran, это то, что я получил:

ptes = 1.20000005
Re = 0.000379003613
densm = 1460.
пустота = 0,757799625
СВЭЛ = 1,53357923
визави = 611,490234
dhyd = 0,151121646
ХТ = 0,0850000009
р = 0,703936338

Пожалуйста, помогите! Любые советы будут полезны!

+1

Какие результаты вы получаете от каждого соответствующего бита кода? Возможно ли, что разница связана с ошибками округления (особенно на разделении)? –

+1

Вместо того чтобы проходить в 'pressure_drop' как' ref', почему бы вам просто не вернуть его? – juharr

+0

Разве у вас нет 'Math.Pow (re, -1.63)'? так как ** имеет наивысший приоритет? – juharr

ответ

2

Я уверен, вы хотите этого

public static float calculatePressureDrop(
    float pressure_drop_coeff, 
    float re, 
    float density_massecuite, 
    float voidage, 
    float superficial_mass_velocity, 
    float viscosity, 
    float hydraulic_diameter, 
    float height_of_section) 
{ 
    return pressure_drop_coeff * 1.3F * (float)Math.Pow(re, -1.63) 
      * (float)Math.Pow(superficial_mass_velocity , 2) * height_of_section 
     /hydraulic_diameter/voidage/density_massecuite/1000F; 
} 

Затем вы можете использовать его как

float pressure_drop = calculatePressureDrop(...); 

Ты проблема заключалась в том, что вы не давали самую высокую precidence к операторам электростанций. Также в общем случае лучше избегать параметров ref, если вы можете.

+0

Hi juharr, я раньше старался, но это не сработало. Я также попробовал решение, которое вы дали, но не повезло. :( – rkc88

+0

@ rkc88 Думаю, вам нужно будет использовать пример ввода и вывода для помогите определить, в чем проблема. – juharr

+0

@ rkc88 Только что понял, что у меня было '1.63' вместо' -1.63'. Попробуйте сейчас. – juharr

2

Я не знаю, FORTRAN очень хорошо, но если ** имеет более высокий приоритет, чем *, то:

p=a*(Re**(-1.63))*(svel**2)*ht/dhyd/void/densm/1000

Ваш C#, кажется, делать что-то подобное:

p=a*(Re**((-1.63)*(svel**(2*ht/dhyd/void/densm/1000))))

2

Приоритет операторов (ISO/IEC 1539-1:. 2010 ака Fortran 2008 сл 7.1.3), имеющих отношение к этому выражению является **, * или /, унарный + или -, двоичный + или -.

Фортран выражение

p=a*Re**(-1.63)*svel**2*ht/dhyd/void/densm/1000. 

эквивалентно математическому выражению

p = a * (Re**(-1.63)) * (svel**2) * ht/dhyd/void/densm/1000.0 

в сочетании с другим утверждением (a=1.30 до и p=p*ptes после) дает:

p = 1.30 * (Re**(-1.63)) * (svel**2) * ht/dhyd/void/densm/1000.0 * ptes 

умножения и деления оцениваются влево направо.