Страница 4 из 4 ПерваяПервая ... 234
Показано с 31 по 39 из 39

Тема: Целочисленные в формате u32 и u64

  1. #31
    Пользователь
    Регистрация
    27.11.2011
    Адрес
    Краснодар
    Сообщений
    12,991

    По умолчанию

    EFrol дальше в математику ПР это все пихните. когда отрицательное число будет -2 100 999 например
    Речь же не всегда об отображении.

  2. #32

    По умолчанию

    Понятно, что будут сложности, но они ведь решаемы!!

    Цитата Сообщение от Валенок Посмотреть сообщение
    Прочитать - можно. Только обрабатывать - творчески.
    Давайте добавим макросы для работы c s32, u64, s64 и даже с double float.
    Можем же ведь?!
    Последний раз редактировалось EFrol; 18.10.2024 в 10:49.

  3. #33
    Пользователь
    Регистрация
    27.11.2011
    Адрес
    Краснодар
    Сообщений
    12,991

    По умолчанию

    EFrol дело не в "можем ведь" а в том, что это начнет отжирать ресурсы ПР и увеличивать время цикла. Зачем насильничать над ПР?

  4. #34

    По умолчанию

    Цитата Сообщение от melky Посмотреть сообщение
    EFrol дело не в "можем ведь" а в том, что это начнет отжирать ресурсы ПР и увеличивать время цикла. Зачем насильничать над ПР?
    Ну это пусть каждый решает сам для себя.
    Я, например, перехожу на Arduino. Мне как-то всё равно.
    Последний раз редактировалось EFrol; 18.10.2024 в 13:14.

  5. #35

    По умолчанию

    Цитата Сообщение от EFrol Посмотреть сообщение
    Понятно, что будут сложности, но они ведь решаемы!!
    Давайте добавим макросы для работы c s32, u64, s64 и даже с double float.
    Можем же ведь?!
    Для S32 уже всё обсудили и выложили, только в этой теме уже 2 раза ссылку давал.
    Про 64 бита сделали только сложение, до умножения так и не дошло. Ссылку давал FPavel в начале.
    Последний раз редактировалось kondor3000; 18.10.2024 в 13:50.

  6. #36

    По умолчанию

    Опять я, наверно, не те макросы использую?!
    Код:
    function_block u64_MUL
    
        var_input
            x1H, x1L : udint;
            x2H, x2L : udint;
        end_var
    
        var_output
           qH, qL : udint;
        end_var
        
        var
           cnt : udint;
        end_var
    
        qH := 0; qL := 0;
        
        for cnt := 0 to 63 do
            if x2L.0 then
                qL := qL + x1L;
                qH := qH + x1H;
                if (qL < x1L) then qH := qH + 1; end_if
            end_if
            x2L := shr(x2L, 1); x2L.31 := x2H.0; x2H := shr(x2H, 1);
            x1H := shl(x1H, 1); x1H.0 := x1L.31; x1L := shl(x1L, 1);
        end_for
    
    end_function_block
    Код:
    function_block u64_DIV
    
        var_input
           x1h, x1l : udint;    // Делимое
           x2h, x2l : udint;    // Делитель
        end_var
    
        var_output
           QH, QL : udint;      // Частное
           MH, ML : udint;      // Остаток
        end_var
    
        var
           cnt : udint; 
        end_var
    
        if x2h = 0 and x2l = 0 then return; end_if
    
        cnt := 1; QH := 0; QL := 0;
        
        while x2h < 2147483648 do
            x2h := shl(x2h, 1);
            if x2l > 2147483647 then x2h := x2h + 1; end_if
            x2l := shl(x2l, 1); cnt := cnt + 1;
        end_while
        
        while cnt > 0 do
            QH := shl(QH, 1);
            if QL > 2147483647 then QH := QH + 1; end_if
            QL := shl(QL, 1);
    
            if x1h > x2h then
                x1h := x1h - x2h; QL := QL + 1;
                if x1l >= x2L then
                    x1l := x1l - x2l;
                else
                    x1l := x2l - x1l; x1l := 0 - x1l;
                    x1h := x1h - 1;
                end_if
            elsif x1h = x2h then 
                if x1l >= x2l then
                    x1h := 0; x1l := x1l - x2l; QL := QL + 1;
                end_if
            end_if
    
            x2l := shr(x2l, 1);
            if x2h > shl(shr(x2h, 1), 1) then x2l := x2l + 2147483648; end_if
            x2h := shr(x2h, 1);
    
            cnt := cnt - 1;
        end_while
        MH := x1h; ML := x1l;
    
    end_function_block
    Последний раз редактировалось EFrol; 19.10.2024 в 07:57.

  7. #37

    По умолчанию

    Это всё конечно хорошо, но почему никто не смотрит, какие числа надо перемножать и складывать ?
    число 2 в 32 и в 48 спепени перемножить с числом в 3 и 4 регистре, а потом всё сложить.
    То есть умножить надо 2 раза 16 битное на 64 битное, а потом всё сложить. Сложение нужно 1 число 32 битное + 2 числа 64 битных.
    2 регистр можно посчитать просто умножением в Лоджике 65535*65536=4294901760 .

    Еще раз, что надо посчитать, вот скрин Вложение 74299

    1 регистр 0x2200
    младшая часть — значение оставляем «как есть» (может быть до 65535)
    2 регистр 0x2201
    значение умножаем на 2^16 (может быть до 4294901760)
    3 регистр 0x2202
    значение умножаем на 2^32 (сейчас 0, а будет число до 5 знаков, например 65535 * 4294967296=281470681743360 )
    4 регистр 0x2203
    значение умножаем на 2^48 (сейчас 0, а будет число до 5 знаков, например 65535 * 281474976710656=18446462598732840960 )

    65535+4294901760+281470681743360+18446462598732840 960=18446744073709551615 - максимально возможное 20-значное число
    умноженное на 0.00001=184467440737095.51615
    Деление делать не надо, просто откинуть 5 последних знаков.
    Последний раз редактировалось kondor3000; 18.10.2024 в 19:32.

  8. #38

    По умолчанию

    kondor3000, Вы несколько запутались в формате принимаемого числа.

    В том РЭ приведён пример, как из 4-х принятых регистров составить 64-разрядное число.
    На самом деле при приёме ничего умножать не нужно - для подобного, обычно, пользуются или сдвигами или приведением типа результата к массиву слов (или рассыпухе из 4 слов).
    Если бы дело происходило в CODESYS 3.5, можно было бы поступить следующими способами (забыл только обозначение там 64-разрядного типа, пусть будет u64)
    Код:
    type TConvert:
    union
      My64: u64;
      x0, x1, x2, x3: uint;
      a: array [0..3] of uint;
    end_union
    end_type
    
    v: TConvert;  // промежуточная переменная
    r0, r1, r2, r3: uint; //регистры из Modbus
    v64: u64; // это и есть итоговая переменная
    
    // заполним её регистрами при помощи вспомогательной переменной
    v.x0 := r0; v.x1 := r1; v.x2 := r2; v.x3 := r3;
    v64 := v.My64;
    
    // можно аналогично через массив
    x.a[0] := r0; // ....... и так далее
    v64 := v.My64;
    
    // можно через сдвиги
    v64 := r0 + shl(r1, 16) + shl(r2, 32) + shl(r3, 48);
    
    // можно через умножение
    v64 := r0 + r1 * 65536 + r2 * ........ // не помню дальше константы, но смысл понятен
    А EFrol приводит макросы арифметических операций над уже полученными 64-разрядными числами, он "уже их принял" и ведёт дальнейшую обработку - считает деньги по тарифу
    Последний раз редактировалось FPavel; 18.10.2024 в 21:25.

  9. #39

    По умолчанию

    Да, открывал, видел, но при наборе примера не стал забивать голову константами - именно эти константы вместе с умножением - исключительно бумажный пример без практического применения, т.к. сдвиг всегда быстрее умножения, а прямое размещение данных сразу в нужном месте (привет, union!) - ещё быстрее.

Страница 4 из 4 ПерваяПервая ... 234

Похожие темы

  1. Как присвоить различные целочисленные значения для одной переменной?
    от Пётр Поросёнков в разделе Среда программирования OWEN Logic
    Ответов: 8
    Последнее сообщение: 24.02.2024, 18:58
  2. ПМ 01 не отправлет смс в формате PDU
    от djmadmax в разделе Эксплуатация
    Ответов: 18
    Последнее сообщение: 01.12.2016, 11:34
  3. Системное время в формате DATE
    от Columbariy в разделе ПЛК1хх
    Ответов: 2
    Последнее сообщение: 10.10.2014, 23:54
  4. Ответов: 10
    Последнее сообщение: 01.10.2014, 15:47
  5. Передавать архивы файлов в формате csv
    от IDN в разделе ПЛК3xx (архив)
    Ответов: 5
    Последнее сообщение: 16.05.2014, 10:33

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •