How can i calc High precision digital (no loss of precision)

Started by 2b2ttianxiu, Jul 11, 2023, 05:48 PM

Previous topic - Next topic

2b2ttianxiu

How can i calc High precision digital (no loss of precision) in squirrel, i need to calc big number, e.x 1000000000000 in 32-bit server, i dont want to change my server bit version, because i compiled my script.

habi

Perhaps by using blob. Then you have to define the operations.
Ref: http://squirrel-lang.org/squirreldoc/stdlib/stdbloblib.html



Samir_HG

local BigNumber = {
    split_number = function(number) {
        local parts = [];
        local str = number.tostring();
        local len = str.len();
        local num_parts = ceil(len / 9.0);
        for (local i = 0; i < num_parts; i++) {
            local start = len - (i + 1) * 9;
            local end = len - i * 9;
            if (start < 0) start = 0;
            parts.append(str.slice(start, end).tointeger());
        }
        return parts;
    },

    add_arrays = function(a, b) {
        local result = [];
        local carry = 0;
        local len_a = a.len();
        local len_b = b.len();
        local max_len = (len_a > len_b) ? len_a : len_b;
        for (local i = 0; i < max_len; i++) {
            local sum = carry;
            if (i < len_a) sum += a[i];
            if (i < len_b) sum += b[i];
            result.append(sum % 1000000000);
            carry = sum / 1000000000;
        }
        if (carry > 0) result.append(carry);
        return result;
    },

    subtract_arrays = function(a, b) {
        local result = [];
        local borrow = 0;
        local len_a = a.len();
        local len_b = b.len();
        for (local i = 0; i < len_a; i++) {
            local diff = a[i] - borrow;
            if (i < len_b) diff -= b[i];
            if (diff < 0) {
                diff += 1000000000;
                borrow = 1;
            } else {
                borrow = 0;
            }
            result.append(diff);
        }
        while (result.len() > 1 && result[result.len() - 1] == 0) result.pop();
        return result;
    },

    multiply_arrays = function(a, b) {
        local result = [];
        local len_a = a.len();
        local len_b = b.len();
        for (local i = 0; i < len_a + len_b; i++) result.append(0);
        for (local i = 0; i < len_a; i++) {
            for (local j = 0; j < len_b; j++) {
                result[i + j] += a[i] * b[j];
                result[i + j + 1] += result[i + j] / 1000000000;
                result[i + j] %= 1000000000;
            }
        }
        while (result.len() > 1 && result[result.len() - 1] == 0) result.pop();
        return result;
    },

    divide_arrays = function(a, b) {
        if (b.len() == 1 && b[0] == 0) {
            print("Error: Division by zero");
            return [];
        }

        if (this.compare_arrays(a, b) < 0) return [0];
        local result = [];
        local remainder = [];

        for (local i = a.len() - 1; i >= 0; i--) {
            remainder.insert(0, a[i]);
            while (remainder.len() > 1 && remainder[remainder.len() - 1] == 0) remainder.pop();
            local digit_quotient = 0;
            while (this.compare_arrays(remainder, b) >= 0) {
                remainder = this.subtract_arrays(remainder, b);
                digit_quotient++;
            }
            result.insert(0, digit_quotient);
        }
        while (result.len() > 1 && result[result.len() - 1] == 0) result.pop();
        return result;
    },

    compare_arrays = function(a, b) {
        local len_a = a.len();
        local len_b = b.len();
        if (len_a < len_b) return -1;
        if (len_a > len_b) return 1;
        for (local i = len_a - 1; i >= 0; i--) {
            if (a[i] < b[i]) return -1;
            if (a[i] > b[i]) return 1;
        }
        return 0;
    },

    print_array = function(a) {
        local str = "";
        for (local i = a.len() - 1; i >= 0; i--) {
            if (i == a.len() - 1) str += a[i].tostring();
            else str += format("%09d", a[i]);
        }
        print(str);
    }
}

Usage:

local a = BigNumber.split_number("100000000000");
local b = BigNumber.split_number("1000000000000");
print("Addition: ");
local sum_result = BigNumber.add_arrays(a, b);
BigNumber.print_array(sum_result); // output "1100000000000"
print("Subtraction: ");
local sub_result = BigNumber.subtract_arrays(b, a);
BigNumber.print_array(sub_result); // output "900000000000"
print("Multiplication: ");
local mul_result = BigNumber.multiply_arrays(a, b);
BigNumber.print_array(mul_result); // output "100000000000000000000000"
print("Division: ");
local div_result = BigNumber.divide_arrays(b, a);
BigNumber.print_array(div_result); // output "10"

Output:


When using a value in these functions, please convert it to a string before