Procedure.s DetermineSign(a.s, b.s, operation.s) Protected signA = 1 Protected signB = 1 ; Определяем знаки чисел If Left(a, 1) = "-" signA = -1 a = Right(a, Len(a) - 1) EndIf If Left(b, 1) = "-" signB = -1 b = Right(b, Len(b) - 1) EndIf ; Определяем знак результата в зависимости от операции Select operation Case "+" If signA = signB ProcedureReturn Str(signA) Else If signA = 1 ProcedureReturn "subtract" Else ProcedureReturn "subtract_reverse" EndIf EndIf Case "-" If signA = signB If signA = 1 ProcedureReturn "subtract" Else ProcedureReturn "subtract_reverse" EndIf Else ProcedureReturn Str(signA) EndIf Case "*" ProcedureReturn Str(signA * signB) Case "/" ProcedureReturn Str(signA * signB) EndSelect EndProcedure Procedure.s String(char.s, count) Protected result.s = "" For i = 1 To count result + char Next ProcedureReturn result EndProcedure Declare.s AddLongNumbers(a.s,b.s) Procedure.s SubtractLongNumbers(a.s, b.s) Protected signResult.s = DetermineSign(a, b, "-") ; Убираем знаки из чисел If Left(a, 1) = "-" a = Right(a, Len(a) - 1) EndIf If Left(b, 1) = "-" b = Right(b, Len(b) - 1) EndIf ; Если знак результата требует сложения If signResult = "1" Or signResult = "-1" ProcedureReturn AddLongNumbers(a, b) EndIf ; Выполняем вычитание Protected borrow = 0 Protected result.s = "" Protected i, diff, digitA, digitB ; Выравниваем числа по десятичной точке Protected aPoint = FindString(a, ".", 1) Protected bPoint = FindString(b, ".", 1) If aPoint = 0 a + ".0" aPoint = Len(a) - 1 EndIf If bPoint = 0 b + ".0" bPoint = Len(b) - 1 EndIf ; Выравниваем дробные части While Len(a) - aPoint < Len(b) - bPoint a + "0" Wend While Len(b) - bPoint < Len(a) - aPoint b + "0" Wend ; Выравниваем целые части While aPoint < bPoint a = "0" + a aPoint + 1 Wend While bPoint < aPoint b = "0" + b bPoint + 1 Wend ; Вычитаем цифры справа налево For i = Len(a) To 1 Step -1 If Mid(a, i, 1) = "." result = "." + result Continue EndIf digitA = Val(Mid(a, i, 1)) - borrow digitB = Val(Mid(b, i, 1)) If digitA < digitB digitA + 10 borrow = 1 Else borrow = 0 EndIf diff = digitA - digitB result = Str(diff) + result Next ; Убираем ведущие нули While Left(result, 1) = "0" And Len(result) > 1 And Mid(result, 2, 1) <> "." result = Right(result, Len(result) - 1) Wend ; Добавляем знак результата If signResult = "-1" result = "-" + result EndIf ProcedureReturn result EndProcedure Procedure.s AddLongNumbers(a.s, b.s) Protected signResult.s = DetermineSign(a, b, "+") ; Убираем знаки из чисел If Left(a, 1) = "-" a = Right(a, Len(a) - 1) EndIf If Left(b, 1) = "-" b = Right(b, Len(b) - 1) EndIf ; Если знак результата требует вычитания If signResult = "subtract" ProcedureReturn SubtractLongNumbers(a, b) ElseIf signResult = "subtract_reverse" ProcedureReturn SubtractLongNumbers(b, a) EndIf ; Выполняем сложение Protected carry = 0 Protected result.s = "" Protected i, j, sum, digitA, digitB ; Выравниваем числа по десятичной точке Protected aPoint = FindString(a, ".", 1) Protected bPoint = FindString(b, ".", 1) If aPoint = 0 a + ".0" aPoint = Len(a) - 1 EndIf If bPoint = 0 b + ".0" bPoint = Len(b) - 1 EndIf ; Выравниваем дробные части While Len(a) - aPoint < Len(b) - bPoint a + "0" Wend While Len(b) - bPoint < Len(a) - aPoint b + "0" Wend ; Выравниваем целые части While aPoint < bPoint a = "0" + a aPoint + 1 Wend While bPoint < aPoint b = "0" + b bPoint + 1 Wend ; Складываем цифры справа налево For i = Len(a) To 1 Step -1 If Mid(a, i, 1) = "." result = "." + result Continue EndIf digitA = Val(Mid(a, i, 1)) digitB = Val(Mid(b, i, 1)) sum = digitA + digitB + carry carry = sum / 10 result = Str(sum % 10) + result Next If carry > 0 result = Str(carry) + result EndIf ; Добавляем знак результата If signResult = "-1" result = "-" + result EndIf ProcedureReturn result EndProcedure Procedure.s MultiplyLongNumbers(a.s, b.s) Protected signResult.s = DetermineSign(a, b, "*") ; Убираем знаки из чисел If Left(a, 1) = "-" a = Right(a, Len(a) - 1) EndIf If Left(b, 1) = "-" b = Right(b, Len(b) - 1) EndIf ; Убираем десятичные точки и запоминаем количество знаков после точки Protected aPoint = FindString(a, ".", 1) Protected bPoint = FindString(b, ".", 1) If aPoint > 0 a = RemoveString(a, ".") aDecimalPlaces = Len(a) - aPoint + 1 Else aDecimalPlaces = 0 EndIf If bPoint > 0 b = RemoveString(b, ".") bDecimalPlaces = Len(b) - bPoint + 1 Else bDecimalPlaces = 0 EndIf ; Умножаем числа как целые Protected result.s = "0" Protected i, j, carry, product Protected temp.s For i = Len(b) To 1 Step -1 carry = 0 temp = "" For j = Len(a) To 1 Step -1 product = Val(Mid(a, j, 1)) * Val(Mid(b, i, 1)) + carry carry = product / 10 temp = Str(product % 10) + temp Next If carry > 0 temp = Str(carry) + temp EndIf ; Сдвигаем результат влево на соответствующее количество разрядов temp + String("0", Len(b) - i) result = AddLongNumbers(result, temp) Next ; Вставляем десятичную точку Protected totalDecimalPlaces = aDecimalPlaces + bDecimalPlaces If totalDecimalPlaces > 0 ; Если количество десятичных разрядов больше длины результата, добавляем ведущие нули If totalDecimalPlaces > Len(result) result = String("0", totalDecimalPlaces - Len(result)) + result EndIf ; Вставляем точку result = Left(result, Len(result) - totalDecimalPlaces) + "." + Right(result, totalDecimalPlaces) EndIf ; Убираем ведущие нули While Left(result, 1) = "0" And Len(result) > 1 And Mid(result, 2, 1) <> "." result = Right(result, Len(result) - 1) Wend ; Убираем лишние нули после точки If FindString(result, ".", 1) > 0 While Right(result, 1) = "0" result = Left(result, Len(result) - 1) Wend If Right(result, 1) = "." result = Left(result, Len(result) - 1) EndIf EndIf ; Добавляем знак результата If signResult = "-1" result = "-" + result EndIf ProcedureReturn result EndProcedure a.s = "123.456" b.s = "78.98765" Debug "Произведение: " + MultiplyLongNumbers(a, b) Debug ValD(a)*ValD(b)
Чё-то я где-то тут не допираю - умножает нормально но точка в числе стоит не там, как исправить?