Pertanyaan Cara Mengkonversi Pythons Desimal () ketikkan INT dan eksponen


Saya ingin menggunakan tipe data Desimal () dalam python dan mengubahnya menjadi integer dan eksponen sehingga saya dapat mengirim data itu ke mikrokontroler / plc dengan presisi penuh dan kontrol desimal. https://docs.python.org/2/library/decimal.html

Saya telah membuatnya bekerja, tetapi itu adalah hackish; apakah ada yang tahu cara yang lebih baik? Jika tidak jalan apa yang saya ambil untuk menulis tingkat yang lebih rendah "as_int ()" berfungsi sendiri?

Kode contoh:

from decimal import *
d=Decimal('3.14159')
t=d.as_tuple()
if t[0] == 0:
    sign=1
else:
    sign=-1

digits= t[1]
theExponent=t[2]
theInteger=sign * int(''.join(map(str,digits)))

theExponent
theInteger

Bagi mereka yang belum diprogram PLC, alternatif saya untuk ini adalah dengan menggunakan int dan menyatakan titik desimal di kedua sistem atau menggunakan floating point (yang hanya mendukung beberapa PLC) dan bersifat lossy. Jadi Anda dapat melihat mengapa bisa melakukan ini akan luar biasa!

Terima kasih sebelumnya!


9
2017-07-24 22:09


asal


Jawaban:


Anda bisa melakukan ini:

[Ini 3 kali lebih cepat daripada metode lain]

d=Decimal('3.14159')

list_d = str(d).split('.')   
# Converting the decimal to string and splitting it at the decimal point

# If decimal point exists => Negative exponent
# i.e   3.14159 => "3", "14159"
# exponent = -len("14159") = -5
# integer = int("3"+"14159") = 314159

if len(list_d) == 2:
    # Exponent is the negative of length of no of digits after decimal point
    exponent = -len(list_d[1])
    integer = int(list_d[0] + list_d[1])



# If the decimal point does not exist => Positive / Zero exponent
# 3400
# exponent = len("3400") - len("34") = 2
# integer = int("34") = 34

else:
    str_dec = list_d[0].rstrip('0')
    exponent = len(list_d[0]) - len(str_dec)
    integer = int(str_dec)

print integer, exponent

Pengujian kinerja

def to_int_exp(decimal_instance):

    list_d = str(decimal_instance).split('.')

    if len(list_d) == 2:
        # Negative exponent
        exponent = -len(list_d[1])
        integer = int(list_d[0] + list_d[1])

    else:
        str_dec = list_d[0].rstrip('0')
        # Positive exponent
        exponent = len(list_d[0]) - len(str_dec)
        integer = int(str_dec)

    return integer, exponent

def to_int_exp1(decimal_instance):
    t=decimal_instance.as_tuple()

    if t[0] == 0:
        sign=1
    else:
        sign=-1

    digits= t[1]

    exponent = t[2]

    integer = sign * int(''.join(map(str,digits)))

    return integer, exponent
Menghitung waktu yang diambil untuk 100.000 loop untuk kedua metode:
ttaken = time.time()
for i in range(100000):
    d = Decimal(random.uniform(-3, +3))
    to_int_exp(d)    
ttaken = time.time() - ttaken
print ttaken

Waktu yang diambil untuk metode string parsing: 1.56606507301

ttaken = time.time()
for i in range(100000):
    d = Decimal(random.uniform(-3, +3))
    to_int_exp1(d)    
ttaken = time.time() - ttaken
print ttaken

Waktu yang diambil untuk konversi ke tuple kemudian ekstrak metode: 4.67159295082


5
2017-07-24 22:48



from functools import reduce   # Only in Python 3, omit this in Python 2.x
from decimal import *

d = Decimal('3.14159')
t = d.as_tuple()

theInteger = reduce(lambda rst, x: rst * 10 + x, t.digits)
theExponent = t.exponent

2
2017-07-24 22:29



Dapatkan eksponen langsung dari tupel seperti Anda:

exponent = d.as_tuple()[2]

Kemudian kalikan dengan kekuatan 10 yang tepat:

i = int(d * Decimal('10')**-exponent)

Menyatukan semuanya:

from decimal import Decimal

_ten = Decimal('10')

def int_exponent(d):
    exponent = d.as_tuple()[2]
    int_part = int(d * (_ten ** -exponent))
    return int_part, exponent

2
2017-07-24 23:02



from decimal import *
d=Decimal('3.14159')
t=d.as_tuple()
digits=t.digits
theInteger=0
for x in range(len(digits)):
   theInteger=theInteger+digits[x]*10**(len(digits)-x)

0
2017-07-24 22:39