Though Each language has sufficient datatypes yet for certain situation we need
more mathematical datatypes,I made an attempt to create division algorithm for
integer which does not rely on rounding end digits or truncating.
The limitation of algorithm is due to inherent behavior of python datatype to
round fraction especially in case float & inability of Decimal to extract
required fractions natively.
Code:
from decimal import Decimal, getcontext
decimalDivident: int = 918
decimalDivisor: int = 139
# decimalDivident: int = 22
# decimalDivisor: int = 7
counter:int = 0;
print(f"Dividing:'{decimalDivident}' by '{decimalDivisor}'")
class RecurringDecimal:
def __init__(self, decimalValue: str, repeatStart: int, repeatEnd: int,stringValue:float):
self.decimalValue = decimalValue # String representation of the decimal
self.stringValue = stringValue # String representation of the decimal
self.repeatStart = repeatStart # Index where repeating part starts
self.repeatEnd = repeatEnd # Index where repeating part ends
def __repr__(self):
return f"RecurringDecimal(decimal='{self.decimal_value}', repeat_start={self.repeat_start}, repeat_end={self.repeat_end})"
def getDivision(divisor: int,divident:int,requiredDecimalFraction:int) -> RecurringDecimal:
division:int = 0
decimalDivision=0.0
remainder:int = 0
repeateEndIndex:int=-1
immediateDivision:int = 0
fractionPosition:int=-1
noOfDecimalAfterFraction:int=0
noOfDigitsInDivision:int=0
noOfDigitsAfterDecimal:int=0
repeateStartIndex:int=-1
reminderList:list=[]
enhancedDouble:RecurringDecimal
try:
print(f"*requiredDecimalFraction:'{requiredDecimalFraction}'")
while noOfDecimalAfterFraction < requiredDecimalFraction:
remainder = divident % divisor
immediateDivision = divident // divisor
if not remainder in reminderList:
reminderList.append(remainder)
elif remainder in reminderList and repeateStartIndex == -1:
repeateStartIndex = reminderList.index(remainder)
repeateEndIndex = len(reminderList) - repeateStartIndex -1
if(immediateDivision > 0):
division = division * 10 + immediateDivision
else:
division = division * 10
# print(f"*division:'{division}'")
divident = remainder
# print(f"#Before Inner While Loop:")
# print(f"#remainder:'{remainder}'")
# print(f"#divisor:'{divisor}'")
#print(f"In Inner While Loop:")
while remainder < divisor:
noOfDigitsAfterDecimal +=1
remainder = remainder * 10
divident = remainder
if fractionPosition == -1:
fractionPosition = len(str(division))
# print(f"##remainder:'{remainder}'")
# print(f"##divisor:'{divisor}'")
# print(f"##divident:'{divident}'")
if fractionPosition != -1:
noOfDecimalAfterFraction = noOfDecimalAfterFraction + 1
# print(f"**After Inner While Loop:")
if requiredDecimalFraction == noOfDecimalAfterFraction:
# print(f"--->No Of Decimal After Fraction'{noOfDecimalAfterFraction}'")
# print(f"--->Required Fractions Received")
break
if remainder ==0:
# print(f"--->Reminder Become Zero'")
break
# print(f"$$$$ division:'{division}'")
noOfDigitsInDivision = len(str(division))
# print(f"$$$$ fractionPosition:'{fractionPosition}'")
# print(f"$$$$ noOfDigitsInDivision:'{noOfDigitsInDivision}'")
if fractionPosition != -1:
decimalDivision =division / (10 ** (noOfDigitsInDivision - fractionPosition))
num_str = str(Decimal(decimalDivision).normalize())
decimal_part = num_str.split(".")[1] if "." in num_str else ""
print("%%% decimal_part:='{decimal_part}'")
if repeateEndIndex > 0:
stringDivision = num_str.split(".")[0] + "." + decimal_part[:repeateStartIndex + repeateEndIndex+1].ljust(repeateStartIndex + repeateEndIndex+1, '0')
else:
stringDivision = num_str.split(".")[0] + "." + decimal_part[:requiredDecimalFraction].ljust(requiredDecimalFraction, '0')
enhancedDouble=RecurringDecimal(decimalDivision,repeateStartIndex,repeateEndIndex,stringDivision)
print(f"$$$$ noOfDigitsAfterDecimal='{noOfDigitsAfterDecimal-1}' immediateDivision='{immediateDivision}'")
print(f"$$$$ repeateStartIndex='{repeateStartIndex}' repeateEndIndex='{repeateEndIndex}'")
return enhancedDouble
except ZeroDivisionError as e:
print("Error:", e)
raise ZeroDivisionError("Division by zero is not allowed.")
enhancedDouble:RecurringDecimal = getDivision(decimalDivisor,decimalDivident,22)
print(f"Division Result:'{enhancedDouble.decimalValue}',Recurring Start Point:'{enhancedDouble.repeatStart}' Recurring End Point:'{enhancedDouble.repeatEnd}' String Value '{enhancedDouble.stringValue}'")
No comments:
Post a Comment