Перевод байта в десятичную строку.

Тема в разделе "WASM.A&O", создана пользователем _Juicy, 25 фев 2005.

  1. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    NANO

    ] к чему такая погоня за скоростью в данной ситуации? чем плохо то, что уже созданно?"



    Для упражнения мозгов, чтобы не расслаблялись и салом-пивом не заплывали :)



    Да и не прав ты насчет "x=0 до 120", т.к. к примеру уже 69*13/128 = 7.0078125, т.е. 7 вместо 6. Заполни за 30 сек. табличку в Excel и посмотри числа вблизи 70,80 и т.п.
     
  2. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    NANOТы видел как в винде реализована wsprintf - через одно место (хоть и работают они правильно) но одно преобразование "%u" (вариант NoName) выполняется за 500 тактов на PIII, и вообще все ф-ции так реализованы.



    А деление на 10, мне кажется основа для строковых преобразований, примеров (где это надо делать быстро) можно надумать уйму. Одно деление Mathisen-Fog плюс остаток выполняется около 11 тактов, подходит для x <= 10004h, а если надо для x <= 255h и это можно сделать быстрее, так этож супер. Вот бы все проги были построены на оптимальных алгоритмах, или хотя-бы винда :)
     
  3. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Вот вариант деления на 10 как 13/128 с коррекцией ошибки на 1 (работает до x < 709, т.к. дальше возникают ошибки на 2):
    Код (Text):
    1.     ;--- eax = x ---
    2.     lea edx,[eax+4*eax]
    3.     lea ebx,[edx+8*eax]
    4.     shr ebx,7         ;"частное"
    5.     lea edx,[ebx+4*ebx]
    6.     add edx,edx
    7.     sub eax,edx       ;"остаток"
    8.     ;--- коррекция ---
    9.     cdq               ;edx - знак остатка
    10.     add ebx,edx       ;коррекция частного в ebx
    11.     and edx,26
    12.     add eax,edx       ;коррекция остатка в eax
    Получается покороче, но не быстрее, чем более общий вариант великого оптимизатора А.Фога.
     
  4. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    leo >




    Я имел ввиду что-то вроде этого:
    Код (Text):
    1.     ;преобразуем младшие 4 бита в BCD
    2.     and  al,0Fh  
    3.     sub  al,0Ah
    4.     sbb  edx,edx
    5.     and  dl,0Ah
    6.     inc  dh
    7.     add  dl,al
    На этом участке проблемы вроде не должно возникнуть, поскольку все регистры - партиальные. хотя дальше есть "add eax,edx"...



    >




    Да, это разумно, но, напиример, в моих вариантех и без этого есть что улучшить.

    (я сохранял в eax, что бы потом проверить правильность работы кода)



    >




    Не обязательно сокращать таблицу таким способом. Например, очевидно, что 25% тратится впустую. Если оставшиеся 3 байта dword'а упаковать в 2 (подобно моему последнему варианту), то получится обойтись без сравнения, только сдвиг + and.



    >




    Все эти длинные куски кода имеют тот же недостаток, что и большие таблицы - возможны промахи кэша :-(

    На вскидку, сам этот код не очень-то быстро будет работать (хотя я ничего не тестил)



    Учитывая существующие варианты, мне кажется, что 32 байта таблица оптимальна. Переделать чуток твой вариант, так как там нет всяких daa, которые тормозят на PIV. да и чтение из памяти всего одно.