2010-01-10 43 views
6

Có triển khai thực hiện trăn thuần túy fractions.Fraction hỗ trợ long s làm tử số và mẫu số không? Thật không may, exponentiation dường như được mã hóa để trả lại một phao (ack !!!), ít nhất nên hỗ trợ bằng cách sử dụng decimal.Decimal.Phân số có độ chính xác thập phân

Nếu không có, tôi cho rằng tôi có thể tạo một bản sao của thư viện và cố gắng thay thế các lần xuất hiện của float() bằng thứ gì đó thích hợp từ Decimal nhưng tôi muốn một cái gì đó đã được thử nghiệm bởi những người khác trước đây.

Dưới đây là một ví dụ mã:

base = Fraction.from_decimal(Decimal(1).exp()) 
a = Fraction(69885L, 53L) 
x = Fraction(9L, 10L) 

print base**(-a*x), type(base**(-a*x)) 

kết quả trong 0.0 <type 'float'> nơi câu trả lời phải là một số thập phân thực sự nhỏ.

Cập nhật: Bây giờ tôi đã có công việc sau đây (giả sử, cho ** b, cả hai đều là phân số, tất nhiên, tôi sẽ cần một hàm khác khi exp_ là phao hoặc chính nó một Thập phân):

def fracpow(base, exp_): 
    base = Decimal(base.numerator)/Decimal(base.denominator) 
    exp_ = Decimal(exp_.numerator)/Decimal(exp_.denominator) 

    return base**exp_ 

cung cấp câu trả lời 4.08569925773896097019795484811E-516.

Tôi vẫn muốn quan tâm nếu có cách tốt hơn để làm điều này mà không có các chức năng bổ sung (tôi đoán nếu tôi làm việc với lớp Fraction đủ, tôi sẽ tìm các phao khác đang hoạt động theo cách của mình).

+0

Khi tôi phân số. (11,17) ** 2 Tôi nhận được phân số.Fraction (121, 289). Bạn được những gì? –

+0

thử loại (phân số.Fraction (11,17) ** 2.1) – Noah

+0

IMO, hành vi bạn thấy là chính xác, mặc dù không phải những gì bạn muốn.Kể từ khi số mũ là một phao, nó là hợp lý mà mọi thứ được chuyển đổi để nổi. Bây giờ, nếu số mũ là Phân số (21,10), điều đó sẽ thú vị hơn ... –

Trả lời

6

"Nâng lên một sức mạnh" không phải là một hoạt động khép kín trong rationals (khác với bốn phép tính số học thông thường): không có số hợp lý rr == 2 ** 0.5. Truyền thuyết kể rằng Pythagoras (từ định lý của nó thực tế này chỉ đơn giản là sau) đã có đệ tử của ông Hippasus giết chết cho tội ác khủng khiếp chứng minh điều này; có vẻ như bạn thông cảm với phản ứng bị cáo buộc của Pythagoras ;-), với việc sử dụng kỳ lạ của bạn là "nên".

Phân số của Python có nghĩa là chính xác, vì vậy chắc chắn có trường hợp trong đó tăng một phần đến sức mạnh của phân đoạn khác sẽ là hoàn toàn không thể trả về một phần nhỏ như kết quả của nó; và "nên" chỉ có thể không được áp dụng một cách hợp lý cho một phép toán không thể.

Vì vậy, tốt nhất bạn có thể làm là để gần đúng kết quả mong muốn của bạn, ví dụ: bằng cách nhận được một kết quả không phải là một phần chính xác (phao thường được coi là đủ cho mục đích) và sau đó tiếp tục xấp xỉ nó trở lại với một phần nhỏ. Hầu hết các triển khai thực hiện thuần-Python hiện có (có nhiềurationals.py các tệp được tìm thấy quanh mạng ;-) không thích thực hiện toán tử **, nhưng tất nhiên không có gì ngăn cản bạn đưa ra quyết định thiết kế khác trong triển khai của riêng bạn!)

+0

Đây là khóa học chính xác về mặt toán học, nhưng lý do tôi sử dụng lớp Phân số là vì tôi muốn độ chính xác cao, và tôi đang cố gắng cập nhật mã người khác đã viết thư viện clnum. Kể từ khi Fraction hạnh phúc để mất một thời gian như một tử số hoặc mẫu số, nó có vẻ chỉ công bằng mà nó sẽ có thể trả về một số thập phân khi lũy thừa. Bây giờ, nếu tôi chỉ có thể tìm ra nếu fracpow (0,0) nên được định nghĩa là 1, hoặc nếu đó là một lỗi trong mã! – Noah

+1

@Noah, không thể thực sự giúp bạn với mã Python thuần túy ở đây, vì những công việc như vậy tôi luôn sử dụng 'gmpy', tất nhiên; nhưng gmpy.mpq không cho phép gốc không chính xác với số mũ phân số hoặc (_my_ quyết định thiết kế trong trường hợp này), vì vậy tôi sẽ đi qua phao có độ chính xác cao (gmpy.mpf trong trường hợp của tôi) giống như bạn đang làm với Decimal (đó là phao quá, chỉ thập phân chứ không phải là nhị phân, với SW thay vì HW triển khai, và với độ chính xác có thể cài đặt cao như mong muốn - gmpy.mpf là tương tự, nhưng nhị phân chứ không phải là số thập phân). –

+0

Lỗi từ xấp xỉ số điểm của bạn sẽ thường lớn hơn sau đó lỗi từ xấp xỉ kết quả xấp xỉ với một phao. –

0

Bạn có thể viết hàm "pow" của riêng bạn cho các phân số không sử dụng lũy ​​thừa dấu chấm động. Đó có phải là những gì bạn đang cố gắng làm không?

Điều này sẽ tăng một phần nhỏ lên một số nguyên có khả năng quay trở lại thả nổi.

def pow(fract, exp): 
    if exp == 0: 
     return fract 
    elif exp % 2 == 0: 
     t = pow(fract, exp//2) 
     return t*t 
    else: 
     return fract*pos(fract, exp-1) 
+0

Hmmm, tốt hơn có trường hợp _some_ cơ sở để chấm dứt đệ quy cuối cùng! -) –

Các vấn đề liên quan