REAL4 --> строка

Тема в разделе "WASM.BEGINNERS", создана пользователем AssemblerIA64, 4 янв 2008.

  1. AssemblerIA64

    AssemblerIA64 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2007
    Сообщения:
    160
    Посоветуйте, пожалуйста, алгорифм для преобразования короткого вещественного в строку. (У меня есть один, просто хочется сравнить их оптимизированность). Спасибо.
     
  2. 10110111

    10110111 New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2006
    Сообщения:
    319
    Адрес:
    Санкт-Петербург
    1. последовательными делениями на 10
    Код (Text):
    1. ConvertNumberToString:
    2.     __asm
    3.     {
    4.         mov ebx,NumOfSymbols;//EBX is a dot position counter
    5.         lea edx,StrOut+4933 ;//Initialization
    6.         fninit
    7.         fstcw   word ptr CRu    ;//Control word for rounding to nearest number
    8.         fstcw   word ptr CRd
    9.         or  word ptr CRd,0xc00;//Control word for rounding to null
    10.         fld tbyte ptr Number
    11.         ftst            ;//Checking sign
    12.         fstsw   ax
    13.         sahf
    14.         mov Sign,0
    15.         jnc Plus1
    16.         mov Sign,-1
    17.         fabs            ;//Find Abs(Num)
    18. Plus1:
    19.         fild    dword ptr NumOfSymbols
    20.         fldl2t
    21.         fmulp   st(1),st(0)
    22.         fld st(0)
    23.         fldcw   word ptr CRd
    24.         frndint
    25.         fsubr   st(0),st(1)
    26.         f2xm1
    27.         fld1
    28.         faddp   st(1),st(0)
    29.         fscale
    30.         fxch    st(1)
    31.         fstp    st      ;//ST0=10**NumOfSymbols
    32.         fldcw   CRu     ;//Set rounding mode
    33.         fmulp   st(1),st(0) ;//Number*10**NumOfSymbols to use Number Mod 10
    34.         fld st(0)
    35.         fstp    tbyte ptr Number;//Save Number
    36.         frndint
    37.         fld qword ptr _10_
    38.         fxch    st(1)
    39. Cycle:
    40.         fldcw   CRu
    41. FindRem:
    42.         fprem
    43.         fcomi   st(0),st(1)
    44.         jnc FindRem     ;//Get full remainder
    45.         fistp   dword ptr temp
    46.         mov eax,temp    ;//EAX=Current digit or integer indeterminance
    47.         test    eax,eax
    48.         js  Error       ;//EAX contains integer indefinity: Number is not a number or is infinity or denormalized number
    49.         or  al,0x30     ;//Convert digit to ASCII
    50.         dec edx     ;//Decrease position of symbol
    51.         mov byte ptr [edx],al
    52.         fld tbyte ptr Number
    53.         fdiv    st(0),st(1) ;//Get quotient
    54.         fld st(0)
    55.         fstp    tbyte ptr Number;//Save Number
    56.         fldcw   CRd     ;//Set rounding to null
    57.         frndint
    58.         dec ebx     ;//Decrease position
    59.         jnz DoNotPutDot ;//If not zero then dot is not in this position
    60.         dec edx     ;//Else decrease digit position counter
    61.         mov byte ptr [edx],'.';//and put the dot
    62. DoNotPutDot:
    63.         ftst
    64.         fstsw   ax
    65.         sahf
    66.         jnz Cycle       ;//If quotient is non-null, continue cycle
    67.         cmp ebx,0
    68.         jng DotAlreadyPut
    69. PutZeros:
    70.         dec edx     ;//If the dot is not put yet
    71.         mov byte ptr [edx],0x30;//Then fill the rest of positions with zeros
    72.         dec ebx
    73.         jnz PutZeros    ;//Continue the cycle if it isn't time to put dot
    74.         sub edx,2
    75.         mov word ptr [edx],('.'*256+0x30);//Put string "0."
    76. DotAlreadyPut:
    77.         cmp Sign,0
    78.         je  Plus2       ;//If the number is greater than zero, the minus sign is not needed
    79.         dec edx
    80.         mov byte ptr [edx],'-';//If Number<0 the first symbol is '-'
    81. Plus2:
    82.         mov StrAddr,edx ;//Save string address
    2. через BCD-представление. тут можно заюзать MMX+XMM.
    Код (Text):
    1.         jmp ConvertFloatToASCII
    2. Zero:
    3.         mov dword ptr [edi],'0'
    4.         jmp End
    5. ConvertFloatToASCII:
    6.         lea edi,StrOut
    7.         fninit
    8.         fld tbyte ptr [Number]
    9.         ftst
    10.         fstsw   ax
    11.         sahf
    12.         je  Zero
    13.         jnc Plus
    14.         mov [edi],'-'
    15.         add edi,1
    16.         fabs
    17. Plus:
    18.         add edi,1
    19.         fldcw   word ptr [_77F_]
    20.         fldlg2
    21.         fld st(1)
    22.         fyl2x
    23.         frndint
    24.         fld st(0)
    25.         fbstp   tbyte ptr [lgNum]
    26.         fild    [_15_]
    27.         fsubrp  st(1),st(0)
    28.         fldl2t
    29.         fmulp   st(1),st(0)
    30.         fld st(0)
    31.         fldcw   word ptr [_F7F_]
    32.         frndint
    33.         fsubr   st(0),st(1)
    34.         f2xm1
    35.         fld1
    36.         faddp   st(1),st(0)
    37.         fscale
    38.         fstp    st(1)
    39.         fldcw   word ptr [_37F_]
    40.         fmulp   st(1),st(0)
    41.         fbstp   tbyte ptr [BCDNum]
    42.         mov eax,dword ptr [BCDNum]
    43.         mov ecx,dword ptr [BCDNum+4]
    44.         bswap   eax
    45.         bswap   ecx
    46.         mov dword ptr [BCDNum+4],eax
    47.         mov dword ptr [BCDNum],ecx
    48.         movq    xmm0,qword ptr [BCDNum]
    49.         movaps  xmm1,xmm0
    50.         pand    xmm0,_0F_0F_
    51.         psrlq   xmm1,4
    52.         pand    xmm1,_0F_0F_
    53.         punpcklbw   xmm1,xmm0
    54.         por xmm1,_30_30_
    55.         movups  [edi],xmm1
    56.         movzx   eax,byte ptr [edi]
    57.         mov byte ptr [edi],'.'
    58.         mov byte ptr [edi-1],al
    59.         mov byte ptr [edi+16],'e'
    60.         mov eax,dword ptr [lgNum+6]
    61.         rol eax,1
    62.         add eax,eax
    63.         add eax,'+'
    64.         mov dword ptr [edi+17],eax
    65.         mov eax,dword ptr [lgNum]
    66.         bswap   eax
    67.         movd    xmm0,eax
    68.         movaps  xmm1,xmm0
    69.         psrlq   xmm1,4
    70.         pand    xmm0,_0F_0F_
    71.         pand    xmm1,_0F_0F_
    72.         punpcklbw   xmm1,xmm0
    73.         por xmm1,[_30_00_]
    74.         movups  [lgNum],xmm1
    75.         mov ebx,edi
    76.         lea edi,lgNum
    77.         mov eax,0x30
    78.         mov ecx,32
    79.         repe    scasb
    80.         mov esi,edi
    81.         sub esi,1
    82.         add ecx,1
    83.         mov edi,ebx
    84.         add edi,18
    85.         rep movsb
    86. End:
     
  3. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    А может попробовать в целых числах? Через внутреннее бинарное представление числа? Разбить на мантиссу и коэффициент порядка...
     
  4. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    Xerx
    Так придётся основание менять с 2 на 10 предварительно...
     
  5. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    SII
    Порядок и характеристику можно получить напрямую. А мантиссу можно считать побитно как степени двойки (суммировать до нужно точности в целых числах).

    В Вики есть пример перевода двоичного-float в десятичный-float. По нему вполне понятно как это сделать, ИМХО.

    http://ru.wikipedia.org/wiki/Систем....81.D1.8F.D1.82.D0.B8.D1.87.D0.BD.D1.83.D1.8E
     
  6. AssemblerIA64

    AssemblerIA64 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2007
    Сообщения:
    160
    10110111, а можно посмотреть как во 2-ом варианте определены данные?
    Код (Text):
    1. fild    [_15_]
    15 - в шестнадцатеричной или в десятичной системе ???
     
  7. 10110111

    10110111 New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2006
    Сообщения:
    319
    Адрес:
    Санкт-Петербург
    Да, ступил, не дав данные. Просто это был эксперимент на сях с асм вставками, и все XMM-данные были введены __emit'ами, вот и мне и было лень преобразовывать данные к читабельному виду. =)
    Код (Text):
    1. align 16
    2. _30_30_:
    3.         dd 4 dup(0x30303030)
    4. _30_00_:
    5.         dd 2 dup(0x30303030)
    6.         dd 2 dup(0)
    7. _0F_0F_:
    8.         dd 4 dup(0x0f0f0f0f)
    9. _77F_:
    10.         dd 0x77f
    11. _F7F_:
    12.         dd 0xF7F
    13. _37f_:
    14.         dd 0x37f
    15. _15_:
    16.         dd 15
    Цель эксперимента была - минимизировать ветвления. Если у кого-нибудь получится исключить имеющиеся, будет интересно посмотреть.
     
  8. 10110111

    10110111 New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2006
    Сообщения:
    319
    Адрес:
    Санкт-Петербург
    Во, придумал:
    Заменяем это
    Код (Text):
    1.         jnc Plus
    2.         mov [edi],'-'
    3.         add edi,1
    4.         fabs
    5. Plus:
    6.         add edi,1
    на:
    Код (Text):
    1.         mov [edi],'-' ; if this is unneeded (Number>0), it will be overwritten by first digit
    2.         adс    edi,0 ;if (!carry) add 0; else add 1;
    3.         fabs ;if Number>0 this doesn't do anything
    4.         add edi,1
    и получаем код вообще почти без ветвлений =)
    ЗЫ: Правда, ещё стоит проверять на нечисла - после "Je Zero" надо "Jp NAN", но это уже особые случаи.
     
  9. AssemblerIA64

    AssemblerIA64 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2007
    Сообщения:
    160
    10110111, спасибо ещё раз.
     
  10. AssemblerIA64

    AssemblerIA64 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2007
    Сообщения:
    160
    Кстати: вместо
    Код (Text):
    1. _77F_:
    2.         dd 0x77f
    3. _F7F_:
    4.         dd 0xF7F
    5. _37f_:
    6.         dd 0x37f
    лучше
    Код (Text):
    1. _77F_:
    2.         dw 0x77f
    3. _F7F_:
    4.         dw 0xF7F
    5. _37f_:
    6.         dw 0x37f
    ;)
     
  11. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    PureBasic.
     
  12. AssemblerIA64

    AssemblerIA64 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2007
    Сообщения:
    160
    То есть?
     
  13. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Насчёт математики - я не видел лучшего компилятора, используй его libs
     
  14. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Кстати MasmLib: fptoa() и dwtoa() - не подходят?
     
  15. AssemblerIA64

    AssemblerIA64 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2007
    Сообщения:
    160
    Я пишу на FASM'е под DOS.
    К тому же хочется изучить эти алгорифмы.
     
  16. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Математику не изменишь.
     
  17. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Лет 10 назад работал на Spectrum, проц z80 не умеет даже делить, а сопроцессор математики реализовался программным путём - разбирать это было интересно...
     
  18. 10110111

    10110111 New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2006
    Сообщения:
    319
    Адрес:
    Санкт-Петербург
    тока не забудь, что XMM будут работать тока при включенном бите в CR4. Я, когда запускал этот код под DOS, долго недоумевал, в чем причина зависаний.
     
  19. AssemblerIA64

    AssemblerIA64 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2007
    Сообщения:
    160
    10110111, а каким отладчиком Вы пользуетесь? Все, которые у меня есть, либо не показывают XMM регистры, либо показывают их в форме вещественного числа.
     
  20. AssemblerIA64

    AssemblerIA64 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2007
    Сообщения:
    160
    Может кто-нибудь ещё подскажет?