溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

python調(diào)用dll出現(xiàn)精度問題怎么辦

發(fā)布時(shí)間:2023-02-25 14:53:18 來源:億速云 閱讀:106 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“python調(diào)用dll出現(xiàn)精度問題怎么辦”的相關(guān)知識(shí),小編通過實(shí)際案例向大家展示操作過程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“python調(diào)用dll出現(xiàn)精度問題怎么辦”文章能幫助大家解決問題。

遇到的問題具體情況

dll 生成函數(shù)代碼聲明如下

extern __declspec(dllexport) void LinearCompute(GoFloat64 currentX, GoFloat64 currentY, GoFloat64 targetX, GoFloat64 targetY, GoFloat64* resultX, GoFloat64* resultY);

使用python調(diào)用代碼

from ctypes import *

# c_double 聲明c 雙精度小數(shù)變量
result_x = c_double(0)
result_y = c_double(0)

x_c = 1400.
y_c = 1450.
x_t = 1500.
y_t = 5600.

# byref 調(diào)用指針
dll.LinearCompute(c_double(x_c), c_double(y_c), c_double(x_t), c_double(y_t), byref(result_x), byref(result_y))

print(result_x.value, '  ', result_y.value)

但是輸出的內(nèi)容顯示,輸入到函數(shù)中的 x_c ,y_c 等數(shù)據(jù)對(duì)不上。

python調(diào)用dll出現(xiàn)精度問題怎么辦

這里需要使用 decimal 庫進(jìn)行精度方面轉(zhuǎn)換

所以以上代碼改為如下:

from ctypes import *
from decimal import *

result_x = c_double(0)
result_y = c_double(0)

x_c = Decimal(1400)
y_c = Decimal(1450)

x_t = Decimal(1500)
y_t = Decimal(5600)

dll.LinearCompute(c_double(x_c), c_double(y_c), c_double(x_t), c_double(y_t), byref(result_x), byref(result_y))

print(result_x.value, '  ', result_y.value)

然后運(yùn)行的結(jié)果如下

python調(diào)用dll出現(xiàn)精度問題怎么辦

可以看見 傳入的數(shù)值變得正常了。

Decimal類型的優(yōu)點(diǎn)

Decimal類型是在浮點(diǎn)類型的基礎(chǔ)上設(shè)計(jì)的,但是它在幾個(gè)地方上要優(yōu)于floating point:

  • Decimal類型可以非常精確地在計(jì)算機(jī)中存儲(chǔ),而學(xué)過c++的都知道,浮點(diǎn)型在計(jì)算機(jī)中是無法精確存儲(chǔ)的,比如1.1和2.2在計(jì)算機(jī)中存儲(chǔ)后,運(yùn)算(1.1+2.2)表達(dá)式的值結(jié)果會(huì)是3.3000000000000003;Decimal類型則不會(huì)出現(xiàn)這種情況。同樣,由于無法精確存儲(chǔ),浮點(diǎn)型也就無法精確計(jì)算(相對(duì)于Decimal類型),可以再測(cè)試(0.1+0.1+0.1-0.3)兩種類型的計(jì)算結(jié)果。

  • Decimal類型會(huì)自動(dòng)保留小數(shù)點(diǎn)后面不需要的0,以與輸入的精度相匹配,比如下面小程序中的例子:浮點(diǎn)型的1.20+1.30結(jié)果是2.5;而Decimal類型結(jié)果是2.50,這樣貌似比較人性化。

  • Decimal類型可以根據(jù)需要自己設(shè)置小數(shù)點(diǎn)后精度。通過getcontext().prec = x (x為你想要的精度來設(shè)置,getcontext()函數(shù)下面再詳細(xì)介紹)。

  • Decimal類型有很強(qiáng)的管理功能,它能夠根據(jù)需要設(shè)置,來控制輸出的格式,得到或者忽略某類錯(cuò)誤(如除0,可以設(shè)置忽略它,而得到一個(gè)Infinity的Decimal值)。

比較重要的一點(diǎn),如果使用 decimal 轉(zhuǎn)換小數(shù)時(shí),需要使用 單引號(hào) 引起來。

from decimal import *

print(Decimal(1.1) + Decimal(3.3))
print(Decimal(1.1) - Decimal(3.3))
print(Decimal(1.1) * Decimal(3.3))
print(Decimal(1.1) / Decimal(3.3))

#輸出結(jié)果
'''
4.399999999999999911182158030
-2.199999999999999733546474090
3.630000000000000097699626167
0.3333333333333333781908292778
'''

python調(diào)用dll出現(xiàn)精度問題怎么辦

但是如果使用字符串,就可以得到正常的結(jié)果了。

關(guān)于“python調(diào)用dll出現(xiàn)精度問題怎么辦”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI