我正在使用 Julia,但我确信解决方案将主要翻译成不同的语言。
我想以
Float64
精度计算以下表达式 $T$ 的正值。
a
是正常数。平方根内的表达式应始终为正,但随着 T
接近零,由于数值精度问题,结果偶尔会出现负数。
julia> α=1/4.0; map( T -> ( 4 * exp(-α * T) - 3 - exp( -2α * T ) + 2α * T ), 10.0.^(-10:0) )
11-element Vector{Float64}:
-4.137018548132909e-18
-4.137018546840439e-17
3.038735495922355e-17
-2.512379594116203e-16
4.113329634720811e-17
1.8928899382176026e-16
1.0552627836227929e-14
1.041483522687403e-11
1.0397158019953556e-8
1.022361261644733e-5
0.00867247257298609
使用
BigFloat
s计算时不会出现相同的问题(对于相同的值)。
julia> α=BigFloat(1/4.0); map( T -> ( 4 * exp(-α * T) - 3 - exp( -2α * T ) + 2α * T ), 10.0.^(-10:0) )
11-element Vector{BigFloat}:
1.041666666647135530517511139334179132983501942809441564565600382453160881163658e-32
1.041666666471354361319426381902535606415006422809427598976663299435084708258933e-29
1.041666664713541734328314928659467024540737963331449636847040682408936614887116e-26
1.041666647135417166709396893449432138811473447225776037995767356684771923939405e-23
1.041666471354189311710850303868877685043857627660615702953528423064833434922657e-20
1.04166471354394556609940068924547895770393434711169898595204995967864381931136e-17
1.041647135644529365261489400892467181239989440055364005317784883808499181692089e-14
1.041471376951090709983860760560291162481306334994613272150860749219930444115473e-11
1.039715818279496102769801850953898783936741961589734116598630369857383947507474e-08
1.022361261666541821235659358423414459600515733306470783618814653113646037198644e-05
0.008672472572986049376881532922102135745171026217378941282377306337925928800328869
有没有什么方法可以修改这个计算以提高精度并在仍然使用
Float64
s的同时防止这个问题?
使用
4*z - 3 - z^2 = (3-z)*(z-1)
和使用
e^(-aT)-1 = expm1(-aT)
以完全相对精度计算该因子为
-aT*(1+O(aT))
.